CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
PFPhotonAlgo.cc
Go to the documentation of this file.
1 //
2 // Original Authors: Fabian Stoeckli: fabian.stoeckli@cern.ch
3 // Nicholas Wardle: nckw@cern.ch
4 // Rishi Patel rpatel@cern.ch(ongoing developer and maintainer)
5 //
6 
22 #include <TFile.h>
23 #include <iomanip>
24 #include <algorithm>
25 #include <TMath.h>
26 using namespace std;
27 using namespace reco;
28 
29 
30 PFPhotonAlgo::PFPhotonAlgo(std::string mvaweightfile,
31  double mvaConvCut,
32  bool useReg,
33  std::string X0_Map,
34  const reco::Vertex& primary,
35  const boost::shared_ptr<PFEnergyCalibration>& thePFEnergyCalibration,
36  double sumPtTrackIsoForPhoton,
37  double sumPtTrackIsoSlopeForPhoton
38  ) :
39  isvalid_(false),
40  verbosityLevel_(Silent),
41  MVACUT(mvaConvCut),
42  useReg_(useReg),
43  thePFEnergyCalibration_(thePFEnergyCalibration),
44  sumPtTrackIsoForPhoton_(sumPtTrackIsoForPhoton),
45  sumPtTrackIsoSlopeForPhoton_(sumPtTrackIsoSlopeForPhoton),
46  nlost(0.0), nlayers(0.0),
47  chi2(0.0), STIP(0.0), del_phi(0.0),HoverPt(0.0), EoverPt(0.0), track_pt(0.0),
48  mvaValue(0.0),
49  CrysPhi_(0.0), CrysEta_(0.0), VtxZ_(0.0), ClusPhi_(0.0), ClusEta_(0.0),
50  ClusR9_(0.0), Clus5x5ratio_(0.0), PFCrysEtaCrack_(0.0), logPFClusE_(0.0), e3x3_(0.0),
51  CrysIPhi_(0), CrysIEta_(0),
52  CrysX_(0.0), CrysY_(0.0),
53  EB(0.0),
54  eSeed_(0.0), e1x3_(0.0),e3x1_(0.0), e1x5_(0.0), e2x5Top_(0.0), e2x5Bottom_(0.0), e2x5Left_(0.0), e2x5Right_(0.0),
55  etop_(0.0), ebottom_(0.0), eleft_(0.0), eright_(0.0),
56  e2x5Max_(0.0),
57  PFPhoEta_(0.0), PFPhoPhi_(0.0), PFPhoR9_(0.0), PFPhoR9Corr_(0.0), SCPhiWidth_(0.0), SCEtaWidth_(0.0),
58  PFPhoEt_(0.0), RConv_(0.0), PFPhoEtCorr_(0.0), PFPhoE_(0.0), PFPhoECorr_(0.0), MustE_(0.0), E3x3_(0.0),
59  dEta_(0.0), dPhi_(0.0), LowClusE_(0.0), RMSAll_(0.0), RMSMust_(0.0), nPFClus_(0.0),
60  TotPS1_(0.0), TotPS2_(0.0),
61  nVtx_(0.0),
62  x0inner_(0.0), x0middle_(0.0), x0outer_(0.0),
63  excluded_(0.0), Mustache_EtRatio_(0.0), Mustache_Et_out_(0.0)
64 {
65  primaryVertex_=primary;
66  //Book MVA
67  tmvaReader_ = new TMVA::Reader("!Color:Silent");
68  tmvaReader_->AddVariable("del_phi",&del_phi);
69  tmvaReader_->AddVariable("nlayers", &nlayers);
70  tmvaReader_->AddVariable("chi2",&chi2);
71  tmvaReader_->AddVariable("EoverPt",&EoverPt);
72  tmvaReader_->AddVariable("HoverPt",&HoverPt);
73  tmvaReader_->AddVariable("track_pt", &track_pt);
74  tmvaReader_->AddVariable("STIP",&STIP);
75  tmvaReader_->AddVariable("nlost", &nlost);
76  tmvaReader_->BookMVA("BDT",mvaweightfile.c_str());
77 
78  //Material Map
79  TFile *XO_File = new TFile(X0_Map.c_str(),"READ");
80  X0_sum=(TH2D*)XO_File->Get("TrackerSum");
81  X0_inner = (TH2D*)XO_File->Get("Inner");
82  X0_middle = (TH2D*)XO_File->Get("Middle");
83  X0_outer = (TH2D*)XO_File->Get("Outer");
84 
85 }
86 
88  std::vector<bool>& active,
89  std::auto_ptr<PFCandidateCollection> &pfCandidates,
90  std::vector<reco::PFCandidatePhotonExtra>& pfPhotonExtraCandidates,
91  std::vector<reco::PFCandidate>
92  &tempElectronCandidates
93 ){
94 
95  //std::cout<<" calling RunPFPhoton "<<std::endl;
96 
97  /* For now we construct the PhotonCandidate simply from
98  a) adding the CORRECTED energies of each participating ECAL cluster
99  b) build the energy-weighted direction for the Photon
100  */
101 
102 
103  // define how much is printed out for debugging.
104  // ... will be setable via CFG file parameter
105  verbosityLevel_ = Chatty; // Chatty mode.
106 
107 
108  // loop over all elements in the Block
109  const edm::OwnVector< reco::PFBlockElement >& elements = blockRef->elements();
111  std::vector<bool>::const_iterator actIter = active.begin();
112  PFBlock::LinkData linkData = blockRef->linkData();
113  bool isActive = true;
114 
115 
116  if(elements.size() != active.size()) {
117  // throw excpetion...
118  //std::cout<<" WARNING: Size of collection and active-vectro don't agree!"<<std::endl;
119  return;
120  }
121 
122  // local vecotr to keep track of the indices of the 'elements' for the Photon candidate
123  // once we decide to keep the candidate, the 'active' entriesd for them must be set to false
124  std::vector<unsigned int> elemsToLock;
125  elemsToLock.resize(0);
126 
127  for( ; ele != elements.end(); ++ele, ++actIter ) {
128 
129  // if it's not a SuperCluster, go to the next element
130  if( !( ele->type() == reco::PFBlockElement::SC ) ) continue;
131 
132  // Photon kienmatics, will be updated for each identified participating element
133  float photonEnergy_ = 0.;
134  float photonX_ = 0.;
135  float photonY_ = 0.;
136  float photonZ_ = 0.;
137  float RawEcalEne = 0.;
138 
139  // Total pre-shower energy
140  float ps1TotEne = 0.;
141  float ps2TotEne = 0.;
142 
143  bool hasConvTrack=false;
144  bool hasSingleleg=false;
145  std::vector<unsigned int> AddClusters(0);
146  std::vector<unsigned int> IsoTracks(0);
147  std::multimap<unsigned int, unsigned int>ClusterAddPS1;
148  std::multimap<unsigned int, unsigned int>ClusterAddPS2;
149  std::vector<reco::TrackRef>singleLegRef;
150  std::vector<float>MVA_values(0);
151  std::vector<float>MVALCorr;
152  std::vector<CaloCluster>PFClusters;
153  reco::ConversionRefVector ConversionsRef_;
154  isActive = *(actIter);
155  //cout << " Found a SuperCluster. Energy " ;
156  const reco::PFBlockElementSuperCluster *sc = dynamic_cast<const reco::PFBlockElementSuperCluster*>(&(*ele));
157  //std::cout << sc->superClusterRef()->energy () << " Track/Ecal/Hcal Iso " << sc->trackIso()<< " " << sc->ecalIso() ;
158  //std::cout << " " << sc->hcalIso() <<std::endl;
159  if (!(sc->fromPhoton()))continue;
160 
161  // check the status of the SC Element...
162  // ..... I understand it should *always* be active, since PFElectronAlgo does not touch this (yet?) RISHI: YES
163  if( !isActive ) {
164  //std::cout<<" SuperCluster is NOT active.... "<<std::endl;
165  continue;
166  }
167  elemsToLock.push_back(ele-elements.begin()); //add SC to elements to lock
168  // loop over its constituent ECAL cluster
169  std::multimap<double, unsigned int> ecalAssoPFClusters;
170  blockRef->associatedElements( ele-elements.begin(),
171  linkData,
172  ecalAssoPFClusters,
175  //R9 of SuperCluster and RawE
176  PFPhoR9_=sc->photonRef()->r9();
177  E3x3_=PFPhoR9_*(sc->superClusterRef()->rawEnergy());
178  // loop over the ECAL clusters linked to the iEle
179  if( ! ecalAssoPFClusters.size() ) {
180  // This SC element has NO ECAL elements asigned... *SHOULD NOT HAPPEN*
181  //std::cout<<" Found SC element with no ECAL assigned "<<std::endl;
182  continue;
183  }
184 
185  // This is basically CASE 2
186  // .... we loop over all ECAL cluster linked to each other by this SC
187  for(std::multimap<double, unsigned int>::iterator itecal = ecalAssoPFClusters.begin();
188  itecal != ecalAssoPFClusters.end(); ++itecal) {
189 
190  // to get the reference to the PF clusters, this is needed.
191  reco::PFClusterRef clusterRef = elements[itecal->second].clusterRef();
192 
193  // from the clusterRef get the energy, direction, etc
194  // float ClustRawEnergy = clusterRef->energy();
195  // float ClustEta = clusterRef->position().eta();
196  // float ClustPhi = clusterRef->position().phi();
197 
198  // initialize the vectors for the PS energies
199  vector<double> ps1Ene(0);
200  vector<double> ps2Ene(0);
201  double ps1=0;
202  double ps2=0;
203  hasSingleleg=false;
204  hasConvTrack=false;
205 
206  /*
207  cout << " My cluster index " << itecal->second
208  << " energy " << ClustRawEnergy
209  << " eta " << ClustEta
210  << " phi " << ClustPhi << endl;
211  */
212  // check if this ECAL element is still active (could have been eaten by PFElectronAlgo)
213  // ......for now we give the PFElectron Algo *ALWAYS* Shot-Gun on the ECAL elements to the PFElectronAlgo
214 
215  if( !( active[itecal->second] ) ) {
216  //std::cout<< " .... this ECAL element is NOT active anymore. Is skipped. "<<std::endl;
217  continue;
218  }
219 
220  // ------------------------------------------------------------------------------------------
221  // TODO: do some tests on the ECAL cluster itself, deciding to use it or not for the Photons
222  // ..... ??? Do we need this?
223  if ( false ) {
224  // Check if there are a large number tracks that do not pass pre-ID around this ECAL cluster
225  bool useIt = true;
226  int mva_reject=0;
227  bool isClosest=false;
228  std::multimap<double, unsigned int> Trackscheck;
229  blockRef->associatedElements( itecal->second,
230  linkData,
231  Trackscheck,
234  for(std::multimap<double, unsigned int>::iterator track = Trackscheck.begin();
235  track != Trackscheck.end(); ++track) {
236 
237  // first check if is it's still active
238  if( ! (active[track->second]) ) continue;
239  hasSingleleg=EvaluateSingleLegMVA(blockRef, primaryVertex_, track->second);
240  //check if it is the closest linked track
241  std::multimap<double, unsigned int> closecheck;
242  blockRef->associatedElements(track->second,
243  linkData,
244  closecheck,
245  reco::PFBlockElement::ECAL,
247  if(closecheck.begin()->second ==itecal->second)isClosest=true;
248  if(!hasSingleleg)mva_reject++;
249  }
250 
251  if(mva_reject>0 && isClosest)useIt=false;
252  //if(mva_reject==1 && isClosest)useIt=false;
253  if( !useIt ) continue; // Go to next ECAL cluster within SC
254  }
255  // ------------------------------------------------------------------------------------------
256 
257  // We decided to keep the ECAL cluster for this Photon Candidate ...
258  elemsToLock.push_back(itecal->second);
259 
260  // look for PS in this Block linked to this ECAL cluster
261  std::multimap<double, unsigned int> PS1Elems;
262  std::multimap<double, unsigned int> PS2Elems;
263  //PS Layer 1 linked to ECAL cluster
264  blockRef->associatedElements( itecal->second,
265  linkData,
266  PS1Elems,
269  //PS Layer 2 linked to the ECAL cluster
270  blockRef->associatedElements( itecal->second,
271  linkData,
272  PS2Elems,
275 
276  // loop over all PS1 and compute energy
277  for(std::multimap<double, unsigned int>::iterator iteps = PS1Elems.begin();
278  iteps != PS1Elems.end(); ++iteps) {
279 
280  // first chekc if it's still active
281  if( !(active[iteps->second]) ) continue;
282 
283  //Check if this PS1 is not closer to another ECAL cluster in this Block
284  std::multimap<double, unsigned int> ECALPS1check;
285  blockRef->associatedElements( iteps->second,
286  linkData,
287  ECALPS1check,
288  reco::PFBlockElement::ECAL,
290  if(itecal->second==ECALPS1check.begin()->second)//then it is closest linked
291  {
292  reco::PFClusterRef ps1ClusterRef = elements[iteps->second].clusterRef();
293  ps1Ene.push_back( ps1ClusterRef->energy() );
294  ps1=ps1+ps1ClusterRef->energy(); //add to total PS1
295  // incativate this PS1 Element
296  elemsToLock.push_back(iteps->second);
297  }
298  }
299  for(std::multimap<double, unsigned int>::iterator iteps = PS2Elems.begin();
300  iteps != PS2Elems.end(); ++iteps) {
301 
302  // first chekc if it's still active
303  if( !(active[iteps->second]) ) continue;
304 
305  // Check if this PS2 is not closer to another ECAL cluster in this Block:
306  std::multimap<double, unsigned int> ECALPS2check;
307  blockRef->associatedElements( iteps->second,
308  linkData,
309  ECALPS2check,
310  reco::PFBlockElement::ECAL,
312  if(itecal->second==ECALPS2check.begin()->second)//is closest linked
313  {
314  reco::PFClusterRef ps2ClusterRef = elements[iteps->second].clusterRef();
315  ps2Ene.push_back( ps2ClusterRef->energy() );
316  ps2=ps2ClusterRef->energy()+ps2; //add to total PS2
317  // incativate this PS2 Element
318  elemsToLock.push_back(iteps->second);
319  }
320  }
321 
322  // loop over the HCAL Clusters linked to the ECAL cluster (CASE 6)
323  std::multimap<double, unsigned int> hcalElems;
324  blockRef->associatedElements( itecal->second,linkData,
325  hcalElems,
328 
329  for(std::multimap<double, unsigned int>::iterator ithcal = hcalElems.begin();
330  ithcal != hcalElems.end(); ++ithcal) {
331 
332  if ( ! (active[ithcal->second] ) ) continue; // HCAL Cluster already used....
333 
334  // TODO: Decide if this HCAL cluster is to be used
335  // .... based on some Physics
336  // .... To we need to check if it's closer to any other ECAL/TRACK?
337 
338  bool useHcal = false;
339  if ( !useHcal ) continue;
340  //not locked
341  //elemsToLock.push_back(ithcal->second);
342  }
343 
344  // This is entry point for CASE 3.
345  // .... we loop over all Tracks linked to this ECAL and check if it's labeled as conversion
346  // This is the part for looping over all 'Conversion' Tracks
347  std::multimap<double, unsigned int> convTracks;
348  blockRef->associatedElements( itecal->second,
349  linkData,
350  convTracks,
353  for(std::multimap<double, unsigned int>::iterator track = convTracks.begin();
354  track != convTracks.end(); ++track) {
355 
356  // first check if is it's still active
357  if( ! (active[track->second]) ) continue;
358 
359  // check if it's a CONV track
360  const reco::PFBlockElementTrack * trackRef = dynamic_cast<const reco::PFBlockElementTrack*>((&elements[track->second]));
361 
362  //Check if track is a Single leg from a Conversion
363  mvaValue=-999;
364  hasSingleleg=EvaluateSingleLegMVA(blockRef, primaryVertex_, track->second);
365 
366  // Daniele; example for mvaValues, do the same for single leg trackRef and convRef
367  //
368  // if(hasSingleleg)
369  // mvaValues.push_back(mvaValue);
370 
371  //If it is not then it will be used to check Track Isolation at the end
372  if(!hasSingleleg)
373  {
374  bool included=false;
375  //check if this track is already included in the vector so it is linked to an ECAL cluster that is already examined
376  for(unsigned int i=0; i<IsoTracks.size(); i++)
377  {if(IsoTracks[i]==track->second)included=true;}
378  if(!included)IsoTracks.push_back(track->second);
379  }
380  //For now only Pre-ID tracks that are not already identified as Conversions
381  if(hasSingleleg &&!(trackRef->trackType(reco::PFBlockElement::T_FROM_GAMMACONV)))
382  {
383  elemsToLock.push_back(track->second);
384 
385  reco::TrackRef t_ref=elements[track->second].trackRef();
386  bool matched=false;
387  for(unsigned int ic=0; ic<singleLegRef.size(); ic++)
388  if(singleLegRef[ic]==t_ref)matched=true;
389 
390  if(!matched){
391  singleLegRef.push_back(t_ref);
392  MVA_values.push_back(mvaValue);
393  }
394  //find all the clusters linked to this track
395  std::multimap<double, unsigned int> moreClusters;
396  blockRef->associatedElements( track->second,
397  linkData,
398  moreClusters,
399  reco::PFBlockElement::ECAL,
401 
402  float p_in=sqrt(elements[track->second].trackRef()->innerMomentum().x() * elements[track->second].trackRef()->innerMomentum().x() +
403  elements[track->second].trackRef()->innerMomentum().y()*elements[track->second].trackRef()->innerMomentum().y()+
404  elements[track->second].trackRef()->innerMomentum().z()*elements[track->second].trackRef()->innerMomentum().z());
405  float linked_E=0;
406  for(std::multimap<double, unsigned int>::iterator clust = moreClusters.begin();
407  clust != moreClusters.end(); ++clust)
408  {
409  if(!active[clust->second])continue;
410  //running sum of linked energy
411  linked_E=linked_E+elements[clust->second].clusterRef()->energy();
412  //prevent too much energy from being added
413  if(linked_E/p_in>1.5)break;
414  bool included=false;
415  //check if these ecal clusters are already included with the supercluster
416  for(std::multimap<double, unsigned int>::iterator cluscheck = ecalAssoPFClusters.begin();
417  cluscheck != ecalAssoPFClusters.end(); ++cluscheck)
418  {
419  if(cluscheck->second==clust->second)included=true;
420  }
421  if(!included)AddClusters.push_back(clust->second);//Add to a container of clusters to be Added to the Photon candidate
422  }
423  }
424 
425  // Possibly need to be more smart about them (CASE 5)
426  // .... for now we simply skip non id'ed tracks
427  if( ! (trackRef->trackType(reco::PFBlockElement::T_FROM_GAMMACONV) ) ) continue;
428  hasConvTrack=true;
429  elemsToLock.push_back(track->second);
430  //again look at the clusters linked to this track
431  //if(elements[track->second].convRef().isNonnull())
432  //{
433  // ConversionsRef_.push_back(elements[track->second].convRef());
434  //}
435  std::multimap<double, unsigned int> moreClusters;
436  blockRef->associatedElements( track->second,
437  linkData,
438  moreClusters,
439  reco::PFBlockElement::ECAL,
441 
442  float p_in=sqrt(elements[track->second].trackRef()->innerMomentum().x() * elements[track->second].trackRef()->innerMomentum().x() +
443  elements[track->second].trackRef()->innerMomentum().y()*elements[track->second].trackRef()->innerMomentum().y()+
444  elements[track->second].trackRef()->innerMomentum().z()*elements[track->second].trackRef()->innerMomentum().z());
445  float linked_E=0;
446  for(std::multimap<double, unsigned int>::iterator clust = moreClusters.begin();
447  clust != moreClusters.end(); ++clust)
448  {
449  if(!active[clust->second])continue;
450  linked_E=linked_E+elements[clust->second].clusterRef()->energy();
451  if(linked_E/p_in>1.5)break;
452  bool included=false;
453  for(std::multimap<double, unsigned int>::iterator cluscheck = ecalAssoPFClusters.begin();
454  cluscheck != ecalAssoPFClusters.end(); ++cluscheck)
455  {
456  if(cluscheck->second==clust->second)included=true;
457  }
458  if(!included)AddClusters.push_back(clust->second);//again only add if it is not already included with the supercluster
459  }
460 
461  // we need to check for other TRACKS linked to this conversion track, that point possibly no an ECAL cluster not included in the SC
462  // .... This is basically CASE 4.
463 
464  std::multimap<double, unsigned int> moreTracks;
465  blockRef->associatedElements( track->second,
466  linkData,
467  moreTracks,
470 
471  for(std::multimap<double, unsigned int>::iterator track2 = moreTracks.begin();
472  track2 != moreTracks.end(); ++track2) {
473 
474  // first check if is it's still active
475  if( ! (active[track2->second]) ) continue;
476  //skip over the 1st leg already found above
477  if(track->second==track2->second)continue;
478  // check if it's a CONV track
479  const reco::PFBlockElementTrack * track2Ref = dynamic_cast<const reco::PFBlockElementTrack*>((&elements[track2->second]));
480  if( ! (track2Ref->trackType(reco::PFBlockElement::T_FROM_GAMMACONV) ) ) continue; // Possibly need to be more smart about them (CASE 5)
481  elemsToLock.push_back(track2->second);
482  // so it's another active conversion track, that is in the Block and linked to the conversion track we already found
483  // find the ECAL cluster linked to it...
484  std::multimap<double, unsigned int> convEcal;
485  blockRef->associatedElements( track2->second,
486  linkData,
487  convEcal,
488  reco::PFBlockElement::ECAL,
490  float p_in=sqrt(elements[track->second].trackRef()->innerMomentum().x()*elements[track->second].trackRef()->innerMomentum().x()+
491  elements[track->second].trackRef()->innerMomentum().y()*elements[track->second].trackRef()->innerMomentum().y()+
492  elements[track->second].trackRef()->innerMomentum().z()*elements[track->second].trackRef()->innerMomentum().z());
493 
494 
495  float linked_E=0;
496  for(std::multimap<double, unsigned int>::iterator itConvEcal = convEcal.begin();
497  itConvEcal != convEcal.end(); ++itConvEcal) {
498 
499  if( ! (active[itConvEcal->second]) ) continue;
500  bool included=false;
501  for(std::multimap<double, unsigned int>::iterator cluscheck = ecalAssoPFClusters.begin();
502  cluscheck != ecalAssoPFClusters.end(); ++cluscheck)
503  {
504  if(cluscheck->second==itConvEcal->second)included=true;
505  }
506  linked_E=linked_E+elements[itConvEcal->second].clusterRef()->energy();
507  if(linked_E/p_in>1.5)break;
508  if(!included){AddClusters.push_back(itConvEcal->second);
509  }
510 
511  // it's still active, so we have to add it.
512  // CAUTION: we don't care here if it's part of the SC or not, we include it anyways
513 
514  // loop over the HCAL Clusters linked to the ECAL cluster (CASE 6)
515  std::multimap<double, unsigned int> hcalElems_conv;
516  blockRef->associatedElements( itecal->second,linkData,
517  hcalElems_conv,
520 
521  for(std::multimap<double, unsigned int>::iterator ithcal2 = hcalElems_conv.begin();
522  ithcal2 != hcalElems_conv.end(); ++ithcal2) {
523 
524  if ( ! (active[ithcal2->second] ) ) continue; // HCAL Cluster already used....
525 
526  // TODO: Decide if this HCAL cluster is to be used
527  // .... based on some Physics
528  // .... To we need to check if it's closer to any other ECAL/TRACK?
529 
530  bool useHcal = true;
531  if ( !useHcal ) continue;
532 
533  //elemsToLock.push_back(ithcal2->second);
534 
535  } // end of loop over HCAL clusters linked to the ECAL cluster from second CONVERSION leg
536 
537  } // end of loop over ECALs linked to second T_FROM_GAMMACONV
538 
539  } // end of loop over SECOND conversion leg
540 
541  // TODO: Do we need to check separatly if there are HCAL cluster linked to the track?
542 
543  } // end of loop over tracks
544 
545 
546  // Calibrate the Added ECAL energy
547  float addedCalibEne=0;
548  float addedRawEne=0;
549  std::vector<double>AddedPS1(0);
550  std::vector<double>AddedPS2(0);
551  double addedps1=0;
552  double addedps2=0;
553  for(unsigned int i=0; i<AddClusters.size(); i++)
554  {
555  std::multimap<double, unsigned int> PS1Elems_conv;
556  std::multimap<double, unsigned int> PS2Elems_conv;
557  blockRef->associatedElements(AddClusters[i],
558  linkData,
559  PS1Elems_conv,
562  blockRef->associatedElements( AddClusters[i],
563  linkData,
564  PS2Elems_conv,
567 
568  for(std::multimap<double, unsigned int>::iterator iteps = PS1Elems_conv.begin();
569  iteps != PS1Elems_conv.end(); ++iteps)
570  {
571  if(!active[iteps->second])continue;
572  std::multimap<double, unsigned int> PS1Elems_check;
573  blockRef->associatedElements(iteps->second,
574  linkData,
575  PS1Elems_check,
576  reco::PFBlockElement::ECAL,
578  if(PS1Elems_check.begin()->second==AddClusters[i])
579  {
580 
581  reco::PFClusterRef ps1ClusterRef = elements[iteps->second].clusterRef();
582  AddedPS1.push_back(ps1ClusterRef->energy());
583  addedps1=addedps1+ps1ClusterRef->energy();
584  elemsToLock.push_back(iteps->second);
585  }
586  }
587 
588  for(std::multimap<double, unsigned int>::iterator iteps = PS2Elems_conv.begin();
589  iteps != PS2Elems_conv.end(); ++iteps) {
590  if(!active[iteps->second])continue;
591  std::multimap<double, unsigned int> PS2Elems_check;
592  blockRef->associatedElements(iteps->second,
593  linkData,
594  PS2Elems_check,
595  reco::PFBlockElement::ECAL,
597 
598  if(PS2Elems_check.begin()->second==AddClusters[i])
599  {
600  reco::PFClusterRef ps2ClusterRef = elements[iteps->second].clusterRef();
601  AddedPS2.push_back(ps2ClusterRef->energy());
602  addedps2=addedps2+ps2ClusterRef->energy();
603  elemsToLock.push_back(iteps->second);
604  }
605  }
606  reco::PFClusterRef AddclusterRef = elements[AddClusters[i]].clusterRef();
607  addedRawEne = AddclusterRef->energy()+addedRawEne;
608  addedCalibEne = thePFEnergyCalibration_->energyEm(*AddclusterRef,AddedPS1,AddedPS2,false)+addedCalibEne;
609  AddedPS2.clear();
610  AddedPS1.clear();
611  elemsToLock.push_back(AddClusters[i]);
612  }
613  AddClusters.clear();
614  float EE=thePFEnergyCalibration_->energyEm(*clusterRef,ps1Ene,ps2Ene,false)+addedCalibEne;
615  PFClusters.push_back(*clusterRef);
616  if(useReg_){
617  float LocCorr=EvaluateLCorrMVA(clusterRef);
618  EE=LocCorr*clusterRef->energy()+addedCalibEne;
619  }
620  else{
621  float LocCorr=EvaluateLCorrMVA(clusterRef);
622  MVALCorr.push_back(LocCorr*clusterRef->energy());
623  }
624 
625  //cout<<"Original Energy "<<EE<<"Added Energy "<<addedCalibEne<<endl;
626 
627  photonEnergy_ += EE;
628  RawEcalEne += clusterRef->energy()+addedRawEne;
629  photonX_ += EE * clusterRef->position().X();
630  photonY_ += EE * clusterRef->position().Y();
631  photonZ_ += EE * clusterRef->position().Z();
632  ps1TotEne += ps1+addedps1;
633  ps2TotEne += ps2+addedps2;
634  } // end of loop over all ECAL cluster within this SC
635  AddFromElectron_.clear();
636  float Elec_energy=0;
637  float Elec_rawEcal=0;
638  float Elec_totPs1=0;
639  float Elec_totPs2=0;
640  float ElectronX=0;
641  float ElectronY=0;
642  float ElectronZ=0;
643  std::vector<double>AddedPS1(0);
644  std::vector<double>AddedPS2(0);
645 
647  tempElectronCandidates,
648  sc
649  );
650 
651  if(AddFromElectron_.size()>0)
652  {
653  //collect elements from early Conversions that are reconstructed as Electrons
654 
655  for(std::vector<unsigned int>::const_iterator it =
656  AddFromElectron_.begin();
657  it != AddFromElectron_.end(); ++it)
658  {
659 
660  if(elements[*it].type()== reco::PFBlockElement::ECAL)
661  {
662  //cout<<"Cluster ind "<<*it<<endl;
663  AddedPS1.clear();
664  AddedPS2.clear();
665  unsigned int index=*it;
666  reco::PFClusterRef clusterRef =
667  elements[index].clusterRef();
668  //match to PS1 and PS2 to this cluster for calibration
669  Elec_rawEcal=Elec_rawEcal+
670  elements[index].clusterRef()->energy();
671  std::multimap<double, unsigned int> PS1Elems;
672  std::multimap<double, unsigned int> PS2Elems;
673 
674  blockRef->associatedElements(index,
675  linkData,
676  PS1Elems, reco::PFBlockElement::PS1,
678  blockRef->associatedElements( index,
679  linkData,
680  PS2Elems,
683 
684 
685  for(std::multimap<double, unsigned int>::iterator iteps =
686  PS1Elems.begin();
687  iteps != PS1Elems.end(); ++iteps)
688  {
689  std::multimap<double, unsigned int> Clustcheck; blockRef->associatedElements( iteps->second, linkData,
690  Clustcheck,
691  reco::PFBlockElement::ECAL,
693  if(Clustcheck.begin()->second==index)
694  {
695  AddedPS1.push_back(elements[iteps->second].clusterRef()->energy());
696  Elec_totPs1=Elec_totPs1+elements[iteps->second].clusterRef()->energy();
697  }
698  }
699 
700  for(std::multimap<double, unsigned int>::iterator iteps =
701  PS2Elems.begin();
702  iteps != PS2Elems.end(); ++iteps)
703  {
704  std::multimap<double, unsigned int> Clustcheck; blockRef->associatedElements( iteps->second, linkData,
705  Clustcheck,
706  reco::PFBlockElement::ECAL,
708  if(Clustcheck.begin()->second==index)
709  {
710  AddedPS2.push_back(elements[iteps->second].clusterRef()->energy());
711  Elec_totPs2=Elec_totPs2+elements[iteps->second].clusterRef()->energy();
712  }
713  }
714 
715  //energy calibration
716  float EE=thePFEnergyCalibration_->
717  energyEm(*clusterRef,AddedPS1,AddedPS2,false);
718  PFClusters.push_back(*clusterRef);
719  if(useReg_){
720  float LocCorr=EvaluateLCorrMVA(clusterRef);
721  EE=LocCorr*clusterRef->energy();
722  MVALCorr.push_back(LocCorr*clusterRef->energy());
723 
724  }
725  else{
726  float LocCorr=EvaluateLCorrMVA(clusterRef);
727  MVALCorr.push_back(LocCorr*clusterRef->energy());
728  }
729 
730  Elec_energy += EE;
731  ElectronX += EE * clusterRef->position().X();
732  ElectronY += EE * clusterRef->position().Y();
733  ElectronZ += EE * clusterRef->position().Z();
734 
735  }
736  if(elements[*it].type()==reco::PFBlockElement::TRACK){
737  reco::TrackRef t_ref=elements[*it].trackRef();
738  singleLegRef.push_back(t_ref);
739  EvaluateSingleLegMVA(blockRef, primaryVertex_, *it);
740  MVA_values.push_back(mvaValue);
741  }
742  }
743 
744  }
745 
746  //std::cout<<"Added Energy to Photon "<<Elec_energy<<" to "<<photonEnergy_<<std::endl;
747  photonEnergy_ += Elec_energy;
748  RawEcalEne += Elec_rawEcal;
749  photonX_ += ElectronX;
750  photonY_ += ElectronY;
751  photonZ_ += ElectronZ;
752  ps1TotEne += Elec_totPs1;
753  ps2TotEne += Elec_totPs2;
754 
755  // we've looped over all ECAL clusters, ready to generate PhotonCandidate
756  if( ! (photonEnergy_ > 0.) ) continue; // This SC is not a Photon Candidate
757  float sum_track_pt=0;
758  //Now check if there are tracks failing isolation outside of the Jurassic isolation region
759  for(unsigned int i=0; i<IsoTracks.size(); i++)sum_track_pt=sum_track_pt+elements[IsoTracks[i]].trackRef()->pt();
760 
761 
762 
763  math::XYZVector photonPosition(photonX_,
764  photonY_,
765  photonZ_);
766 
767  math::XYZVector photonDirection=photonPosition.Unit();
768 
769  math::XYZTLorentzVector photonMomentum(photonEnergy_* photonDirection.X(),
770  photonEnergy_* photonDirection.Y(),
771  photonEnergy_* photonDirection.Z(),
772  photonEnergy_ );
773 
774  if(sum_track_pt>(sumPtTrackIsoForPhoton_ + sumPtTrackIsoSlopeForPhoton_ * photonMomentum.pt()) && AddFromElectron_.size()==0)
775  {
776  elemsToLock.resize(0);
777  continue;
778 
779  }
780 
781  //THIS SC is not a Photon it fails track Isolation
782  //if(sum_track_pt>(2+ 0.001* photonMomentum.pt()))
783  //continue;//THIS SC is not a Photon it fails track Isolation
784 
785  /*
786  std::cout<<" Created Photon with energy = "<<photonEnergy_<<std::endl;
787  std::cout<<" pT = "<<photonMomentum.pt()<<std::endl;
788  std::cout<<" RawEne = "<<RawEcalEne<<std::endl;
789  std::cout<<" E = "<<photonMomentum.e()<<std::endl;
790  std::cout<<" eta = "<<photonMomentum.eta()<<std::endl;
791  std::cout<<" TrackIsolation = "<< sum_track_pt <<std::endl;
792  */
793 
794  reco::PFCandidate photonCand(0,photonMomentum, reco::PFCandidate::gamma);
795 
796  photonCand.setPs1Energy(ps1TotEne);
797  photonCand.setPs2Energy(ps2TotEne);
798  photonCand.setEcalEnergy(RawEcalEne,photonEnergy_);
799  photonCand.setHcalEnergy(0.,0.);
800  photonCand.set_mva_nothing_gamma(1.);
801  photonCand.setSuperClusterRef(sc->superClusterRef());
803  photonCand.setVertex( v );
804  if(hasConvTrack || hasSingleleg)photonCand.setFlag( reco::PFCandidate::GAMMA_TO_GAMMACONV, true);
805  int matches=match_ind.size();
806  int count=0;
807  for ( std::vector<reco::PFCandidate>::const_iterator ec=tempElectronCandidates.begin(); ec != tempElectronCandidates.end(); ++ec ){
808  for(int i=0; i<matches; i++)
809  {
810  if(count==match_ind[i])photonCand.addDaughter(*ec);
811  count++;
812  }
813  }
814  //photonCand.setPositionAtECALEntrance(math::XYZPointF(photonMom_.position()));
815  // set isvalid_ to TRUE since we've found at least one photon candidate
816  isvalid_ = true;
817  // push back the candidate into the collection ...
818  //Add Elements from Electron
819  for(std::vector<unsigned int>::const_iterator it =
820  AddFromElectron_.begin();
821  it != AddFromElectron_.end(); ++it)photonCand.addElementInBlock(blockRef,*it);
822 
823 
824  // ... and lock all elemts used
825  for(std::vector<unsigned int>::const_iterator it = elemsToLock.begin();
826  it != elemsToLock.end(); ++it)
827  {
828  if(active[*it])
829  {
830  photonCand.addElementInBlock(blockRef,*it);
831  if( elements[*it].type() == reco::PFBlockElement::TRACK )
832  {
833  if(elements[*it].convRef().isNonnull())
834  {
835  //make sure it is not stored already as the partner track
836  bool matched=false;
837  for(unsigned int ic = 0; ic < ConversionsRef_.size(); ic++)
838  {
839  if(ConversionsRef_[ic]==elements[*it].convRef())matched=true;
840  }
841  if(!matched)ConversionsRef_.push_back(elements[*it].convRef());
842  }
843  }
844  }
845  active[*it] = false;
846  }
847  PFPhoECorr_=0;
848  // here add the extra information
850  //Store Locally Contained PF Cluster regressed energy
851  for(unsigned int l=0; l<MVALCorr.size(); ++l)
852  {
853  myExtra.addLCorrClusEnergy(MVALCorr[l]);
854  PFPhoECorr_=PFPhoECorr_+MVALCorr[l];//total Locally corrected energy
855  }
856  TotPS1_=ps1TotEne;
857  TotPS2_=ps2TotEne;
858  //Do Global Corrections here:
859  float GCorr=EvaluateGCorrMVA(photonCand, PFClusters);
860  if(useReg_){
861  math::XYZTLorentzVector photonCorrMomentum(GCorr*PFPhoECorr_* photonDirection.X(),
862  GCorr*PFPhoECorr_* photonDirection.Y(),
863  GCorr*PFPhoECorr_* photonDirection.Z(),
864  GCorr * photonEnergy_ );
865  photonCand.setP4(photonCorrMomentum);
866  }
867  //Mustache ID variables
868  Mustache Must;
869  Must.FillMustacheVar(PFClusters);
870  int excluded= Must.OutsideMust();
871  float MustacheEt=Must.MustacheEtOut();
872  myExtra.setMustache_Et(MustacheEt);
873  myExtra.setExcludedClust(excluded);
874  if(fabs(photonCand.eta()<1.4446))
875  myExtra.setMVAGlobalCorrE(GCorr * PFPhoECorr_);
876  else if(PFPhoR9_>0.94)
877  myExtra.setMVAGlobalCorrE(GCorr * PFPhoECorr_);
878  else myExtra.setMVAGlobalCorrE(GCorr * photonEnergy_);
879  float Res=EvaluateResMVA(photonCand, PFClusters);
880  myExtra.SetPFPhotonRes(Res);
881 
882  // Daniele example for mvaValues
883  // do the same for single leg trackRef and convRef
884  for(unsigned int ic = 0; ic < MVA_values.size(); ic++)
885  {
886  myExtra.addSingleLegConvMva(MVA_values[ic]);
887  myExtra.addSingleLegConvTrackRef(singleLegRef[ic]);
888  //cout<<"Single Leg Tracks "<<singleLegRef[ic]->pt()<<" MVA "<<MVA_values[ic]<<endl;
889  }
890  for(unsigned int ic = 0; ic < ConversionsRef_.size(); ic++)
891  {
892  myExtra.addConversionRef(ConversionsRef_[ic]);
893  //cout<<"Conversion Pairs "<<ConversionsRef_[ic]->pairMomentum()<<endl;
894  }
895  pfPhotonExtraCandidates.push_back(myExtra);
896  pfCandidates->push_back(photonCand);
897  // ... and reset the vector
898  elemsToLock.resize(0);
899  hasConvTrack=false;
900  hasSingleleg=false;
901  } // end of loops over all elements in block
902 
903  return;
904 }
905 
906 float PFPhotonAlgo::EvaluateResMVA(reco::PFCandidate photon, std::vector<reco::CaloCluster>PFClusters){
907  float BDTG=1;
908  PFPhoEta_=photon.eta();
909  PFPhoPhi_=photon.phi();
910  PFPhoE_=photon.energy();
911  //fill Material Map:
912  int ix = X0_sum->GetXaxis()->FindBin(PFPhoEta_);
913  int iy = X0_sum->GetYaxis()->FindBin(PFPhoPhi_);
914  x0inner_= X0_inner->GetBinContent(ix,iy);
915  x0middle_=X0_middle->GetBinContent(ix,iy);
916  x0outer_=X0_outer->GetBinContent(ix,iy);
917  SCPhiWidth_=photon.superClusterRef()->phiWidth();
918  SCEtaWidth_=photon.superClusterRef()->etaWidth();
919  Mustache Must;
920  std::vector<unsigned int>insideMust;
921  std::vector<unsigned int>outsideMust;
922  std::multimap<float, unsigned int>OrderedClust;
923  Must.FillMustacheVar(PFClusters);
924  MustE_=Must.MustacheE();
925  LowClusE_=Must.LowestMustClust();
927  Must.MustacheClust(PFClusters,insideMust, outsideMust );
928  for(unsigned int i=0; i<insideMust.size(); ++i){
929  int index=insideMust[i];
930  OrderedClust.insert(make_pair(PFClusters[index].energy(),index));
931  }
932  std::multimap<float, unsigned int>::iterator it;
933  it=OrderedClust.begin();
934  unsigned int lowEindex=(*it).second;
935  std::multimap<float, unsigned int>::reverse_iterator rit;
936  rit=OrderedClust.rbegin();
937  unsigned int highEindex=(*rit).second;
938  if(insideMust.size()>1){
939  dEta_=fabs(PFClusters[highEindex].eta()-PFClusters[lowEindex].eta());
940  dPhi_=asin(PFClusters[highEindex].phi()-PFClusters[lowEindex].phi());
941  }
942  else{
943  dEta_=0;
944  dPhi_=0;
945  LowClusE_=0;
946  }
947  //calculate RMS for All clusters and up until the Next to Lowest inside the Mustache
948  RMSAll_=ClustersPhiRMS(PFClusters, PFPhoPhi_);
949  std::vector<reco::CaloCluster>PFMustClusters;
950  if(insideMust.size()>2){
951  for(unsigned int i=0; i<insideMust.size(); ++i){
952  unsigned int index=insideMust[i];
953  if(index==lowEindex)continue;
954  PFMustClusters.push_back(PFClusters[index]);
955  }
956  }
957  else{
958  for(unsigned int i=0; i<insideMust.size(); ++i){
959  unsigned int index=insideMust[i];
960  PFMustClusters.push_back(PFClusters[index]);
961  }
962  }
963  RMSMust_=ClustersPhiRMS(PFMustClusters, PFPhoPhi_);
964  //then use cluster Width for just one PFCluster
965  RConv_=310;
966  PFCandidate::ElementsInBlocks eleInBlocks = photon.elementsInBlocks();
967  for(unsigned i=0; i<eleInBlocks.size(); i++)
968  {
969  PFBlockRef blockRef = eleInBlocks[i].first;
970  unsigned indexInBlock = eleInBlocks[i].second;
971  const edm::OwnVector< reco::PFBlockElement >& elements=eleInBlocks[i].first->elements();
972  const reco::PFBlockElement& element = elements[indexInBlock];
973  if(element.type()==reco::PFBlockElement::TRACK){
974  float R=sqrt(element.trackRef()->innerPosition().X()*element.trackRef()->innerPosition().X()+element.trackRef()->innerPosition().Y()*element.trackRef()->innerPosition().Y());
975  if(RConv_>R)RConv_=R;
976  }
977  else continue;
978  }
979  float GC_Var[17];
980  GC_Var[0]=PFPhoEta_;
981  GC_Var[1]=PFPhoEt_;
982  GC_Var[2]=PFPhoR9Corr_;
983  GC_Var[3]=PFPhoPhi_;
984  GC_Var[4]=SCEtaWidth_;
985  GC_Var[5]=SCPhiWidth_;
986  GC_Var[6]=x0inner_;
987  GC_Var[7]=x0middle_;
988  GC_Var[8]=x0outer_;
989  GC_Var[9]=RConv_;
990  GC_Var[10]=LowClusE_;
991  GC_Var[11]=RMSMust_;
992  GC_Var[12]=RMSAll_;
993  GC_Var[13]=dEta_;
994  GC_Var[14]=dPhi_;
995  GC_Var[15]=nVtx_;
996  GC_Var[16]=MustE_;
997 
998  BDTG=ReaderRes_->GetResponse(GC_Var);
999  // cout<<"Res "<<BDTG<<endl;
1000 
1001  // cout<<"BDTG Parameters X0"<<x0inner_<<", "<<x0middle_<<", "<<x0outer_<<endl;
1002  // cout<<"Et, Eta, Phi "<<PFPhoEt_<<", "<<PFPhoEta_<<", "<<PFPhoPhi_<<endl;
1003  // cout<<"PFPhoR9 "<<PFPhoR9_<<endl;
1004  // cout<<"R "<<RConv_<<endl;
1005 
1006  return BDTG;
1007 
1008 }
1009 
1010 float PFPhotonAlgo::EvaluateGCorrMVA(reco::PFCandidate photon, std::vector<CaloCluster>PFClusters){
1011  float BDTG=1;
1012  PFPhoEta_=photon.eta();
1013  PFPhoPhi_=photon.phi();
1014  PFPhoE_=photon.energy();
1015  //fill Material Map:
1016  int ix = X0_sum->GetXaxis()->FindBin(PFPhoEta_);
1017  int iy = X0_sum->GetYaxis()->FindBin(PFPhoPhi_);
1018  x0inner_= X0_inner->GetBinContent(ix,iy);
1019  x0middle_=X0_middle->GetBinContent(ix,iy);
1020  x0outer_=X0_outer->GetBinContent(ix,iy);
1021  SCPhiWidth_=photon.superClusterRef()->phiWidth();
1022  SCEtaWidth_=photon.superClusterRef()->etaWidth();
1023  Mustache Must;
1024  std::vector<unsigned int>insideMust;
1025  std::vector<unsigned int>outsideMust;
1026  std::multimap<float, unsigned int>OrderedClust;
1027  Must.FillMustacheVar(PFClusters);
1028  MustE_=Must.MustacheE();
1029  LowClusE_=Must.LowestMustClust();
1031  Must.MustacheClust(PFClusters,insideMust, outsideMust );
1032  for(unsigned int i=0; i<insideMust.size(); ++i){
1033  int index=insideMust[i];
1034  OrderedClust.insert(make_pair(PFClusters[index].energy(),index));
1035  }
1036  std::multimap<float, unsigned int>::iterator it;
1037  it=OrderedClust.begin();
1038  unsigned int lowEindex=(*it).second;
1039  std::multimap<float, unsigned int>::reverse_iterator rit;
1040  rit=OrderedClust.rbegin();
1041  unsigned int highEindex=(*rit).second;
1042  if(insideMust.size()>1){
1043  dEta_=fabs(PFClusters[highEindex].eta()-PFClusters[lowEindex].eta());
1044  dPhi_=asin(PFClusters[highEindex].phi()-PFClusters[lowEindex].phi());
1045  }
1046  else{
1047  dEta_=0;
1048  dPhi_=0;
1049  LowClusE_=0;
1050  }
1051  //calculate RMS for All clusters and up until the Next to Lowest inside the Mustache
1052  RMSAll_=ClustersPhiRMS(PFClusters, PFPhoPhi_);
1053  std::vector<reco::CaloCluster>PFMustClusters;
1054  if(insideMust.size()>2){
1055  for(unsigned int i=0; i<insideMust.size(); ++i){
1056  unsigned int index=insideMust[i];
1057  if(index==lowEindex)continue;
1058  PFMustClusters.push_back(PFClusters[index]);
1059  }
1060  }
1061  else{
1062  for(unsigned int i=0; i<insideMust.size(); ++i){
1063  unsigned int index=insideMust[i];
1064  PFMustClusters.push_back(PFClusters[index]);
1065  }
1066  }
1067  RMSMust_=ClustersPhiRMS(PFMustClusters, PFPhoPhi_);
1068  //then use cluster Width for just one PFCluster
1069  RConv_=310;
1070  PFCandidate::ElementsInBlocks eleInBlocks = photon.elementsInBlocks();
1071  for(unsigned i=0; i<eleInBlocks.size(); i++)
1072  {
1073  PFBlockRef blockRef = eleInBlocks[i].first;
1074  unsigned indexInBlock = eleInBlocks[i].second;
1075  const edm::OwnVector< reco::PFBlockElement >& elements=eleInBlocks[i].first->elements();
1076  const reco::PFBlockElement& element = elements[indexInBlock];
1077  if(element.type()==reco::PFBlockElement::TRACK){
1078  float R=sqrt(element.trackRef()->innerPosition().X()*element.trackRef()->innerPosition().X()+element.trackRef()->innerPosition().Y()*element.trackRef()->innerPosition().Y());
1079  if(RConv_>R)RConv_=R;
1080  }
1081  else continue;
1082  }
1083  //cout<<"Nvtx "<<nVtx_<<endl;
1084  if(fabs(PFPhoEta_)<1.4446){
1085  float GC_Var[17];
1086  GC_Var[0]=PFPhoEta_;
1087  GC_Var[1]=PFPhoECorr_;
1088  GC_Var[2]=PFPhoR9Corr_;
1089  GC_Var[3]=SCEtaWidth_;
1090  GC_Var[4]=SCPhiWidth_;
1091  GC_Var[5]=PFPhoPhi_;
1092  GC_Var[6]=x0inner_;
1093  GC_Var[7]=x0middle_;
1094  GC_Var[8]=x0outer_;
1095  GC_Var[9]=RConv_;
1096  GC_Var[10]=LowClusE_;
1097  GC_Var[11]=RMSMust_;
1098  GC_Var[12]=RMSAll_;
1099  GC_Var[13]=dEta_;
1100  GC_Var[14]=dPhi_;
1101  GC_Var[15]=nVtx_;
1102  GC_Var[16]=MustE_;
1103  BDTG=ReaderGCEB_->GetResponse(GC_Var);
1104  }
1105  else if(PFPhoR9_>0.94){
1106  float GC_Var[19];
1107  GC_Var[0]=PFPhoEta_;
1108  GC_Var[1]=PFPhoECorr_;
1109  GC_Var[2]=PFPhoR9Corr_;
1110  GC_Var[3]=SCEtaWidth_;
1111  GC_Var[4]=SCPhiWidth_;
1112  GC_Var[5]=PFPhoPhi_;
1113  GC_Var[6]=x0inner_;
1114  GC_Var[7]=x0middle_;
1115  GC_Var[8]=x0outer_;
1116  GC_Var[9]=RConv_;
1117  GC_Var[10]=LowClusE_;
1118  GC_Var[11]=RMSMust_;
1119  GC_Var[12]=RMSAll_;
1120  GC_Var[13]=dEta_;
1121  GC_Var[14]=dPhi_;
1122  GC_Var[15]=nVtx_;
1123  GC_Var[16]=TotPS1_;
1124  GC_Var[17]=TotPS2_;
1125  GC_Var[18]=MustE_;
1126  BDTG=ReaderGCEEhR9_->GetResponse(GC_Var);
1127  }
1128 
1129  else{
1130  float GC_Var[19];
1131  GC_Var[0]=PFPhoEta_;
1132  GC_Var[1]=PFPhoE_;
1133  GC_Var[2]=PFPhoR9Corr_;
1134  GC_Var[3]=SCEtaWidth_;
1135  GC_Var[4]=SCPhiWidth_;
1136  GC_Var[5]=PFPhoPhi_;
1137  GC_Var[6]=x0inner_;
1138  GC_Var[7]=x0middle_;
1139  GC_Var[8]=x0outer_;
1140  GC_Var[9]=RConv_;
1141  GC_Var[10]=LowClusE_;
1142  GC_Var[11]=RMSMust_;
1143  GC_Var[12]=RMSAll_;
1144  GC_Var[13]=dEta_;
1145  GC_Var[14]=dPhi_;
1146  GC_Var[15]=nVtx_;
1147  GC_Var[16]=TotPS1_;
1148  GC_Var[17]=TotPS2_;
1149  GC_Var[18]=MustE_;
1150  BDTG=ReaderGCEElR9_->GetResponse(GC_Var);
1151  }
1152  //cout<<"GC "<<BDTG<<endl;
1153 
1154  return BDTG;
1155 
1156 }
1157 
1158 double PFPhotonAlgo::ClustersPhiRMS(std::vector<reco::CaloCluster>PFClusters, float PFPhoPhi){
1159  double PFClustPhiRMS=0;
1160  double delPhi2=0;
1161  double delPhiSum=0;
1162  double ClusSum=0;
1163  for(unsigned int c=0; c<PFClusters.size(); ++c){
1164  delPhi2=(acos(cos(PFPhoPhi-PFClusters[c].phi()))* acos(cos(PFPhoPhi-PFClusters[c].phi())) )+delPhi2;
1165  delPhiSum=delPhiSum+ acos(cos(PFPhoPhi-PFClusters[c].phi()))*PFClusters[c].energy();
1166  ClusSum=ClusSum+PFClusters[c].energy();
1167  }
1168  double meandPhi=delPhiSum/ClusSum;
1169  PFClustPhiRMS=sqrt(fabs(delPhi2/ClusSum - (meandPhi*meandPhi)));
1170 
1171  return PFClustPhiRMS;
1172 }
1173 
1175  float BDTG=1;
1176  PFPhotonClusters ClusterVar(clusterRef);
1177  std::pair<double, double>ClusCoor=ClusterVar.GetCrysCoor();
1178  std::pair<int, int>ClusIndex=ClusterVar.GetCrysIndex();
1179  //Local Coordinates:
1180  if(clusterRef->layer()==PFLayer:: ECAL_BARREL ){//is Barrel
1181  PFCrysEtaCrack_=ClusterVar.EtaCrack();
1182  CrysEta_=ClusCoor.first;
1183  CrysPhi_=ClusCoor.second;
1184  CrysIEta_=ClusIndex.first;
1185  CrysIPhi_=ClusIndex.second;
1186  }
1187  else{
1188  CrysX_=ClusCoor.first;
1189  CrysY_=ClusCoor.second;
1190  }
1191  //Shower Shape Variables:
1192  eSeed_= ClusterVar.E5x5Element(0, 0)/clusterRef->energy();
1193  etop_=ClusterVar.E5x5Element(0,1)/clusterRef->energy();
1194  ebottom_=ClusterVar.E5x5Element(0,-1)/clusterRef->energy();
1195  eleft_=ClusterVar.E5x5Element(-1,0)/clusterRef->energy();
1196  eright_=ClusterVar.E5x5Element(1,0)/clusterRef->energy();
1197  e1x3_=(ClusterVar.E5x5Element(0,0)+ClusterVar.E5x5Element(0,1)+ClusterVar.E5x5Element(0,-1))/clusterRef->energy();
1198  e3x1_=(ClusterVar.E5x5Element(0,0)+ClusterVar.E5x5Element(-1,0)+ClusterVar.E5x5Element(1,0))/clusterRef->energy();
1199  e1x5_=ClusterVar.E5x5Element(0,0)+ClusterVar.E5x5Element(0,-2)+ClusterVar.E5x5Element(0,-1)+ClusterVar.E5x5Element(0,1)+ClusterVar.E5x5Element(0,2);
1200 
1201  e2x5Top_=(ClusterVar.E5x5Element(-2,2)+ClusterVar.E5x5Element(-1, 2)+ClusterVar.E5x5Element(0, 2)
1202  +ClusterVar.E5x5Element(1, 2)+ClusterVar.E5x5Element(2, 2)
1203  +ClusterVar.E5x5Element(-2,1)+ClusterVar.E5x5Element(-1,1)+ClusterVar.E5x5Element(0,1)
1204  +ClusterVar.E5x5Element(1,1)+ClusterVar.E5x5Element(2,1))/clusterRef->energy();
1205  e2x5Bottom_=(ClusterVar.E5x5Element(-2,-2)+ClusterVar.E5x5Element(-1,-2)+ClusterVar.E5x5Element(0,-2)
1206  +ClusterVar.E5x5Element(1,-2)+ClusterVar.E5x5Element(2,-2)
1207  +ClusterVar.E5x5Element(-2,1)+ClusterVar.E5x5Element(-1,1)
1208  +ClusterVar.E5x5Element(0,1)+ClusterVar.E5x5Element(1,1)+ClusterVar.E5x5Element(2,1))/clusterRef->energy();
1209  e2x5Left_= (ClusterVar.E5x5Element(-2,-2)+ClusterVar.E5x5Element(-2,-1)
1210  +ClusterVar.E5x5Element(-2,0)
1211  +ClusterVar.E5x5Element(-2,1)+ClusterVar.E5x5Element(-2,2)
1212  +ClusterVar.E5x5Element(-1,-2)+ClusterVar.E5x5Element(-1,-1)+ClusterVar.E5x5Element(-1,0)
1213  +ClusterVar.E5x5Element(-1,1)+ClusterVar.E5x5Element(-1,2))/clusterRef->energy();
1214 
1215  e2x5Right_ =(ClusterVar.E5x5Element(2,-2)+ClusterVar.E5x5Element(2,-1)
1216  +ClusterVar.E5x5Element(2,0)+ClusterVar.E5x5Element(2,1)+ClusterVar.E5x5Element(2,2)
1217  +ClusterVar.E5x5Element(1,-2)+ClusterVar.E5x5Element(1,-1)+ClusterVar.E5x5Element(1,0)
1218  +ClusterVar.E5x5Element(1,1)+ClusterVar.E5x5Element(1,2))/clusterRef->energy();
1219  float centerstrip=ClusterVar.E5x5Element(0,0)+ClusterVar.E5x5Element(0, -2)
1220  +ClusterVar.E5x5Element(0,-1)+ClusterVar.E5x5Element(0,1)+ClusterVar.E5x5Element(0,2);
1221  float rightstrip=ClusterVar.E5x5Element(1, 0)+ClusterVar.E5x5Element(1,1)
1222  +ClusterVar.E5x5Element(1,2)+ClusterVar.E5x5Element(1,-1)+ClusterVar.E5x5Element(1,-2);
1223  float leftstrip=ClusterVar.E5x5Element(-1,0)+ClusterVar.E5x5Element(-1,-1)+ClusterVar.E5x5Element(-1,2)
1224  +ClusterVar.E5x5Element(-1,1)+ClusterVar.E5x5Element(-1,2);
1225 
1226  if(rightstrip>leftstrip)e2x5Max_=rightstrip+centerstrip;
1227  else e2x5Max_=leftstrip+centerstrip;
1228  e2x5Max_=e2x5Max_/clusterRef->energy();
1229  //GetCrysCoordinates(clusterRef);
1230  //fill5x5Map(clusterRef);
1232  ClusPhi_=clusterRef->position().phi();
1233  ClusEta_=fabs(clusterRef->position().eta());
1234  EB=fabs(clusterRef->position().eta())/clusterRef->position().eta();
1235  logPFClusE_=log(clusterRef->energy());
1236  if(ClusEta_<1.4446){
1237  float LC_Var[26];
1238  LC_Var[0]=VtxZ_;
1239  LC_Var[1]=EB;
1240  LC_Var[2]=ClusEta_;
1241  LC_Var[3]=ClusPhi_;
1242  LC_Var[4]=logPFClusE_;
1243  LC_Var[5]=eSeed_;
1244  //top bottom left right
1245  LC_Var[6]=etop_;
1246  LC_Var[7]=ebottom_;
1247  LC_Var[8]=eleft_;
1248  LC_Var[9]=eright_;
1249  LC_Var[10]=ClusR9_;
1250  LC_Var[11]=e1x3_;
1251  LC_Var[12]=e3x1_;
1252  LC_Var[13]=Clus5x5ratio_;
1253  LC_Var[14]=e1x5_;
1254  LC_Var[15]=e2x5Max_;
1255  LC_Var[16]=e2x5Top_;
1256  LC_Var[17]=e2x5Bottom_;
1257  LC_Var[18]=e2x5Left_;
1258  LC_Var[19]=e2x5Right_;
1259  LC_Var[20]=CrysEta_;
1260  LC_Var[21]=CrysPhi_;
1261  float CrysIphiMod2=CrysIPhi_%2;
1262  float CrysIetaMod5=CrysIEta_%5;
1263  float CrysIphiMod20=CrysIPhi_%20;
1264  LC_Var[22]=CrysIphiMod2;
1265  LC_Var[23]=CrysIetaMod5;
1266  LC_Var[24]=CrysIphiMod20;
1267  LC_Var[25]=PFCrysEtaCrack_;
1268  BDTG=ReaderLCEB_->GetResponse(LC_Var);
1269  //cout<<"LC "<<BDTG<<endl;
1270  }
1271  else{
1272  float LC_Var[22];
1273  LC_Var[0]=VtxZ_;
1274  LC_Var[1]=EB;
1275  LC_Var[2]=ClusEta_;
1276  LC_Var[3]=ClusPhi_;
1277  LC_Var[4]=logPFClusE_;
1278  LC_Var[5]=eSeed_;
1279  //top bottom left right
1280  LC_Var[6]=etop_;
1281  LC_Var[7]=ebottom_;
1282  LC_Var[8]=eleft_;
1283  LC_Var[9]=eright_;
1284  LC_Var[10]=ClusR9_;
1285  LC_Var[11]=e1x3_;
1286  LC_Var[12]=e3x1_;
1287  LC_Var[13]=Clus5x5ratio_;
1288  LC_Var[14]=e1x5_;
1289  LC_Var[15]=e2x5Max_;
1290  LC_Var[16]=e2x5Top_;
1291  LC_Var[17]=e2x5Bottom_;
1292  LC_Var[18]=e2x5Left_;
1293  LC_Var[19]=e2x5Right_;
1294  LC_Var[20]=CrysX_;
1295  LC_Var[21]=CrysY_;
1296  BDTG=ReaderLCEE_->GetResponse(LC_Var);
1297  //cout<<"LC "<<BDTG<<endl;
1298  }
1299  return BDTG;
1300 
1301 }
1302 
1303 bool PFPhotonAlgo::EvaluateSingleLegMVA(const reco::PFBlockRef& blockref, const reco::Vertex& primaryvtx, unsigned int track_index)
1304 {
1305  bool convtkfound=false;
1306  const reco::PFBlock& block = *blockref;
1308  //use this to store linkdata in the associatedElements function below
1309  PFBlock::LinkData linkData = block.linkData();
1310  //calculate MVA Variables
1311  chi2=elements[track_index].trackRef()->chi2()/elements[track_index].trackRef()->ndof();
1312  nlost=elements[track_index].trackRef()->trackerExpectedHitsInner().numberOfLostHits();
1313  nlayers=elements[track_index].trackRef()->hitPattern().trackerLayersWithMeasurement();
1314  track_pt=elements[track_index].trackRef()->pt();
1315  STIP=elements[track_index].trackRefPF()->STIP();
1316 
1317  float linked_e=0;
1318  float linked_h=0;
1319  std::multimap<double, unsigned int> ecalAssoTrack;
1320  block.associatedElements( track_index,linkData,
1321  ecalAssoTrack,
1324  std::multimap<double, unsigned int> hcalAssoTrack;
1325  block.associatedElements( track_index,linkData,
1326  hcalAssoTrack,
1329  if(ecalAssoTrack.size() > 0) {
1330  for(std::multimap<double, unsigned int>::iterator itecal = ecalAssoTrack.begin();
1331  itecal != ecalAssoTrack.end(); ++itecal) {
1332  linked_e=linked_e+elements[itecal->second].clusterRef()->energy();
1333  }
1334  }
1335  if(hcalAssoTrack.size() > 0) {
1336  for(std::multimap<double, unsigned int>::iterator ithcal = hcalAssoTrack.begin();
1337  ithcal != hcalAssoTrack.end(); ++ithcal) {
1338  linked_h=linked_h+elements[ithcal->second].clusterRef()->energy();
1339  }
1340  }
1341  EoverPt=linked_e/elements[track_index].trackRef()->pt();
1342  HoverPt=linked_h/elements[track_index].trackRef()->pt();
1343  GlobalVector rvtx(elements[track_index].trackRef()->innerPosition().X()-primaryvtx.x(),
1344  elements[track_index].trackRef()->innerPosition().Y()-primaryvtx.y(),
1345  elements[track_index].trackRef()->innerPosition().Z()-primaryvtx.z());
1346  double vtx_phi=rvtx.phi();
1347  //delta Phi between conversion vertex and track
1348  del_phi=fabs(deltaPhi(vtx_phi, elements[track_index].trackRef()->innerMomentum().Phi()));
1349  mvaValue = tmvaReader_->EvaluateMVA("BDT");
1350  if(mvaValue > MVACUT)convtkfound=true;
1351  return convtkfound;
1352 }
1353 
1354 //Recover Early Conversions reconstructed as PFelectrons
1356  //std::auto_ptr< reco::PFCandidateCollection >
1357  //&pfElectronCandidates_,
1358  std::vector<reco::PFCandidate>&
1359  tempElectronCandidates,
1361  ){
1362  //step 1 check temp electrons for clusters that match Photon Supercluster:
1363  // permElectronCandidates->clear();
1364  int count=0;
1365  for ( std::vector<reco::PFCandidate>::const_iterator ec=tempElectronCandidates.begin(); ec != tempElectronCandidates.end(); ++ec )
1366  {
1367  // bool matched=false;
1368  int mh=ec->gsfTrackRef()->trackerExpectedHitsInner().numberOfLostHits();
1369  //if(mh==0)continue;//Case where missing hits greater than zero
1370 
1371  reco::GsfTrackRef gsf=ec->gsfTrackRef();
1372  //some hoopla to get Electron SC ref
1373 
1374  if(gsf->extra().isAvailable() && gsf->extra()->seedRef().isAvailable() && mh>0)
1375  {
1376  reco::ElectronSeedRef seedRef= gsf->extra()->seedRef().castTo<reco::ElectronSeedRef>();
1377  if(seedRef.isAvailable() && seedRef->isEcalDriven())
1378  {
1379  reco::SuperClusterRef ElecscRef = seedRef->caloCluster().castTo<reco::SuperClusterRef>();
1380 
1381  if(ElecscRef.isNonnull()){
1382  //finally see if it matches:
1383  reco::SuperClusterRef PhotscRef=sc->superClusterRef();
1384  if(PhotscRef==ElecscRef)
1385  {
1386  match_ind.push_back(count);
1387  // matched=true;
1388  //cout<<"Matched Electron with Index "<<count<<" This is the electron "<<*ec<<endl;
1389  //find that they have the same SC footprint start to collect Clusters and tracks and these will be passed to PFPhoton
1390  reco::PFCandidate::ElementsInBlocks eleInBlocks = ec->elementsInBlocks();
1391  for(unsigned i=0; i<eleInBlocks.size(); i++)
1392  {
1393  reco::PFBlockRef blockRef = eleInBlocks[i].first;
1394  unsigned indexInBlock = eleInBlocks[i].second;
1395  //const edm::OwnVector< reco::PFBlockElement >& elements=eleInBlocks[i].first->elements();
1396  //const reco::PFBlockElement& element = elements[indexInBlock];
1397 
1398  AddFromElectron_.push_back(indexInBlock);
1399  }
1400  }
1401  }
1402  }
1403  }
1404  count++;
1405  }
1406 }
float Clus5x5ratio_
Definition: PFPhotonAlgo.h:171
double GetResponse(const float *vector) const
Definition: GBRForest.h:51
type
Definition: HCALResponse.h:22
void setPs2Energy(float e2)
set corrected PS2 energy
Definition: PFCandidate.h:242
Abstract base class for a PFBlock element (track, cluster...)
tuple convTracks
Definition: convBrem_cff.py:35
int i
Definition: DBlmapReader.cc:9
void setPs1Energy(float e1)
set corrected PS1 energy
Definition: PFCandidate.h:236
const GBRForest * ReaderLCEE_
Definition: PFPhotonAlgo.h:152
void setFlag(Flags theFlag, bool value)
set a given flag
Definition: PFCandidate.cc:195
void set_mva_nothing_gamma(float mva)
set mva for gamma detection
Definition: PFCandidate.h:291
double y() const
y coordinate
Definition: Vertex.h:97
float logPFClusE_
Definition: PFPhotonAlgo.h:171
float SCEtaWidth_
Definition: PFPhotonAlgo.h:181
Type type() const
int OutsideMust()
Definition: Mustache.h:24
std::map< unsigned int, Link > LinkData
Definition: PFBlock.h:46
size_type size() const
Definition: OwnVector.h:247
Geom::Phi< T > phi() const
Definition: PV3DBase.h:68
#define X(str)
Definition: MuonsGrabber.cc:49
verbosityLevel verbosityLevel_
Definition: PFPhotonAlgo.h:137
virtual void setP4(const LorentzVector &p4)
set 4-momentum
list elements
Definition: asciidump.py:414
const edm::OwnVector< reco::PFBlockElement > & elements() const
Definition: PFBlock.h:107
const GBRForest * ReaderRes_
Definition: PFPhotonAlgo.h:149
const LinkData & linkData() const
Definition: PFBlock.h:112
std::vector< unsigned int > AddFromElectron_
Definition: PFPhotonAlgo.h:194
const GBRForest * ReaderGCEEhR9_
Definition: PFPhotonAlgo.h:154
bool isAvailable() const
Definition: Ref.h:276
T eta() const
float EvaluateGCorrMVA(reco::PFCandidate, std::vector< reco::CaloCluster >PFClusters)
double E5x5Element(int i, int j)
float e2x5Right_
Definition: PFPhotonAlgo.h:177
float LowestMustClust()
Definition: Mustache.h:22
reco::Vertex primaryVertex_
Definition: PFPhotonAlgo.h:145
std::pair< double, double > GetCrysCoor()
virtual double eta() const
momentum pseudorapidity
std::vector< ElementInBlock > ElementsInBlocks
Definition: PFCandidate.h:337
const ElementsInBlocks & elementsInBlocks() const
Definition: PFCandidate.h:342
std::vector< PFCandidatePtr > pfCandidates(const PFJet &jet, int particleId, bool sort=true)
iterator begin()
Definition: OwnVector.h:227
void RunPFPhoton(const reco::PFBlockRef &blockRef, std::vector< bool > &active, std::auto_ptr< reco::PFCandidateCollection > &pfPhotonCandidates, std::vector< reco::PFCandidatePhotonExtra > &pfPhotonExtraCandidates, std::vector< reco::PFCandidate > &tempElectronCandidates)
Definition: PFPhotonAlgo.cc:87
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:30
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:250
double mvaValue
Definition: PFPhotonAlgo.h:166
void push_back(D *&d)
Definition: OwnVector.h:273
virtual double energy() const
energy
float MustacheEtOut()
Definition: Mustache.h:21
void MustacheClust(std::vector< CaloCluster >clusters, std::vector< unsigned int > &insideMust, std::vector< unsigned int > &outsideMust)
Definition: Mustache.cc:124
std::pair< double, double > GetCrysIndex()
TMVA::Reader * tmvaReader_
Definition: PFPhotonAlgo.h:146
void addElementInBlock(const reco::PFBlockRef &blockref, unsigned elementIndex)
add an element to the current PFCandidate
Definition: PFCandidate.cc:123
T sqrt(T t)
Definition: SSEVec.h:46
virtual reco::TrackRef trackRef() const
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
TH2D * X0_outer
Definition: PFPhotonAlgo.h:189
double z() const
y coordinate
Definition: Vertex.h:99
float EvaluateLCorrMVA(reco::PFClusterRef clusterRef)
const GBRForest * ReaderLCEB_
Definition: PFPhotonAlgo.h:151
TH2D * X0_inner
Definition: PFPhotonAlgo.h:187
block
Formating index page&#39;s pieces.
Definition: Association.py:232
float PFPhoECorr_
Definition: PFPhotonAlgo.h:181
TH2D * X0_middle
Definition: PFPhotonAlgo.h:188
void addDaughter(const Candidate &, const std::string &s="")
add a clone of the passed candidate as daughter
float e2x5Bottom_
Definition: PFPhotonAlgo.h:177
double sumPtTrackIsoSlopeForPhoton_
Definition: PFPhotonAlgo.h:159
PFPhotonAlgo(std::string mvaweightfile, double mvaConvCut, bool useReg, std::string X0_Map, const reco::Vertex &primary, const boost::shared_ptr< PFEnergyCalibration > &thePFEnergyCalibration, double sumPtTrackIsoForPhoton, double sumPtTrackIsoSlopeForPhoton)
Definition: PFPhotonAlgo.cc:30
void setEcalEnergy(float eeRaw, float eeCorr)
set corrected Ecal energy
Definition: PFCandidate.h:185
float SCPhiWidth_
Definition: PFPhotonAlgo.h:181
double ClustersPhiRMS(std::vector< reco::CaloCluster >PFClusters, float PFPhoPhi)
boost::shared_ptr< PFEnergyCalibration > thePFEnergyCalibration_
Definition: PFPhotonAlgo.h:157
const GBRForest * ReaderGCEB_
Definition: PFPhotonAlgo.h:153
void EarlyConversion(std::vector< reco::PFCandidate > &tempElectronCandidates, const reco::PFBlockElementSuperCluster *sc)
double x() const
x coordinate
Definition: Vertex.h:95
iterator end()
Definition: OwnVector.h:232
virtual bool trackType(TrackType trType) const
float PFCrysEtaCrack_
Definition: PFPhotonAlgo.h:171
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:31
void associatedElements(unsigned i, const LinkData &linkData, std::multimap< double, unsigned > &sortedAssociates, reco::PFBlockElement::Type type=PFBlockElement::NONE, LinkTest test=LINKTEST_RECHIT) const
Definition: PFBlock.cc:75
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:13
virtual void setVertex(math::XYZPoint p)
Definition: PFCandidate.h:370
float EvaluateResMVA(reco::PFCandidate, std::vector< reco::CaloCluster >PFClusters)
bool EvaluateSingleLegMVA(const reco::PFBlockRef &blockref, const reco::Vertex &primaryvtx, unsigned int track_index)
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:33
void push_back(value_type const &ref)
Add a Ref&lt;C, T&gt; to the RefVector.
Definition: RefVector.h:64
size_type size() const
Size of the RefVector.
Definition: RefVector.h:89
void setSuperClusterRef(const reco::SuperClusterRef &scRef)
Definition: PFCandidate.cc:522
const GBRForest * ReaderGCEElR9_
Definition: PFPhotonAlgo.h:155
void FillMustacheVar(std::vector< CaloCluster >clusters)
Definition: Mustache.cc:218
double sumPtTrackIsoForPhoton_
Definition: PFPhotonAlgo.h:158
std::vector< int > match_ind
Definition: PFPhotonAlgo.h:160
float MustacheE()
Definition: Mustache.h:19
virtual double phi() const
momentum azimuthal angle
mathSSE::Vec4< T > v
void setHcalEnergy(float ehRaw, float ehCorr)
set corrected Hcal energy
Definition: PFCandidate.h:195
reco::SuperClusterRef superClusterRef() const
return a reference to the corresponding SuperCluster if any
Definition: PFCandidate.cc:502
Definition: DDAxes.h:10
Block of elements.
Definition: PFBlock.h:30
float PFPhoR9Corr_
Definition: PFPhotonAlgo.h:181