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 
31  double mvaConvCut,
32  bool useReg,
34  const reco::Vertex& primary,
35  const boost::shared_ptr<PFEnergyCalibration>& thePFEnergyCalibration,
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 
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
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  math::XYZVector photonPositionwrtVtx(
767  photonX_- primaryVertex_->x(),
768  photonY_-primaryVertex_->y(),
769  photonZ_-primaryVertex_->z()
770  );
771  math::XYZVector photonDirection=photonPositionwrtVtx.Unit();
772 
773  math::XYZTLorentzVector photonMomentum(photonEnergy_* photonDirection.X(),
774  photonEnergy_* photonDirection.Y(),
775  photonEnergy_* photonDirection.Z(),
776  photonEnergy_ );
777 
778  if(sum_track_pt>(sumPtTrackIsoForPhoton_ + sumPtTrackIsoSlopeForPhoton_ * photonMomentum.pt()) && AddFromElectron_.size()==0)
779  {
780  elemsToLock.resize(0);
781  continue;
782 
783  }
784 
785  //THIS SC is not a Photon it fails track Isolation
786  //if(sum_track_pt>(2+ 0.001* photonMomentum.pt()))
787  //continue;//THIS SC is not a Photon it fails track Isolation
788 
789  /*
790  std::cout<<" Created Photon with energy = "<<photonEnergy_<<std::endl;
791  std::cout<<" pT = "<<photonMomentum.pt()<<std::endl;
792  std::cout<<" RawEne = "<<RawEcalEne<<std::endl;
793  std::cout<<" E = "<<photonMomentum.e()<<std::endl;
794  std::cout<<" eta = "<<photonMomentum.eta()<<std::endl;
795  std::cout<<" TrackIsolation = "<< sum_track_pt <<std::endl;
796  */
797 
798  reco::PFCandidate photonCand(0,photonMomentum, reco::PFCandidate::gamma);
799  photonCand.setPs1Energy(ps1TotEne);
800  photonCand.setPs2Energy(ps2TotEne);
801  photonCand.setEcalEnergy(RawEcalEne,photonEnergy_);
802  photonCand.setHcalEnergy(0.,0.);
803  photonCand.set_mva_nothing_gamma(1.);
804  photonCand.setSuperClusterRef(sc->superClusterRef());
806  photonCand.setVertex( v );
807  if(hasConvTrack || hasSingleleg)photonCand.setFlag( reco::PFCandidate::GAMMA_TO_GAMMACONV, true);
808  int matches=match_ind.size();
809  int count=0;
810  for ( std::vector<reco::PFCandidate>::const_iterator ec=tempElectronCandidates.begin(); ec != tempElectronCandidates.end(); ++ec ){
811  for(int i=0; i<matches; i++)
812  {
813  if(count==match_ind[i])photonCand.addDaughter(*ec);
814  count++;
815  }
816  }
817  // set isvalid_ to TRUE since we've found at least one photon candidate
818  isvalid_ = true;
819  // push back the candidate into the collection ...
820  //Add Elements from Electron
821  for(std::vector<unsigned int>::const_iterator it =
822  AddFromElectron_.begin();
823  it != AddFromElectron_.end(); ++it)photonCand.addElementInBlock(blockRef,*it);
824 
825  // ... and lock all elemts used
826  for(std::vector<unsigned int>::const_iterator it = elemsToLock.begin();
827  it != elemsToLock.end(); ++it)
828  {
829  if(active[*it])
830  {
831  photonCand.addElementInBlock(blockRef,*it);
832  if( elements[*it].type() == reco::PFBlockElement::TRACK )
833  {
834  for( const auto& convref : elements[*it].convRefs() ) {
835  if(convref.isNonnull())
836  {
837  //make sure it is not stored already as the partner track
838  bool matched=false;
839  for(unsigned int ic = 0; ic < ConversionsRef_.size(); ic++)
840  {
841  if(ConversionsRef_[ic]==convref)matched=true;
842  }
843  if(!matched)ConversionsRef_.push_back(convref);
844  }
845  }
846  }
847  }
848  active[*it] = false;
849  }
850  PFPhoECorr_=0;
851  // here add the extra information
853  //Store Locally Contained PF Cluster regressed energy
854  for(unsigned int l=0; l<MVALCorr.size(); ++l)
855  {
856  myExtra.addLCorrClusEnergy(MVALCorr[l]);
857  PFPhoECorr_=PFPhoECorr_+MVALCorr[l];//total Locally corrected energy
858  }
859  TotPS1_=ps1TotEne;
860  TotPS2_=ps2TotEne;
861  //Do Global Corrections here:
862  float GCorr=EvaluateGCorrMVA(photonCand, PFClusters);
863  if(useReg_){
864  math::XYZTLorentzVector photonCorrMomentum(GCorr*PFPhoECorr_* photonDirection.X(),
865  GCorr*PFPhoECorr_* photonDirection.Y(),
866  GCorr*PFPhoECorr_* photonDirection.Z(),
867  GCorr * photonEnergy_ );
868  photonCand.setP4(photonCorrMomentum);
869  }
870 
871  std::multimap<float, unsigned int>OrderedClust;
872  for(unsigned int i=0; i<PFClusters.size(); ++i){
873  float et=PFClusters[i].energy()*sin(PFClusters[i].position().theta());
874  OrderedClust.insert(make_pair(et, i));
875  }
876  std::multimap<float, unsigned int>::reverse_iterator rit;
877  rit=OrderedClust.rbegin();
878  unsigned int highEindex=(*rit).second;
879  //store Position at ECAL Entrance as Position of Max Et PFCluster
880  photonCand.setPositionAtECALEntrance(math::XYZPointF(PFClusters[highEindex].position()));
881 
882  //Mustache ID variables
883  Mustache Must;
884  Must.FillMustacheVar(PFClusters);
885  int excluded= Must.OutsideMust();
886  float MustacheEt=Must.MustacheEtOut();
887  myExtra.setMustache_Et(MustacheEt);
888  myExtra.setExcludedClust(excluded);
889  if(fabs(photonCand.eta()<1.4446))
890  myExtra.setMVAGlobalCorrE(GCorr * PFPhoECorr_);
891  else if(PFPhoR9_>0.94)
892  myExtra.setMVAGlobalCorrE(GCorr * PFPhoECorr_);
893  else myExtra.setMVAGlobalCorrE(GCorr * photonEnergy_);
894  float Res=EvaluateResMVA(photonCand, PFClusters);
895  myExtra.SetPFPhotonRes(Res);
896 
897  // Daniele example for mvaValues
898  // do the same for single leg trackRef and convRef
899  for(unsigned int ic = 0; ic < MVA_values.size(); ic++)
900  {
901  myExtra.addSingleLegConvMva(MVA_values[ic]);
902  myExtra.addSingleLegConvTrackRef(singleLegRef[ic]);
903  //cout<<"Single Leg Tracks "<<singleLegRef[ic]->pt()<<" MVA "<<MVA_values[ic]<<endl;
904  }
905  for(unsigned int ic = 0; ic < ConversionsRef_.size(); ic++)
906  {
907  myExtra.addConversionRef(ConversionsRef_[ic]);
908  //cout<<"Conversion Pairs "<<ConversionsRef_[ic]->pairMomentum()<<endl;
909  }
910  pfPhotonExtraCandidates.push_back(myExtra);
911  pfCandidates->push_back(photonCand);
912  // ... and reset the vector
913  elemsToLock.resize(0);
914  hasConvTrack=false;
915  hasSingleleg=false;
916  } // end of loops over all elements in block
917 
918  return;
919 }
920 
921 float PFPhotonAlgo::EvaluateResMVA(const reco::PFCandidate& photon, const std::vector<reco::CaloCluster>& _PFClusters){
922  std::vector<reco::CaloCluster> PFClusters = _PFClusters;
923  float BDTG=1;
924  PFPhoEta_=photon.eta();
925  PFPhoPhi_=photon.phi();
926  PFPhoE_=photon.energy();
927  //fill Material Map:
928  int ix = X0_sum->GetXaxis()->FindBin(PFPhoEta_);
929  int iy = X0_sum->GetYaxis()->FindBin(PFPhoPhi_);
930  x0inner_= X0_inner->GetBinContent(ix,iy);
931  x0middle_=X0_middle->GetBinContent(ix,iy);
932  x0outer_=X0_outer->GetBinContent(ix,iy);
933  SCPhiWidth_=photon.superClusterRef()->phiWidth();
934  SCEtaWidth_=photon.superClusterRef()->etaWidth();
935  Mustache Must;
936  std::vector<unsigned int>insideMust;
937  std::vector<unsigned int>outsideMust;
938  std::multimap<float, unsigned int>OrderedClust;
939  Must.FillMustacheVar(PFClusters);
940  MustE_=Must.MustacheE();
941  LowClusE_=Must.LowestMustClust();
943  Must.MustacheClust(PFClusters,insideMust, outsideMust );
944  for(unsigned int i=0; i<insideMust.size(); ++i){
945  int index=insideMust[i];
946  OrderedClust.insert(make_pair(PFClusters[index].energy(),index));
947  }
948  std::multimap<float, unsigned int>::iterator it;
949  it=OrderedClust.begin();
950  unsigned int lowEindex=(*it).second;
951  std::multimap<float, unsigned int>::reverse_iterator rit;
952  rit=OrderedClust.rbegin();
953  unsigned int highEindex=(*rit).second;
954  if(insideMust.size()>1){
955  dEta_=fabs(PFClusters[highEindex].eta()-PFClusters[lowEindex].eta());
956  dPhi_=asin(PFClusters[highEindex].phi()-PFClusters[lowEindex].phi());
957  }
958  else{
959  dEta_=0;
960  dPhi_=0;
961  LowClusE_=0;
962  }
963  //calculate RMS for All clusters and up until the Next to Lowest inside the Mustache
964  RMSAll_=ClustersPhiRMS(PFClusters, PFPhoPhi_);
965  std::vector<reco::CaloCluster>PFMustClusters;
966  if(insideMust.size()>2){
967  for(unsigned int i=0; i<insideMust.size(); ++i){
968  unsigned int index=insideMust[i];
969  if(index==lowEindex)continue;
970  PFMustClusters.push_back(PFClusters[index]);
971  }
972  }
973  else{
974  for(unsigned int i=0; i<insideMust.size(); ++i){
975  unsigned int index=insideMust[i];
976  PFMustClusters.push_back(PFClusters[index]);
977  }
978  }
979  RMSMust_=ClustersPhiRMS(PFMustClusters, PFPhoPhi_);
980  //then use cluster Width for just one PFCluster
981  RConv_=310;
982  PFCandidate::ElementsInBlocks eleInBlocks = photon.elementsInBlocks();
983  for(unsigned i=0; i<eleInBlocks.size(); i++)
984  {
985  PFBlockRef blockRef = eleInBlocks[i].first;
986  unsigned indexInBlock = eleInBlocks[i].second;
987  const edm::OwnVector< reco::PFBlockElement >& elements=eleInBlocks[i].first->elements();
988  const reco::PFBlockElement& element = elements[indexInBlock];
989  if(element.type()==reco::PFBlockElement::TRACK){
990  float R=sqrt(element.trackRef()->innerPosition().X()*element.trackRef()->innerPosition().X()+element.trackRef()->innerPosition().Y()*element.trackRef()->innerPosition().Y());
991  if(RConv_>R)RConv_=R;
992  }
993  else continue;
994  }
995  float GC_Var[17];
996  GC_Var[0]=PFPhoEta_;
997  GC_Var[1]=PFPhoEt_;
998  GC_Var[2]=PFPhoR9Corr_;
999  GC_Var[3]=PFPhoPhi_;
1000  GC_Var[4]=SCEtaWidth_;
1001  GC_Var[5]=SCPhiWidth_;
1002  GC_Var[6]=x0inner_;
1003  GC_Var[7]=x0middle_;
1004  GC_Var[8]=x0outer_;
1005  GC_Var[9]=RConv_;
1006  GC_Var[10]=LowClusE_;
1007  GC_Var[11]=RMSMust_;
1008  GC_Var[12]=RMSAll_;
1009  GC_Var[13]=dEta_;
1010  GC_Var[14]=dPhi_;
1011  GC_Var[15]=nVtx_;
1012  GC_Var[16]=MustE_;
1013 
1014  BDTG=ReaderRes_->GetResponse(GC_Var);
1015  // cout<<"Res "<<BDTG<<endl;
1016 
1017  // cout<<"BDTG Parameters X0"<<x0inner_<<", "<<x0middle_<<", "<<x0outer_<<endl;
1018  // cout<<"Et, Eta, Phi "<<PFPhoEt_<<", "<<PFPhoEta_<<", "<<PFPhoPhi_<<endl;
1019  // cout<<"PFPhoR9 "<<PFPhoR9_<<endl;
1020  // cout<<"R "<<RConv_<<endl;
1021 
1022  return BDTG;
1023 
1024 }
1025 
1026 float PFPhotonAlgo::EvaluateGCorrMVA(const reco::PFCandidate& photon, const std::vector<CaloCluster>& _PFClusters){
1027  std::vector<CaloCluster> PFClusters = _PFClusters;
1028  float BDTG=1;
1029  PFPhoEta_=photon.eta();
1030  PFPhoPhi_=photon.phi();
1031  PFPhoE_=photon.energy();
1032  //fill Material Map:
1033  int ix = X0_sum->GetXaxis()->FindBin(PFPhoEta_);
1034  int iy = X0_sum->GetYaxis()->FindBin(PFPhoPhi_);
1035  x0inner_= X0_inner->GetBinContent(ix,iy);
1036  x0middle_=X0_middle->GetBinContent(ix,iy);
1037  x0outer_=X0_outer->GetBinContent(ix,iy);
1038  SCPhiWidth_=photon.superClusterRef()->phiWidth();
1039  SCEtaWidth_=photon.superClusterRef()->etaWidth();
1040  Mustache Must;
1041  std::vector<unsigned int>insideMust;
1042  std::vector<unsigned int>outsideMust;
1043  std::multimap<float, unsigned int>OrderedClust;
1044  Must.FillMustacheVar(PFClusters);
1045  MustE_=Must.MustacheE();
1046  LowClusE_=Must.LowestMustClust();
1048  Must.MustacheClust(PFClusters,insideMust, outsideMust );
1049  for(unsigned int i=0; i<insideMust.size(); ++i){
1050  int index=insideMust[i];
1051  OrderedClust.insert(make_pair(PFClusters[index].energy(),index));
1052  }
1053  std::multimap<float, unsigned int>::iterator it;
1054  it=OrderedClust.begin();
1055  unsigned int lowEindex=(*it).second;
1056  std::multimap<float, unsigned int>::reverse_iterator rit;
1057  rit=OrderedClust.rbegin();
1058  unsigned int highEindex=(*rit).second;
1059  if(insideMust.size()>1){
1060  dEta_=fabs(PFClusters[highEindex].eta()-PFClusters[lowEindex].eta());
1061  dPhi_=asin(PFClusters[highEindex].phi()-PFClusters[lowEindex].phi());
1062  }
1063  else{
1064  dEta_=0;
1065  dPhi_=0;
1066  LowClusE_=0;
1067  }
1068  //calculate RMS for All clusters and up until the Next to Lowest inside the Mustache
1069  RMSAll_=ClustersPhiRMS(PFClusters, PFPhoPhi_);
1070  std::vector<reco::CaloCluster>PFMustClusters;
1071  if(insideMust.size()>2){
1072  for(unsigned int i=0; i<insideMust.size(); ++i){
1073  unsigned int index=insideMust[i];
1074  if(index==lowEindex)continue;
1075  PFMustClusters.push_back(PFClusters[index]);
1076  }
1077  }
1078  else{
1079  for(unsigned int i=0; i<insideMust.size(); ++i){
1080  unsigned int index=insideMust[i];
1081  PFMustClusters.push_back(PFClusters[index]);
1082  }
1083  }
1084  RMSMust_=ClustersPhiRMS(PFMustClusters, PFPhoPhi_);
1085  //then use cluster Width for just one PFCluster
1086  RConv_=310;
1087  PFCandidate::ElementsInBlocks eleInBlocks = photon.elementsInBlocks();
1088  for(unsigned i=0; i<eleInBlocks.size(); i++)
1089  {
1090  PFBlockRef blockRef = eleInBlocks[i].first;
1091  unsigned indexInBlock = eleInBlocks[i].second;
1092  const edm::OwnVector< reco::PFBlockElement >& elements=eleInBlocks[i].first->elements();
1093  const reco::PFBlockElement& element = elements[indexInBlock];
1094  if(element.type()==reco::PFBlockElement::TRACK){
1095  float R=sqrt(element.trackRef()->innerPosition().X()*element.trackRef()->innerPosition().X()+element.trackRef()->innerPosition().Y()*element.trackRef()->innerPosition().Y());
1096  if(RConv_>R)RConv_=R;
1097  }
1098  else continue;
1099  }
1100  //cout<<"Nvtx "<<nVtx_<<endl;
1101  if(fabs(PFPhoEta_)<1.4446){
1102  float GC_Var[17];
1103  GC_Var[0]=PFPhoEta_;
1104  GC_Var[1]=PFPhoECorr_;
1105  GC_Var[2]=PFPhoR9Corr_;
1106  GC_Var[3]=SCEtaWidth_;
1107  GC_Var[4]=SCPhiWidth_;
1108  GC_Var[5]=PFPhoPhi_;
1109  GC_Var[6]=x0inner_;
1110  GC_Var[7]=x0middle_;
1111  GC_Var[8]=x0outer_;
1112  GC_Var[9]=RConv_;
1113  GC_Var[10]=LowClusE_;
1114  GC_Var[11]=RMSMust_;
1115  GC_Var[12]=RMSAll_;
1116  GC_Var[13]=dEta_;
1117  GC_Var[14]=dPhi_;
1118  GC_Var[15]=nVtx_;
1119  GC_Var[16]=MustE_;
1120  BDTG=ReaderGCEB_->GetResponse(GC_Var);
1121  }
1122  else if(PFPhoR9_>0.94){
1123  float GC_Var[19];
1124  GC_Var[0]=PFPhoEta_;
1125  GC_Var[1]=PFPhoECorr_;
1126  GC_Var[2]=PFPhoR9Corr_;
1127  GC_Var[3]=SCEtaWidth_;
1128  GC_Var[4]=SCPhiWidth_;
1129  GC_Var[5]=PFPhoPhi_;
1130  GC_Var[6]=x0inner_;
1131  GC_Var[7]=x0middle_;
1132  GC_Var[8]=x0outer_;
1133  GC_Var[9]=RConv_;
1134  GC_Var[10]=LowClusE_;
1135  GC_Var[11]=RMSMust_;
1136  GC_Var[12]=RMSAll_;
1137  GC_Var[13]=dEta_;
1138  GC_Var[14]=dPhi_;
1139  GC_Var[15]=nVtx_;
1140  GC_Var[16]=TotPS1_;
1141  GC_Var[17]=TotPS2_;
1142  GC_Var[18]=MustE_;
1143  BDTG=ReaderGCEEhR9_->GetResponse(GC_Var);
1144  }
1145 
1146  else{
1147  float GC_Var[19];
1148  GC_Var[0]=PFPhoEta_;
1149  GC_Var[1]=PFPhoE_;
1150  GC_Var[2]=PFPhoR9Corr_;
1151  GC_Var[3]=SCEtaWidth_;
1152  GC_Var[4]=SCPhiWidth_;
1153  GC_Var[5]=PFPhoPhi_;
1154  GC_Var[6]=x0inner_;
1155  GC_Var[7]=x0middle_;
1156  GC_Var[8]=x0outer_;
1157  GC_Var[9]=RConv_;
1158  GC_Var[10]=LowClusE_;
1159  GC_Var[11]=RMSMust_;
1160  GC_Var[12]=RMSAll_;
1161  GC_Var[13]=dEta_;
1162  GC_Var[14]=dPhi_;
1163  GC_Var[15]=nVtx_;
1164  GC_Var[16]=TotPS1_;
1165  GC_Var[17]=TotPS2_;
1166  GC_Var[18]=MustE_;
1167  BDTG=ReaderGCEElR9_->GetResponse(GC_Var);
1168  }
1169  //cout<<"GC "<<BDTG<<endl;
1170 
1171  return BDTG;
1172 
1173 }
1174 
1175 double PFPhotonAlgo::ClustersPhiRMS(const std::vector<reco::CaloCluster>& PFClusters, float PFPhoPhi){
1176  double PFClustPhiRMS=0;
1177  double delPhi2=0;
1178  double delPhiSum=0;
1179  double ClusSum=0;
1180  for(unsigned int c=0; c<PFClusters.size(); ++c){
1181  delPhi2=(acos(cos(PFPhoPhi-PFClusters[c].phi()))* acos(cos(PFPhoPhi-PFClusters[c].phi())) )+delPhi2;
1182  delPhiSum=delPhiSum+ acos(cos(PFPhoPhi-PFClusters[c].phi()))*PFClusters[c].energy();
1183  ClusSum=ClusSum+PFClusters[c].energy();
1184  }
1185  double meandPhi=delPhiSum/ClusSum;
1186  PFClustPhiRMS=sqrt(fabs(delPhi2/ClusSum - (meandPhi*meandPhi)));
1187 
1188  return PFClustPhiRMS;
1189 }
1190 
1192  float BDTG=1;
1193  PFPhotonClusters ClusterVar(clusterRef);
1194  std::pair<double, double>ClusCoor=ClusterVar.GetCrysCoor();
1195  std::pair<int, int>ClusIndex=ClusterVar.GetCrysIndex();
1196  //Local Coordinates:
1197  if(clusterRef->layer()==PFLayer:: ECAL_BARREL ){//is Barrel
1198  PFCrysEtaCrack_=ClusterVar.EtaCrack();
1199  CrysEta_=ClusCoor.first;
1200  CrysPhi_=ClusCoor.second;
1201  CrysIEta_=ClusIndex.first;
1202  CrysIPhi_=ClusIndex.second;
1203  }
1204  else{
1205  CrysX_=ClusCoor.first;
1206  CrysY_=ClusCoor.second;
1207  }
1208  //Shower Shape Variables:
1209  eSeed_= ClusterVar.E5x5Element(0, 0)/clusterRef->energy();
1210  etop_=ClusterVar.E5x5Element(0,1)/clusterRef->energy();
1211  ebottom_=ClusterVar.E5x5Element(0,-1)/clusterRef->energy();
1212  eleft_=ClusterVar.E5x5Element(-1,0)/clusterRef->energy();
1213  eright_=ClusterVar.E5x5Element(1,0)/clusterRef->energy();
1214  e1x3_=(ClusterVar.E5x5Element(0,0)+ClusterVar.E5x5Element(0,1)+ClusterVar.E5x5Element(0,-1))/clusterRef->energy();
1215  e3x1_=(ClusterVar.E5x5Element(0,0)+ClusterVar.E5x5Element(-1,0)+ClusterVar.E5x5Element(1,0))/clusterRef->energy();
1216  e1x5_=ClusterVar.E5x5Element(0,0)+ClusterVar.E5x5Element(0,-2)+ClusterVar.E5x5Element(0,-1)+ClusterVar.E5x5Element(0,1)+ClusterVar.E5x5Element(0,2);
1217 
1218  e2x5Top_=(ClusterVar.E5x5Element(-2,2)+ClusterVar.E5x5Element(-1, 2)+ClusterVar.E5x5Element(0, 2)
1219  +ClusterVar.E5x5Element(1, 2)+ClusterVar.E5x5Element(2, 2)
1220  +ClusterVar.E5x5Element(-2,1)+ClusterVar.E5x5Element(-1,1)+ClusterVar.E5x5Element(0,1)
1221  +ClusterVar.E5x5Element(1,1)+ClusterVar.E5x5Element(2,1))/clusterRef->energy();
1222  e2x5Bottom_=(ClusterVar.E5x5Element(-2,-2)+ClusterVar.E5x5Element(-1,-2)+ClusterVar.E5x5Element(0,-2)
1223  +ClusterVar.E5x5Element(1,-2)+ClusterVar.E5x5Element(2,-2)
1224  +ClusterVar.E5x5Element(-2,1)+ClusterVar.E5x5Element(-1,1)
1225  +ClusterVar.E5x5Element(0,1)+ClusterVar.E5x5Element(1,1)+ClusterVar.E5x5Element(2,1))/clusterRef->energy();
1226  e2x5Left_= (ClusterVar.E5x5Element(-2,-2)+ClusterVar.E5x5Element(-2,-1)
1227  +ClusterVar.E5x5Element(-2,0)
1228  +ClusterVar.E5x5Element(-2,1)+ClusterVar.E5x5Element(-2,2)
1229  +ClusterVar.E5x5Element(-1,-2)+ClusterVar.E5x5Element(-1,-1)+ClusterVar.E5x5Element(-1,0)
1230  +ClusterVar.E5x5Element(-1,1)+ClusterVar.E5x5Element(-1,2))/clusterRef->energy();
1231 
1232  e2x5Right_ =(ClusterVar.E5x5Element(2,-2)+ClusterVar.E5x5Element(2,-1)
1233  +ClusterVar.E5x5Element(2,0)+ClusterVar.E5x5Element(2,1)+ClusterVar.E5x5Element(2,2)
1234  +ClusterVar.E5x5Element(1,-2)+ClusterVar.E5x5Element(1,-1)+ClusterVar.E5x5Element(1,0)
1235  +ClusterVar.E5x5Element(1,1)+ClusterVar.E5x5Element(1,2))/clusterRef->energy();
1236  float centerstrip=ClusterVar.E5x5Element(0,0)+ClusterVar.E5x5Element(0, -2)
1237  +ClusterVar.E5x5Element(0,-1)+ClusterVar.E5x5Element(0,1)+ClusterVar.E5x5Element(0,2);
1238  float rightstrip=ClusterVar.E5x5Element(1, 0)+ClusterVar.E5x5Element(1,1)
1239  +ClusterVar.E5x5Element(1,2)+ClusterVar.E5x5Element(1,-1)+ClusterVar.E5x5Element(1,-2);
1240  float leftstrip=ClusterVar.E5x5Element(-1,0)+ClusterVar.E5x5Element(-1,-1)+ClusterVar.E5x5Element(-1,2)
1241  +ClusterVar.E5x5Element(-1,1)+ClusterVar.E5x5Element(-1,2);
1242 
1243  if(rightstrip>leftstrip)e2x5Max_=rightstrip+centerstrip;
1244  else e2x5Max_=leftstrip+centerstrip;
1245  e2x5Max_=e2x5Max_/clusterRef->energy();
1246  //GetCrysCoordinates(clusterRef);
1247  //fill5x5Map(clusterRef);
1248  VtxZ_=primaryVertex_->z();
1249  ClusPhi_=clusterRef->position().phi();
1250  ClusEta_=fabs(clusterRef->position().eta());
1251  EB=fabs(clusterRef->position().eta())/clusterRef->position().eta();
1252  logPFClusE_=log(clusterRef->energy());
1253  if(ClusEta_<1.4446){
1254  float LC_Var[26];
1255  LC_Var[0]=VtxZ_;
1256  LC_Var[1]=EB;
1257  LC_Var[2]=ClusEta_;
1258  LC_Var[3]=ClusPhi_;
1259  LC_Var[4]=logPFClusE_;
1260  LC_Var[5]=eSeed_;
1261  //top bottom left right
1262  LC_Var[6]=etop_;
1263  LC_Var[7]=ebottom_;
1264  LC_Var[8]=eleft_;
1265  LC_Var[9]=eright_;
1266  LC_Var[10]=ClusR9_;
1267  LC_Var[11]=e1x3_;
1268  LC_Var[12]=e3x1_;
1269  LC_Var[13]=Clus5x5ratio_;
1270  LC_Var[14]=e1x5_;
1271  LC_Var[15]=e2x5Max_;
1272  LC_Var[16]=e2x5Top_;
1273  LC_Var[17]=e2x5Bottom_;
1274  LC_Var[18]=e2x5Left_;
1275  LC_Var[19]=e2x5Right_;
1276  LC_Var[20]=CrysEta_;
1277  LC_Var[21]=CrysPhi_;
1278  float CrysIphiMod2=CrysIPhi_%2;
1279  float CrysIetaMod5=CrysIEta_%5;
1280  float CrysIphiMod20=CrysIPhi_%20;
1281  LC_Var[22]=CrysIphiMod2;
1282  LC_Var[23]=CrysIetaMod5;
1283  LC_Var[24]=CrysIphiMod20;
1284  LC_Var[25]=PFCrysEtaCrack_;
1285  BDTG=ReaderLCEB_->GetResponse(LC_Var);
1286  //cout<<"LC "<<BDTG<<endl;
1287  }
1288  else{
1289  float LC_Var[22];
1290  LC_Var[0]=VtxZ_;
1291  LC_Var[1]=EB;
1292  LC_Var[2]=ClusEta_;
1293  LC_Var[3]=ClusPhi_;
1294  LC_Var[4]=logPFClusE_;
1295  LC_Var[5]=eSeed_;
1296  //top bottom left right
1297  LC_Var[6]=etop_;
1298  LC_Var[7]=ebottom_;
1299  LC_Var[8]=eleft_;
1300  LC_Var[9]=eright_;
1301  LC_Var[10]=ClusR9_;
1302  LC_Var[11]=e1x3_;
1303  LC_Var[12]=e3x1_;
1304  LC_Var[13]=Clus5x5ratio_;
1305  LC_Var[14]=e1x5_;
1306  LC_Var[15]=e2x5Max_;
1307  LC_Var[16]=e2x5Top_;
1308  LC_Var[17]=e2x5Bottom_;
1309  LC_Var[18]=e2x5Left_;
1310  LC_Var[19]=e2x5Right_;
1311  LC_Var[20]=CrysX_;
1312  LC_Var[21]=CrysY_;
1313  BDTG=ReaderLCEE_->GetResponse(LC_Var);
1314  //cout<<"LC "<<BDTG<<endl;
1315  }
1316  return BDTG;
1317 
1318 }
1319 
1320 bool PFPhotonAlgo::EvaluateSingleLegMVA(const reco::PFBlockRef& blockref, const reco::Vertex& primaryvtx, unsigned int track_index)
1321 {
1322  bool convtkfound=false;
1323  const reco::PFBlock& block = *blockref;
1325  //use this to store linkdata in the associatedElements function below
1326  PFBlock::LinkData linkData = block.linkData();
1327  //calculate MVA Variables
1328  chi2=elements[track_index].trackRef()->chi2()/elements[track_index].trackRef()->ndof();
1329  nlost=elements[track_index].trackRef()->hitPattern().numberOfLostHits(HitPattern::MISSING_INNER_HITS);
1330  nlayers=elements[track_index].trackRef()->hitPattern().trackerLayersWithMeasurement();
1331  track_pt=elements[track_index].trackRef()->pt();
1332  STIP=elements[track_index].trackRefPF()->STIP();
1333 
1334  float linked_e=0;
1335  float linked_h=0;
1336  std::multimap<double, unsigned int> ecalAssoTrack;
1337  block.associatedElements( track_index,linkData,
1338  ecalAssoTrack,
1341  std::multimap<double, unsigned int> hcalAssoTrack;
1342  block.associatedElements( track_index,linkData,
1343  hcalAssoTrack,
1346  if(ecalAssoTrack.size() > 0) {
1347  for(std::multimap<double, unsigned int>::iterator itecal = ecalAssoTrack.begin();
1348  itecal != ecalAssoTrack.end(); ++itecal) {
1349  linked_e=linked_e+elements[itecal->second].clusterRef()->energy();
1350  }
1351  }
1352  if(hcalAssoTrack.size() > 0) {
1353  for(std::multimap<double, unsigned int>::iterator ithcal = hcalAssoTrack.begin();
1354  ithcal != hcalAssoTrack.end(); ++ithcal) {
1355  linked_h=linked_h+elements[ithcal->second].clusterRef()->energy();
1356  }
1357  }
1358  EoverPt=linked_e/elements[track_index].trackRef()->pt();
1359  HoverPt=linked_h/elements[track_index].trackRef()->pt();
1360  GlobalVector rvtx(elements[track_index].trackRef()->innerPosition().X()-primaryvtx.x(),
1361  elements[track_index].trackRef()->innerPosition().Y()-primaryvtx.y(),
1362  elements[track_index].trackRef()->innerPosition().Z()-primaryvtx.z());
1363  double vtx_phi=rvtx.phi();
1364  //delta Phi between conversion vertex and track
1365  del_phi=fabs(deltaPhi(vtx_phi, elements[track_index].trackRef()->innerMomentum().Phi()));
1366  mvaValue = tmvaReader_->EvaluateMVA("BDT");
1367  if(mvaValue > MVACUT)convtkfound=true;
1368  return convtkfound;
1369 }
1370 
1371 //Recover Early Conversions reconstructed as PFelectrons
1373  //std::auto_ptr< reco::PFCandidateCollection >
1374  //&pfElectronCandidates_,
1375  std::vector<reco::PFCandidate>&
1376  tempElectronCandidates,
1378  ){
1379  //step 1 check temp electrons for clusters that match Photon Supercluster:
1380  // permElectronCandidates->clear();
1381  int count=0;
1382  for ( std::vector<reco::PFCandidate>::const_iterator ec=tempElectronCandidates.begin(); ec != tempElectronCandidates.end(); ++ec )
1383  {
1384  // bool matched=false;
1385  int mh=ec->gsfTrackRef()->hitPattern().numberOfLostHits(HitPattern::MISSING_INNER_HITS);
1386  //if(mh==0)continue;//Case where missing hits greater than zero
1387 
1388  reco::GsfTrackRef gsf=ec->gsfTrackRef();
1389  //some hoopla to get Electron SC ref
1390 
1391  if(gsf->extra().isAvailable() && gsf->extra()->seedRef().isAvailable() && mh>0)
1392  {
1393  reco::ElectronSeedRef seedRef= gsf->extra()->seedRef().castTo<reco::ElectronSeedRef>();
1394  if(seedRef.isAvailable() && seedRef->isEcalDriven())
1395  {
1396  reco::SuperClusterRef ElecscRef = seedRef->caloCluster().castTo<reco::SuperClusterRef>();
1397 
1398  if(ElecscRef.isNonnull()){
1399  //finally see if it matches:
1400  reco::SuperClusterRef PhotscRef=sc->superClusterRef();
1401  if(PhotscRef==ElecscRef)
1402  {
1403  match_ind.push_back(count);
1404  // matched=true;
1405  //cout<<"Matched Electron with Index "<<count<<" This is the electron "<<*ec<<endl;
1406  //find that they have the same SC footprint start to collect Clusters and tracks and these will be passed to PFPhoton
1407  reco::PFCandidate::ElementsInBlocks eleInBlocks = ec->elementsInBlocks();
1408  for(unsigned i=0; i<eleInBlocks.size(); i++)
1409  {
1410  reco::PFBlockRef blockRef = eleInBlocks[i].first;
1411  unsigned indexInBlock = eleInBlocks[i].second;
1412  //const edm::OwnVector< reco::PFBlockElement >& elements=eleInBlocks[i].first->elements();
1413  //const reco::PFBlockElement& element = elements[indexInBlock];
1414 
1415  AddFromElectron_.push_back(indexInBlock);
1416  }
1417  }
1418  }
1419  }
1420  }
1421  count++;
1422  }
1423 }
float Clus5x5ratio_
Definition: PFPhotonAlgo.h:174
double GetResponse(const float *vector) const
Definition: GBRForest.h:55
bool isAvailable() const
Definition: Ref.h:614
type
Definition: HCALResponse.h:21
const SuperClusterRef & superClusterRef() const
void setPs2Energy(float e2)
set corrected PS2 energy
Definition: PFCandidate.h:279
Abstract base class for a PFBlock element (track, cluster...)
int i
Definition: DBlmapReader.cc:9
void setPs1Energy(float e1)
set corrected PS1 energy
Definition: PFCandidate.h:273
void MustacheClust(const std::vector< CaloCluster > &clusters, std::vector< unsigned int > &insideMust, std::vector< unsigned int > &outsideMust)
Definition: Mustache.cc:216
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:250
const GBRForest * ReaderLCEE_
Definition: PFPhotonAlgo.h:155
void setFlag(Flags theFlag, bool value)
set a given flag
Definition: PFCandidate.cc:285
void set_mva_nothing_gamma(float mva)
set mva for gamma detection
Definition: PFCandidate.h:329
void setPositionAtECALEntrance(const math::XYZPointF &pos)
set position at ECAL entrance
Definition: PFCandidate.h:348
double y() const
y coordinate
Definition: Vertex.h:110
float logPFClusE_
Definition: PFPhotonAlgo.h:174
float SCEtaWidth_
Definition: PFPhotonAlgo.h:184
Type type() const
int OutsideMust()
Definition: Mustache.h:46
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
std::map< unsigned int, Link > LinkData
Definition: PFBlock.h:46
size_type size() const
Definition: OwnVector.h:254
Geom::Phi< T > phi() const
Definition: PV3DBase.h:69
Geom::Theta< T > theta() const
#define X(str)
Definition: MuonsGrabber.cc:48
verbosityLevel verbosityLevel_
Definition: PFPhotonAlgo.h:140
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:152
const LinkData & linkData() const
Definition: PFBlock.h:112
virtual void setVertex(const math::XYZPoint &p)
set vertex
Definition: PFCandidate.h:408
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< float > > XYZPointF
point in space with cartesian internal representation
Definition: Point3D.h:10
std::vector< unsigned int > AddFromElectron_
Definition: PFPhotonAlgo.h:197
const GBRForest * ReaderGCEEhR9_
Definition: PFPhotonAlgo.h:157
T eta() const
double E5x5Element(int i, int j)
float e2x5Right_
Definition: PFPhotonAlgo.h:180
float LowestMustClust()
Definition: Mustache.h:44
std::pair< double, double > GetCrysCoor()
virtual double eta() const
momentum pseudorapidity
double ClustersPhiRMS(const std::vector< reco::CaloCluster > &PFClusters, float PFPhoPhi)
std::vector< ElementInBlock > ElementsInBlocks
Definition: PFCandidate.h:386
std::vector< PFCandidatePtr > pfCandidates(const PFJet &jet, int particleId, bool sort=true)
iterator begin()
Definition: OwnVector.h:234
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:29
double mvaValue
Definition: PFPhotonAlgo.h:169
void push_back(D *&d)
Definition: OwnVector.h:280
virtual double energy() const
energy
float MustacheEtOut()
Definition: Mustache.h:43
std::pair< double, double > GetCrysIndex()
TMVA::Reader * tmvaReader_
Definition: PFPhotonAlgo.h:149
void addElementInBlock(const reco::PFBlockRef &blockref, unsigned elementIndex)
add an element to the current PFCandidate
Definition: PFCandidate.cc:211
float EvaluateResMVA(const reco::PFCandidate &, const std::vector< reco::CaloCluster > &PFClusters)
T sqrt(T t)
Definition: SSEVec.h:48
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
TH2D * X0_outer
Definition: PFPhotonAlgo.h:192
double z() const
y coordinate
Definition: Vertex.h:112
float EvaluateGCorrMVA(const reco::PFCandidate &, const std::vector< reco::CaloCluster > &PFClusters)
float EvaluateLCorrMVA(reco::PFClusterRef clusterRef)
const GBRForest * ReaderLCEB_
Definition: PFPhotonAlgo.h:154
TH2D * X0_inner
Definition: PFPhotonAlgo.h:190
float PFPhoECorr_
Definition: PFPhotonAlgo.h:184
TH2D * X0_middle
Definition: PFPhotonAlgo.h:191
const reco::Vertex * primaryVertex_
Definition: PFPhotonAlgo.h:148
void addDaughter(const Candidate &, const std::string &s="")
add a clone of the passed candidate as daughter
float e2x5Bottom_
Definition: PFPhotonAlgo.h:180
double sumPtTrackIsoSlopeForPhoton_
Definition: PFPhotonAlgo.h:162
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:217
float SCPhiWidth_
Definition: PFPhotonAlgo.h:184
boost::shared_ptr< PFEnergyCalibration > thePFEnergyCalibration_
Definition: PFPhotonAlgo.h:160
const GBRForest * ReaderGCEB_
Definition: PFPhotonAlgo.h:156
void EarlyConversion(std::vector< reco::PFCandidate > &tempElectronCandidates, const reco::PFBlockElementSuperCluster *sc)
double x() const
x coordinate
Definition: Vertex.h:108
iterator end()
Definition: OwnVector.h:239
virtual bool trackType(TrackType trType) const
float PFCrysEtaCrack_
Definition: PFPhotonAlgo.h:174
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:30
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:12
bool EvaluateSingleLegMVA(const reco::PFBlockRef &blockref, const reco::Vertex &primaryvtx, unsigned int track_index)
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:39
static int position[264][3]
Definition: ReadPGInfo.cc:509
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:620
const GBRForest * ReaderGCEElR9_
Definition: PFPhotonAlgo.h:158
double sumPtTrackIsoForPhoton_
Definition: PFPhotonAlgo.h:161
void FillMustacheVar(const std::vector< CaloCluster > &clusters)
Definition: Mustache.cc:254
volatile std::atomic< bool > shutdown_flag false
std::vector< int > match_ind
Definition: PFPhotonAlgo.h:163
virtual const reco::TrackRef & trackRef() const
const ElementsInBlocks & elementsInBlocks() const
Definition: PFCandidate.cc:682
float MustacheE()
Definition: Mustache.h:41
virtual double phi() const
momentum azimuthal angle
void setHcalEnergy(float ehRaw, float ehCorr)
set corrected Hcal energy
Definition: PFCandidate.h:227
reco::SuperClusterRef superClusterRef() const
return a reference to the corresponding SuperCluster if any
Definition: PFCandidate.cc:600
Definition: DDAxes.h:10
Block of elements.
Definition: PFBlock.h:30
float PFPhoR9Corr_
Definition: PFPhotonAlgo.h:184