CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
PFElectronTranslator.cc
Go to the documentation of this file.
15 
16 
19  = iConfig.getParameter<edm::InputTag>("PFCandidate");
21  = iConfig.getParameter<edm::InputTag>("GSFTracks");
22 
23  PFBasicClusterCollection_ = iConfig.getParameter<std::string>("PFBasicClusters");
24  PFPreshowerClusterCollection_ = iConfig.getParameter<std::string>("PFPreshowerClusters");
25  PFSuperClusterCollection_ = iConfig.getParameter<std::string>("PFSuperClusters");
26  PFMVAValueMap_ = iConfig.getParameter<std::string>("ElectronMVA");
27  PFSCValueMap_ = iConfig.getParameter<std::string>("ElectronSC");
28  MVACut_ = (iConfig.getParameter<edm::ParameterSet>("MVACutBlock")).getParameter<double>("MVACut");
29 
30  produces<reco::BasicClusterCollection>(PFBasicClusterCollection_);
31  produces<reco::PreshowerClusterCollection>(PFPreshowerClusterCollection_);
32  produces<reco::SuperClusterCollection>(PFSuperClusterCollection_);
33  produces<edm::ValueMap<float> >(PFMVAValueMap_);
34  produces<edm::ValueMap<reco::SuperClusterRef> >(PFSCValueMap_);
35 }
36 
38 
40 
42  const edm::EventSetup& iSetup) {
43 
44  std::auto_ptr<reco::SuperClusterCollection>
45  superClusters_p(new reco::SuperClusterCollection);
46 
47  std::auto_ptr<reco::BasicClusterCollection>
48  basicClusters_p(new reco::BasicClusterCollection);
49 
50  std::auto_ptr<reco::PreshowerClusterCollection>
51  psClusters_p(new reco::PreshowerClusterCollection);
52 
53  std::auto_ptr<edm::ValueMap<float> > mvaMap_p(new edm::ValueMap<float>());
54  edm::ValueMap<float>::Filler mvaFiller(*mvaMap_p);
55 
56  std::auto_ptr<edm::ValueMap<reco::SuperClusterRef> >
59 
60 
62  bool status=fetchCandidateCollection(pfCandidates,
64  iEvent );
65 
66  // clear the vectors
67  GsfTrackRef_.clear();
68  basicClusters_.clear();
69  pfClusters_.clear();
70  preshowerClusters_.clear();
71  superClusters_.clear();
72  basicClusterPtr_.clear();
73  preshowerClusterPtr_.clear();
74  gsfPFCandidateIndex_.clear();
75  scMap_.clear();
76  gsfMvaMap_.clear();
77 
78  // loop on the candidates
79  //CC@@
80  // we need first to create AND put the SuperCluster,
81  // basic clusters and presh clusters collection
82  // in order to get a working Handle
83  unsigned ncand=(status)?pfCandidates->size():0;
84  unsigned iGSF=0;
85  for( unsigned i=0; i<ncand; ++i ) {
86 
87  const reco::PFCandidate& cand = (*pfCandidates)[i];
88  if(cand.particleId()!=reco::PFCandidate::e) continue;
89  if(cand.gsfTrackRef().isNull()) continue;
90  // Note that -1 will still cut some total garbage candidates
91  // Fill the MVA map
92  gsfMvaMap_[cand.gsfTrackRef()]=cand.mva_e_pi();
93  if(cand.mva_e_pi()<MVACut_) continue;
94 
95  GsfTrackRef_.push_back(cand.gsfTrackRef());
96  gsfPFCandidateIndex_.push_back(i);
97 
99  pfClusters_.push_back(std::vector<const reco::PFCluster *>());
101 
102  for(unsigned iele=0; iele<cand.elementsInBlocks().size(); ++iele) {
103  // first get the block
104  reco::PFBlockRef blockRef = cand.elementsInBlocks()[iele].first;
105  //
106  unsigned elementIndex = cand.elementsInBlocks()[iele].second;
107  // check it actually exists
108  if(blockRef.isNull()) continue;
109 
110  // then get the elements of the block
111  const edm::OwnVector< reco::PFBlockElement >& elements = (*blockRef).elements();
112 
113  const reco::PFBlockElement & pfbe (elements[elementIndex]);
114  // The first ECAL element should be the cluster associated to the GSF; defined as the seed
115  if(pfbe.type()==reco::PFBlockElement::ECAL)
116  {
117  // const reco::PFCandidate * coCandidate = &cand;
118  // the Brem photons are saved as daughter PFCandidate; this
119  // is convenient to access the corrected energy
120  // std::cout << " Found candidate " << correspondingDaughterCandidate(coCandidate,pfbe) << " " << coCandidate << std::endl;
122  }
123  if(pfbe.type()==reco::PFBlockElement::PS1)
124  {
126  }
127  if(pfbe.type()==reco::PFBlockElement::PS2)
128  {
130  }
131 
132  } // loop on the elements
133 
134  // save the basic clusters
135  basicClusters_p->insert(basicClusters_p->end(),basicClusters_[iGSF].begin(), basicClusters_[iGSF].end());
136  // save the preshower clusters
137  psClusters_p->insert(psClusters_p->end(),preshowerClusters_[iGSF].begin(),preshowerClusters_[iGSF].end());
138 
139  ++iGSF;
140  } // loop on PFCandidates
141 
142 
143  //Save the basic clusters and get an handle as to be able to create valid Refs (thanks to Claude)
144  // std::cout << " Number of basic clusters " << basicClusters_p->size() << std::endl;
146  iEvent.put(basicClusters_p,PFBasicClusterCollection_);
147 
148  //preshower clusters
150  iEvent.put(psClusters_p,PFPreshowerClusterCollection_);
151 
152  // now that the Basic clusters are in the event, the Ref can be created
153  createBasicClusterPtrs(bcRefProd);
154  // now that the preshower clusters are in the event, the Ref can be created
155  createPreshowerClusterPtrs(psRefProd);
156 
157  // and now the Super cluster can be created with valid references
158  if(status) createSuperClusters(*pfCandidates,*superClusters_p);
159 
160  // Let's put the super clusters in the event
161  const edm::OrphanHandle<reco::SuperClusterCollection> scRefProd = iEvent.put(superClusters_p,PFSuperClusterCollection_);
162  // create the super cluster Ref
163  createSuperClusterGsfMapRefs(scRefProd);
164 
165 
166  fillMVAValueMap(iEvent,mvaFiller);
167  mvaFiller.fill();
168 
169  fillSCRefValueMap(iEvent,scRefFiller);
170  scRefFiller.fill();
171 
172  // MVA map
173  iEvent.put(mvaMap_p,PFMVAValueMap_);
174  // Gsf-SC map
175  iEvent.put(scMap_p,PFSCValueMap_);
176 }
177 
178 
179 
181  const edm::InputTag& tag,
182  const edm::Event& iEvent) const {
183  bool found = iEvent.getByLabel(tag, c);
184 
185  if(!found)
186  {
187  std::ostringstream err;
188  err<<" cannot get PFCandidates: "
189  <<tag<<std::endl;
190  edm::LogError("PFElectronTranslator")<<err.str();
191  }
192  return found;
193 
194 }
195 
197  const edm::InputTag& tag,
198  const edm::Event& iEvent) const {
199  bool found = iEvent.getByLabel(tag, c);
200 
201  if(!found ) {
202  std::ostringstream err;
203  err<<" cannot get GSFTracks: "
204  <<tag<<std::endl;
205  edm::LogError("PFElectronTranslator")<<err.str();
206  throw cms::Exception( "MissingProduct", err.str());
207  }
208 }
209 
210 // The basic cluster is a copy of the PFCluster -> the energy is not corrected
211 // It should be possible to get the corrected energy (including the associated PS energy)
212 // from the PFCandidate daugthers ; Needs some work
214  reco::BasicClusterCollection & basicClusters,
215  std::vector<const reco::PFCluster *> & pfClusters,
216  const reco::PFCandidate & coCandidate) const
217 {
218  reco::PFClusterRef myPFClusterRef= PFBE.clusterRef();
219  if(myPFClusterRef.isNull()) return;
220 
221  const reco::PFCluster & myPFCluster (*myPFClusterRef);
222  pfClusters.push_back(&myPFCluster);
223 // std::cout << " Creating BC " << myPFCluster.energy() << " " << coCandidate.ecalEnergy() <<" "<< coCandidate.rawEcalEnergy() <<std::endl;
224 // std::cout << " # hits " << myPFCluster.hitsAndFractions().size() << std::endl;
225 
226 // basicClusters.push_back(reco::CaloCluster(myPFCluster.energy(),
227  basicClusters.push_back(reco::CaloCluster(coCandidate.rawEcalEnergy(),
228  myPFCluster.position(),
229  myPFCluster.caloID(),
230  myPFCluster.hitsAndFractions(),
231  myPFCluster.algo(),
232  myPFCluster.seed()));
233 }
234 
235 
237 {
238  reco::PFClusterRef myPFClusterRef= PFBE.clusterRef();
239  preshowerClusters.push_back(reco::PreshowerCluster(myPFClusterRef->energy(),myPFClusterRef->position(),
240  myPFClusterRef->hitsAndFractions(),plane));
241 }
242 
244 {
245  unsigned size=GsfTrackRef_.size();
246  unsigned basicClusterCounter=0;
247  basicClusterPtr_.resize(size);
248 
249  for(unsigned iGSF=0;iGSF<size;++iGSF) // loop on tracks
250  {
251  unsigned nbc=basicClusters_[iGSF].size();
252  for(unsigned ibc=0;ibc<nbc;++ibc) // loop on basic clusters
253  {
254  // std::cout << "Track "<< iGSF << " ref " << basicClusterCounter << std::endl;
255  reco::CaloClusterPtr bcPtr(basicClustersHandle,basicClusterCounter);
256  basicClusterPtr_[iGSF].push_back(bcPtr);
257  ++basicClusterCounter;
258  }
259  }
260 }
261 
263 {
264  unsigned size=GsfTrackRef_.size();
265  unsigned psClusterCounter=0;
266  preshowerClusterPtr_.resize(size);
267 
268  for(unsigned iGSF=0;iGSF<size;++iGSF) // loop on tracks
269  {
270  unsigned nbc=preshowerClusters_[iGSF].size();
271  for(unsigned ibc=0;ibc<nbc;++ibc) // loop on basic clusters
272  {
273  // std::cout << "Track "<< iGSF << " ref " << basicClusterCounter << std::endl;
274  reco::CaloClusterPtr psPtr(preshowerClustersHandle,psClusterCounter);
275  preshowerClusterPtr_[iGSF].push_back(psPtr);
276  ++psClusterCounter;
277  }
278  }
279 }
280 
282 {
283  unsigned size=GsfTrackRef_.size();
284 
285  for(unsigned iGSF=0;iGSF<size;++iGSF) // loop on tracks
286  {
287  edm::Ref<reco::SuperClusterCollection> scRef(superClustersHandle,iGSF);
288  scMap_[GsfTrackRef_[iGSF]]=scRef;
289  }
290 }
291 
292 
294 {
296  fetchGsfCollection(gsfTracks,
298  iEvent);
299  unsigned ngsf=gsfTracks->size();
300  std::vector<float> values;
301  for(unsigned igsf=0;igsf<ngsf;++igsf)
302  {
303  reco::GsfTrackRef theTrackRef(gsfTracks, igsf);
304  std::map<reco::GsfTrackRef,float>::const_iterator itcheck=gsfMvaMap_.find(theTrackRef);
305  if(itcheck==gsfMvaMap_.end())
306  {
307  // edm::LogWarning("PFElectronTranslator") << "MVA Map, missing GSF track ref " << std::endl;
308  values.push_back(-99.);
309  // std::cout << " Push_back -99. " << std::endl;
310  }
311  else
312  {
313  values.push_back(itcheck->second);
314  }
315  }
316  filler.insert(gsfTracks,values.begin(),values.end());
317 }
318 
319 
322 {
324  fetchGsfCollection(gsfTracks,
326  iEvent);
327  unsigned ngsf=gsfTracks->size();
328  std::vector<reco::SuperClusterRef> values;
329  for(unsigned igsf=0;igsf<ngsf;++igsf)
330  {
331  reco::GsfTrackRef theTrackRef(gsfTracks, igsf);
332  std::map<reco::GsfTrackRef,reco::SuperClusterRef>::const_iterator itcheck=scMap_.find(theTrackRef);
333  if(itcheck==scMap_.end())
334  {
335  // edm::LogWarning("PFElectronTranslator") << "SCRef Map, missing GSF track ref" << std::endl;
336  values.push_back(reco::SuperClusterRef());
337  }
338  else
339  {
340  values.push_back(itcheck->second);
341  }
342  }
343  filler.insert(gsfTracks,values.begin(),values.end());
344 }
345 
346 
348  reco::SuperClusterCollection &superClusters) const
349 {
350  unsigned nGSF=GsfTrackRef_.size();
351  for(unsigned iGSF=0;iGSF<nGSF;++iGSF)
352  {
353 
354  // Computes energy position a la e/gamma
355  double sclusterE=0;
356  double posX=0.;
357  double posY=0.;
358  double posZ=0.;
359 
360  unsigned nbasics=basicClusters_[iGSF].size();
361  for(unsigned ibc=0;ibc<nbasics;++ibc)
362  {
363  double e = basicClusters_[iGSF][ibc].energy();
364  sclusterE += e;
365  posX += e * basicClusters_[iGSF][ibc].position().X();
366  posY += e * basicClusters_[iGSF][ibc].position().Y();
367  posZ += e * basicClusters_[iGSF][ibc].position().Z();
368  }
369  posX /=sclusterE;
370  posY /=sclusterE;
371  posZ /=sclusterE;
372 
373  if(pfCand[gsfPFCandidateIndex_[iGSF]].gsfTrackRef()!=GsfTrackRef_[iGSF])
374  {
375  edm::LogError("PFElectronTranslator") << " Major problem in PFElectron Translator" << std::endl;
376  }
377 
378  // compute the width
379  PFClusterWidthAlgo pfwidth(pfClusters_[iGSF]);
380 
381  double correctedEnergy=pfCand[gsfPFCandidateIndex_[iGSF]].ecalEnergy();
382  reco::SuperCluster mySuperCluster(correctedEnergy,math::XYZPoint(posX,posY,posZ));
383  // protection against empty basic cluster collection ; the value is -2 in this case
384  if(nbasics)
385  {
386 // std::cout << "SuperCluster creation; energy " << pfCand[gsfPFCandidateIndex_[iGSF]].ecalEnergy();
387 // std::cout << " " << pfCand[gsfPFCandidateIndex_[iGSF]].rawEcalEnergy() << std::endl;
388 // std::cout << "Seed energy from basic " << basicClusters_[iGSF][0].energy() << std::endl;
389  mySuperCluster.setSeed(basicClusterPtr_[iGSF][0]);
390  }
391  else
392  {
393  // std::cout << "SuperCluster creation ; seed energy " << 0 << std::endl;
394 // std::cout << "SuperCluster creation ; energy " << pfCand[gsfPFCandidateIndex_[iGSF]].ecalEnergy();
395 // std::cout << " " << pfCand[gsfPFCandidateIndex_[iGSF]].rawEcalEnergy() << std::endl;
396 // std::cout << " No seed found " << 0 << std::endl;
397 // std::cout << " MVA " << pfCand[gsfPFCandidateIndex_[iGSF]].mva_e_pi() << std::endl;
398  mySuperCluster.setSeed(reco::CaloClusterPtr());
399  }
400  // the seed should be the first basic cluster
401 
402  for(unsigned ibc=0;ibc<nbasics;++ibc)
403  {
404  mySuperCluster.addCluster(basicClusterPtr_[iGSF][ibc]);
405  // std::cout <<"Adding Ref to SC " << basicClusterPtr_[iGSF][ibc].index() << std::endl;
406  const std::vector< std::pair<DetId, float> > & v1 = basicClusters_[iGSF][ibc].hitsAndFractions();
407  // std::cout << " Number of cells " << v1.size() << std::endl;
408  for( std::vector< std::pair<DetId, float> >::const_iterator diIt = v1.begin();
409  diIt != v1.end();
410  ++diIt ) {
411  // std::cout << " Adding DetId " << (diIt->first).rawId() << " " << diIt->second << std::endl;
412  mySuperCluster.addHitAndFraction(diIt->first,diIt->second);
413  } // loop over rechits
414  }
415 
416  unsigned nps=preshowerClusterPtr_[iGSF].size();
417  for(unsigned ips=0;ips<nps;++ips)
418  {
419  mySuperCluster.addPreshowerCluster(preshowerClusterPtr_[iGSF][ips]);
420  }
421 
422 
423  // Set the preshower energy
424  mySuperCluster.setPreshowerEnergy(pfCand[gsfPFCandidateIndex_[iGSF]].pS1Energy()+
425  pfCand[gsfPFCandidateIndex_[iGSF]].pS2Energy());
426 
427  // Set the cluster width
428  mySuperCluster.setEtaWidth(pfwidth.pflowEtaWidth());
429  mySuperCluster.setPhiWidth(pfwidth.pflowPhiWidth());
430  // Force the computation of rawEnergy_ of the reco::SuperCluster
431  mySuperCluster.rawEnergy();
432  superClusters.push_back(mySuperCluster);
433  }
434 }
435 
436 
438 {
439  unsigned refindex=pfbe.index();
440  // std::cout << " N daughters " << cand.numberOfDaughters() << std::endl;
441  reco::PFCandidate::const_iterator myDaughterCandidate=cand.begin();
443 
444  for(;myDaughterCandidate!=itend;++myDaughterCandidate)
445  {
446  const reco::PFCandidate * myPFCandidate = (const reco::PFCandidate*)&*myDaughterCandidate;
447  if(myPFCandidate->elementsInBlocks().size()!=1)
448  {
449  // std::cout << " Daughter with " << myPFCandidate.elementsInBlocks().size()<< " element in block " << std::endl;
450  return cand;
451  }
452  if(myPFCandidate->elementsInBlocks()[0].second==refindex)
453  {
454  // std::cout << " Found it " << cand << std::endl;
455  return *myPFCandidate;
456  }
457  }
458  return cand;
459 }
460 
std::vector< std::vector< const reco::PFCluster * > > pfClusters_
reco::GsfTrackRef gsfTrackRef() const
Definition: PFCandidate.h:141
T getParameter(std::string const &) const
std::string PFPreshowerClusterCollection_
Abstract base class for a PFBlock element (track, cluster...)
const math::XYZPoint & position() const
cluster centroid position
Definition: CaloCluster.h:112
int i
Definition: DBlmapReader.cc:9
bool fetchCandidateCollection(edm::Handle< reco::PFCandidateCollection > &c, const edm::InputTag &tag, const edm::Event &iEvent) const
double rawEcalEnergy() const
return corrected Ecal energy
Definition: PFCandidate.h:198
void addHitAndFraction(DetId id, float fraction)
Definition: CaloCluster.h:171
Particle flow cluster, see clustering algorithm in PFClusterAlgo.
Definition: PFCluster.h:42
std::map< reco::GsfTrackRef, float > gsfMvaMap_
virtual const_iterator end() const
last daughter const_iterator
Type type() const
std::vector< reco::CaloClusterPtrVector > basicClusterPtr_
double pflowPhiWidth() const
void insert(const H &h, I begin, I end)
Definition: ValueMap.h:52
void createBasicClusterPtrs(const edm::OrphanHandle< reco::BasicClusterCollection > &basicClustersHandle)
list elements
Definition: asciidump.py:414
const std::vector< std::pair< DetId, float > > & hitsAndFractions() const
Definition: CaloCluster.h:178
void setSeed(const CaloClusterPtr &r)
list of used xtals by DetId // now inherited by CaloCluster
Definition: SuperCluster.h:82
void setPhiWidth(double pw)
Definition: SuperCluster.h:57
double pflowEtaWidth() const
void fillSCRefValueMap(edm::Event &iEvent, edm::ValueMap< reco::SuperClusterRef >::Filler &filler) const
const ElementsInBlocks & elementsInBlocks() const
Definition: PFCandidate.h:314
std::vector< PFCandidatePtr > pfCandidates(const PFJet &jet, int particleId, bool sort=true)
AlgoId algo() const
algorithm identifier
Definition: CaloCluster.h:158
void setEtaWidth(double ew)
Definition: SuperCluster.h:58
std::vector< reco::GsfTrackRef > GsfTrackRef_
int iEvent
Definition: GenABIO.cc:243
bool isNull() const
Checks for null.
Definition: Ref.h:244
const CaloID & caloID() const
Definition: CaloCluster.h:169
const reco::PFCandidate & correspondingDaughterCandidate(const reco::PFCandidate &cand, const reco::PFBlockElement &pfbe) const
unsigned index() const
std::vector< SuperCluster > SuperClusterCollection
collection of SuperCluser objectr
void fillMVAValueMap(edm::Event &iEvent, edm::ValueMap< float >::Filler &filler) const
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:84
std::vector< reco::PreshowerClusterCollection > preshowerClusters_
double rawEnergy() const
raw uncorrected energy (sum of energies of component BasicClusters)
Definition: SuperCluster.cc:79
virtual const_iterator begin() const
first daughter const_iterator
virtual PFClusterRef clusterRef() const
void createSuperClusterGsfMapRefs(const edm::OrphanHandle< reco::SuperClusterCollection > &superClustersHandle)
std::vector< PreshowerCluster > PreshowerClusterCollection
collection of PreshowerCluster objects
virtual void produce(edm::Event &, const edm::EventSetup &)
std::vector< int > gsfPFCandidateIndex_
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:359
edm::InputTag inputTagPFCandidates_
std::map< reco::GsfTrackRef, reco::SuperClusterRef > scMap_
edm::InputTag inputTagGSFTracks_
float mva_e_pi() const
mva for electron-pion discrimination
Definition: PFCandidate.h:245
std::vector< reco::PFCandidate > PFCandidateCollection
collection of PFCandidates
DetId seed() const
return DetId of seed
Definition: CaloCluster.h:188
void fetchGsfCollection(edm::Handle< reco::GsfTrackCollection > &c, const edm::InputTag &tag, const edm::Event &iEvent) const
std::string PFBasicClusterCollection_
void createBasicCluster(const reco::PFBlockElement &, reco::BasicClusterCollection &basicClusters, std::vector< const reco::PFCluster * > &, const reco::PFCandidate &coCandidate) const
std::vector< reco::SuperClusterCollection > superClusters_
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:13
std::vector< reco::CaloClusterPtrVector > preshowerClusterPtr_
void createSuperClusters(const reco::PFCandidateCollection &, reco::SuperClusterCollection &superClusters) const
void addPreshowerCluster(const CaloClusterPtr &r)
add reference to constituent BasicCluster
Definition: SuperCluster.h:88
std::vector< BasicCluster > BasicClusterCollection
collection of BasicCluster objects
void addCluster(const CaloClusterPtr &r)
add reference to constituent BasicCluster
Definition: SuperCluster.h:85
std::vector< reco::BasicClusterCollection > basicClusters_
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:34
void createPreshowerCluster(const reco::PFBlockElement &PFBE, reco::PreshowerClusterCollection &preshowerClusters, unsigned plane) const
PFElectronTranslator(const edm::ParameterSet &)
std::string PFSuperClusterCollection_
tuple status
Definition: ntuplemaker.py:245
virtual ParticleType particleId() const
Definition: PFCandidate.h:299
void createPreshowerClusterPtrs(const edm::OrphanHandle< reco::PreshowerClusterCollection > &preshowerClustersHandle)
virtual void beginRun(edm::Run &run, const edm::EventSetup &c)
tuple size
Write out results.
Definition: Run.h:31
void setPreshowerEnergy(double preshowerEnergy)
Definition: SuperCluster.h:56