CMS 3D CMS Logo

PFLinker.cc
Go to the documentation of this file.
1 
20 
21 namespace edm {
22  class EventSetup;
23 } // namespace edm
24 
26 public:
27  explicit PFLinker(const edm::ParameterSet&);
28 
29  ~PFLinker() override;
30 
31  void produce(edm::Event&, const edm::EventSetup&) override;
32 
33 private:
34  template <typename TYPE>
38  edm::Handle<TYPE>& inputObjCollection,
39  const std::map<edm::Ref<TYPE>, reco::PFCandidatePtr>& mapToTheCandidate,
40  const edm::OrphanHandle<reco::PFCandidateCollection>& newPFCandColl) const;
41 
42 private:
44  std::vector<edm::EDGetTokenT<reco::PFCandidateCollection>> inputTagPFCandidates_;
45 
48 
51 
58 
61 
64 
67 
70 
73 
76 };
77 
79 
81  // vector of InputTag; more than 1 is not for RECO, it is for analysis
82 
83  std::vector<edm::InputTag> tags = iConfig.getParameter<std::vector<edm::InputTag>>("PFCandidate");
84  for (unsigned int i = 0; i < tags.size(); ++i)
85  inputTagPFCandidates_.push_back(consumes<reco::PFCandidateCollection>(tags[i]));
86 
87  inputTagGsfElectrons_ = consumes<reco::GsfElectronCollection>(iConfig.getParameter<edm::InputTag>("GsfElectrons"));
88 
89  inputTagPhotons_ = consumes<reco::PhotonCollection>(iConfig.getParameter<edm::InputTag>("Photons"));
90 
91  muonTag_ = iConfig.getParameter<edm::InputTag>("Muons");
92  inputTagMuons_ = consumes<reco::MuonCollection>(edm::InputTag(muonTag_.label()));
93  inputTagMuonMap_ = consumes<reco::MuonToMuonMap>(muonTag_);
94 
95  nameOutputPF_ = iConfig.getParameter<std::string>("OutputPF");
96 
97  nameOutputElectronsPF_ = iConfig.getParameter<std::string>("ValueMapElectrons");
98 
99  nameOutputPhotonsPF_ = iConfig.getParameter<std::string>("ValueMapPhotons");
100 
101  producePFCandidates_ = iConfig.getParameter<bool>("ProducePFCandidates");
102 
103  nameOutputMergedPF_ = iConfig.getParameter<std::string>("ValueMapMerged");
104 
105  fillMuonRefs_ = iConfig.getParameter<bool>("FillMuonRefs");
106 
107  forceElectronsInHGCAL_ = iConfig.getParameter<bool>("forceElectronsInHGCAL");
108 
109  // should not produce PFCandidates and read seve
110  if (producePFCandidates_ && inputTagPFCandidates_.size() > 1) {
111  edm::LogError("PFLinker")
112  << " cannot read several collections of PFCandidates and produce a new collection at the same time. "
113  << std::endl;
114  assert(false);
115  }
116  if (producePFCandidates_) {
117  produces<reco::PFCandidateCollection>(nameOutputPF_);
118  }
119  produces<edm::ValueMap<reco::PFCandidatePtr>>(nameOutputElectronsPF_);
120  produces<edm::ValueMap<reco::PFCandidatePtr>>(nameOutputPhotonsPF_);
121  produces<edm::ValueMap<reco::PFCandidatePtr>>(nameOutputMergedPF_);
122  if (fillMuonRefs_)
123  produces<edm::ValueMap<reco::PFCandidatePtr>>(muonTag_.label());
124 }
125 
127 
129  auto pfCandidates_p = std::make_unique<reco::PFCandidateCollection>();
130 
131  auto gsfElectrons = iEvent.getHandle(inputTagGsfElectrons_);
132 
133  std::map<reco::GsfElectronRef, reco::PFCandidatePtr> electronCandidateMap;
134 
135  auto photons = iEvent.getHandle(inputTagPhotons_);
136  std::map<reco::PhotonRef, reco::PFCandidatePtr> photonCandidateMap;
137 
139  if (fillMuonRefs_)
140  muonMap = iEvent.getHandle(inputTagMuonMap_);
141  std::map<reco::MuonRef, reco::PFCandidatePtr> muonCandidateMap;
142 
143  unsigned nColPF = inputTagPFCandidates_.size();
144 
145  for (unsigned icol = 0; icol < nColPF; ++icol) {
146  auto pfCandidates = iEvent.getHandle(inputTagPFCandidates_[icol]);
147  unsigned ncand = pfCandidates->size();
148 
149  for (unsigned i = 0; i < ncand; ++i) {
151  reco::PFCandidate cand(candPtr);
152 
153  if (!(cand.energy() > 0))
154  continue;
155 
156  bool isphoton = cand.particleId() == reco::PFCandidate::gamma && cand.mva_nothing_gamma() > 0.;
157  bool iselectron = cand.particleId() == reco::PFCandidate::e;
158  // PFCandidates may have a valid MuonRef though they are not muons.
159  bool hasNonNullMuonRef = cand.muonRef().isNonnull() && fillMuonRefs_;
160 
161  // if not an electron or a photon or a muon just fill the PFCandidate collection
162  if (!(isphoton || iselectron || hasNonNullMuonRef)) {
163  pfCandidates_p->push_back(cand);
164  continue;
165  }
166 
167  if (hasNonNullMuonRef) {
168  reco::MuonRef muRef = (*muonMap)[cand.muonRef()];
169  cand.setMuonRef(muRef);
170  muonCandidateMap[muRef] = candPtr;
171  }
172 
173  // if it is an electron. Find the GsfElectron with the same GsfTrack
174  if (iselectron) {
175  const reco::GsfTrackRef& gsfTrackRef(cand.gsfTrackRef());
176  auto itcheck = find_if(gsfElectrons->begin(), gsfElectrons->end(), [&gsfTrackRef](const auto& ele) {
177  return (ele.gsfTrack() == gsfTrackRef);
178  });
179  if (itcheck == gsfElectrons->end()) {
180  if (!forceElectronsInHGCAL_) {
181  std::ostringstream err;
182  err << " Problem in PFLinker: no GsfElectron " << std::endl;
183  edm::LogError("PFLinker") << err.str();
184  } else {
185  LogDebug("PFLinker") << "Forcing an electron pfCandidate at: " << cand.eta() << " in HGCAL" << std::endl;
186  pfCandidates_p->push_back(cand);
187  }
188  continue; // Watch out ! Continue
189  }
190  reco::GsfElectronRef electronRef(gsfElectrons, itcheck - gsfElectrons->begin());
191  cand.setGsfElectronRef(electronRef);
192  cand.setSuperClusterRef(electronRef->superCluster());
193  // update energy information since now it is done post-particleFlowTmp
194  cand.setEcalEnergy(electronRef->superCluster()->rawEnergy(), electronRef->ecalEnergy());
195  cand.setDeltaP(electronRef->p4Error(reco::GsfElectron::P4_COMBINATION));
196  cand.setP4(electronRef->p4(reco::GsfElectron::P4_COMBINATION));
197  electronCandidateMap[electronRef] = candPtr;
198  }
199 
200  // if it is a photon, find the one with the same PF super-cluster
201  if (isphoton) {
202  const reco::SuperClusterRef& scRef(cand.superClusterRef());
203  auto itcheck = find_if(
204  photons->begin(), photons->end(), [&scRef](const auto& photon) { return photon.superCluster() == scRef; });
205  if (itcheck == photons->end()) {
206  std::ostringstream err;
207  err << " Problem in PFLinker: no Photon " << std::endl;
208  edm::LogError("PFLinker") << err.str();
209  continue; // Watch out ! Continue
210  }
211  reco::PhotonRef photonRef(photons, itcheck - photons->begin());
212  cand.setPhotonRef(photonRef);
213  cand.setSuperClusterRef(photonRef->superCluster());
214  // update energy information since now it is done post-particleFlowTmp
215  cand.setEcalEnergy(photonRef->superCluster()->rawEnergy(),
216  photonRef->getCorrectedEnergy(reco::Photon::regression2));
217  cand.setDeltaP(photonRef->getCorrectedEnergyError(reco::Photon::regression2));
218  cand.setP4(photonRef->p4(reco::Photon::regression2));
219  photonCandidateMap[photonRef] = candPtr;
220  }
221 
222  pfCandidates_p->push_back(cand);
223  }
224  // save the PFCandidates and get a valid handle
225  }
226  const edm::OrphanHandle<reco::PFCandidateCollection> pfCandidateRefProd =
227  (producePFCandidates_) ? iEvent.put(std::move(pfCandidates_p), nameOutputPF_)
229 
230  // now make the valuemaps
231 
232  edm::ValueMap<reco::PFCandidatePtr> pfMapGsfElectrons = fillValueMap<reco::GsfElectronCollection>(
233  iEvent, nameOutputElectronsPF_, gsfElectrons, electronCandidateMap, pfCandidateRefProd);
234 
235  edm::ValueMap<reco::PFCandidatePtr> pfMapPhotons = fillValueMap<reco::PhotonCollection>(
236  iEvent, nameOutputPhotonsPF_, photons, photonCandidateMap, pfCandidateRefProd);
237 
239 
240  if (fillMuonRefs_) {
241  auto muons = iEvent.getHandle(inputTagMuons_);
242 
243  pfMapMuons =
244  fillValueMap<reco::MuonCollection>(iEvent, muonTag_.label(), muons, muonCandidateMap, pfCandidateRefProd);
245  }
246 
247  auto pfMapMerged = std::make_unique<edm::ValueMap<reco::PFCandidatePtr>>();
248  edm::ValueMap<reco::PFCandidatePtr>::Filler pfMapMergedFiller(*pfMapMerged);
249 
250  *pfMapMerged += pfMapGsfElectrons;
251  *pfMapMerged += pfMapPhotons;
252  if (fillMuonRefs_)
253  *pfMapMerged += pfMapMuons;
254 
255  iEvent.put(std::move(pfMapMerged), nameOutputMergedPF_);
256 }
257 
258 template <typename TYPE>
260  edm::Event& event,
262  edm::Handle<TYPE>& inputObjCollection,
263  const std::map<edm::Ref<TYPE>, reco::PFCandidatePtr>& mapToTheCandidate,
264  const edm::OrphanHandle<reco::PFCandidateCollection>& newPFCandColl) const {
265  auto pfMap_p = std::make_unique<edm::ValueMap<reco::PFCandidatePtr>>();
267 
268  typedef typename std::map<edm::Ref<TYPE>, reco::PFCandidatePtr>::const_iterator MapTYPE_it;
269 
270  unsigned nObj = inputObjCollection->size();
271  std::vector<reco::PFCandidatePtr> values(nObj);
272 
273  for (unsigned iobj = 0; iobj < nObj; ++iobj) {
274  edm::Ref<TYPE> objRef(inputObjCollection, iobj);
275  MapTYPE_it itcheck = mapToTheCandidate.find(objRef);
276 
277  reco::PFCandidatePtr candPtr;
278 
279  if (itcheck != mapToTheCandidate.end())
280  candPtr = producePFCandidates_ ? reco::PFCandidatePtr(newPFCandColl, itcheck->second.key()) : itcheck->second;
281 
282  values[iobj] = candPtr;
283  }
284 
285  filler.insert(inputObjCollection, values.begin(), values.end());
286  filler.fill();
287  edm::ValueMap<reco::PFCandidatePtr> returnValue = *pfMap_p;
288  event.put(std::move(pfMap_p), label);
289  return returnValue;
290 }
edm::InputTag muonTag_
Input Muons.
Definition: PFLinker.cc:53
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
edm::EDGetTokenT< reco::MuonCollection > inputTagMuons_
Definition: PFLinker.cc:54
void produce(edm::Event &, const edm::EventSetup &) override
Definition: PFLinker.cc:128
bool producePFCandidates_
Flags - if true: References will be towards new collection ; if false to the original one...
Definition: PFLinker.cc:69
std::string const & label() const
Definition: InputTag.h:36
Log< level::Error, false > LogError
edm::EDGetTokenT< reco::PhotonCollection > inputTagPhotons_
Input Photons.
Definition: PFLinker.cc:50
assert(be >=bs)
PFLinker(const edm::ParameterSet &)
Definition: PFLinker.cc:80
edm::EDGetTokenT< reco::MuonToMuonMap > inputTagMuonMap_
Definition: PFLinker.cc:55
char const * label
int iEvent
Definition: GenABIO.cc:224
std::string nameOutputElectronsPF_
name of output ValueMap electrons
Definition: PFLinker.cc:60
std::string nameOutputPhotonsPF_
name of output ValueMap photons
Definition: PFLinker.cc:63
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
std::string nameOutputPF_
name of output collection of PFCandidate
Definition: PFLinker.cc:57
bool fillMuonRefs_
Set muon refs and produce the value map?
Definition: PFLinker.cc:72
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:41
HLT enums.
bool forceElectronsInHGCAL_
Put Electrons within HGCAL coming from SimPFProducer.
Definition: PFLinker.cc:75
~PFLinker() override
Definition: PFLinker.cc:126
edm::EDGetTokenT< reco::GsfElectronCollection > inputTagGsfElectrons_
Input GsfElectrons.
Definition: PFLinker.cc:47
def move(src, dest)
Definition: eostools.py:511
std::vector< edm::EDGetTokenT< reco::PFCandidateCollection > > inputTagPFCandidates_
Input PFCandidates.
Definition: PFLinker.cc:44
Definition: event.py:1
std::string nameOutputMergedPF_
name of output merged ValueMap
Definition: PFLinker.cc:66
#define LogDebug(id)
edm::ValueMap< reco::PFCandidatePtr > fillValueMap(edm::Event &event, std::string label, edm::Handle< TYPE > &inputObjCollection, const std::map< edm::Ref< TYPE >, reco::PFCandidatePtr > &mapToTheCandidate, const edm::OrphanHandle< reco::PFCandidateCollection > &newPFCandColl) const
Definition: PFLinker.cc:259