CMS 3D CMS Logo

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