CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
List of all members | Public Member Functions | Private Types | Private Member Functions | Private Attributes
PFPhotonAlgo Class Reference

#include <PFPhotonAlgo.h>

Public Member Functions

bool isPhotonValidCandidate (const reco::PFBlockRef &blockRef, std::vector< bool > &active, std::auto_ptr< reco::PFCandidateCollection > &pfPhotonCandidates, std::auto_ptr< reco::PFCandidateCollection > &)
 
 PFPhotonAlgo (std::string mvaweightfile, double mvaConvCut, const reco::Vertex &primary, const boost::shared_ptr< PFEnergyCalibration > &thePFEnergyCalibration)
 
 ~PFPhotonAlgo ()
 

Private Types

enum  verbosityLevel { Silent, Summary, Chatty }
 

Private Member Functions

bool EvaluateSingleLegMVA (const reco::PFBlockRef &blockref, const reco::Vertex &primaryvtx, unsigned int track_index)
 
void RunPFPhoton (const reco::PFBlockRef &blockRef, std::vector< bool > &active, std::auto_ptr< reco::PFCandidateCollection > &pfPhotonCandidates)
 

Private Attributes

float chi2
 
float del_phi
 
float EoverPt
 
float HoverPt
 
bool isvalid_
 
double MVACUT
 
double mvaValue
 
float nlayers
 
float nlost
 
reco::Vertex primaryVertex_
 
float STIP
 
boost::shared_ptr
< PFEnergyCalibration
thePFEnergyCalibration_
 
TMVA::Reader * tmvaReader_
 
float track_pt
 
verbosityLevel verbosityLevel_
 

Detailed Description

Definition at line 24 of file PFPhotonAlgo.h.

Member Enumeration Documentation

Enumerator
Silent 
Summary 
Chatty 

Definition at line 56 of file PFPhotonAlgo.h.

Constructor & Destructor Documentation

PFPhotonAlgo::PFPhotonAlgo ( std::string  mvaweightfile,
double  mvaConvCut,
const reco::Vertex primary,
const boost::shared_ptr< PFEnergyCalibration > &  thePFEnergyCalibration 
)

Definition at line 23 of file PFPhotonAlgo.cc.

References chi2, del_phi, EoverPt, HoverPt, nlayers, nlost, primaryVertex_, STIP, tmvaReader_, and track_pt.

26  :
27  isvalid_(false),
29  MVACUT(mvaConvCut),
30  thePFEnergyCalibration_(thePFEnergyCalibration)
31 {
32  primaryVertex_=primary;
33  //Book MVA
34  tmvaReader_ = new TMVA::Reader("!Color:Silent");
35  tmvaReader_->AddVariable("del_phi",&del_phi);
36  tmvaReader_->AddVariable("nlayers", &nlayers);
37  tmvaReader_->AddVariable("chi2",&chi2);
38  tmvaReader_->AddVariable("EoverPt",&EoverPt);
39  tmvaReader_->AddVariable("HoverPt",&HoverPt);
40  tmvaReader_->AddVariable("track_pt", &track_pt);
41  tmvaReader_->AddVariable("STIP",&STIP);
42  tmvaReader_->AddVariable("nlost", &nlost);
43  tmvaReader_->BookMVA("BDT",mvaweightfile.c_str());
44  }
double MVACUT
Definition: PFPhotonAlgo.h:70
float track_pt
Definition: PFPhotonAlgo.h:76
verbosityLevel verbosityLevel_
Definition: PFPhotonAlgo.h:64
reco::Vertex primaryVertex_
Definition: PFPhotonAlgo.h:71
TMVA::Reader * tmvaReader_
Definition: PFPhotonAlgo.h:72
boost::shared_ptr< PFEnergyCalibration > thePFEnergyCalibration_
Definition: PFPhotonAlgo.h:73
PFPhotonAlgo::~PFPhotonAlgo ( )
inline

Definition at line 34 of file PFPhotonAlgo.h.

References tmvaReader_.

34 {delete tmvaReader_;};
TMVA::Reader * tmvaReader_
Definition: PFPhotonAlgo.h:72

Member Function Documentation

bool PFPhotonAlgo::EvaluateSingleLegMVA ( const reco::PFBlockRef blockref,
const reco::Vertex primaryvtx,
unsigned int  track_index 
)
private

Definition at line 620 of file PFPhotonAlgo.cc.

References reco::PFBlock::associatedElements(), createPayload::block, chi2, del_phi, Geom::deltaPhi(), reco::PFBlockElement::ECAL, reco::PFBlock::elements(), asciidump::elements, EoverPt, reco::PFBlockElement::HCAL, HoverPt, reco::PFBlock::linkData(), reco::PFBlock::LINKTEST_ALL, MVACUT, mvaValue, nlayers, nlost, colinearityKinematic::Phi, PV3DBase< T, PVType, FrameType >::phi(), STIP, tmvaReader_, track_pt, X, reco::Vertex::x(), reco::Vertex::y(), and reco::Vertex::z().

Referenced by RunPFPhoton().

621 {
622  bool convtkfound=false;
623  const reco::PFBlock& block = *blockref;
625  //use this to store linkdata in the associatedElements function below
626  PFBlock::LinkData linkData = block.linkData();
627  //calculate MVA Variables
628  chi2=elements[track_index].trackRef()->chi2()/elements[track_index].trackRef()->ndof();
629  nlost=elements[track_index].trackRef()->trackerExpectedHitsInner().numberOfLostHits();
630  nlayers=elements[track_index].trackRef()->hitPattern().trackerLayersWithMeasurement();
631  track_pt=elements[track_index].trackRef()->pt();
632  STIP=elements[track_index].trackRefPF()->STIP();
633 
634  float linked_e=0;
635  float linked_h=0;
636  std::multimap<double, unsigned int> ecalAssoTrack;
637  block.associatedElements( track_index,linkData,
638  ecalAssoTrack,
641  std::multimap<double, unsigned int> hcalAssoTrack;
642  block.associatedElements( track_index,linkData,
643  hcalAssoTrack,
646  if(ecalAssoTrack.size() > 0) {
647  for(std::multimap<double, unsigned int>::iterator itecal = ecalAssoTrack.begin();
648  itecal != ecalAssoTrack.end(); ++itecal) {
649  linked_e=linked_e+elements[itecal->second].clusterRef()->energy();
650  }
651  }
652  if(hcalAssoTrack.size() > 0) {
653  for(std::multimap<double, unsigned int>::iterator ithcal = hcalAssoTrack.begin();
654  ithcal != hcalAssoTrack.end(); ++ithcal) {
655  linked_h=linked_h+elements[ithcal->second].clusterRef()->energy();
656  }
657  }
658  EoverPt=linked_e/elements[track_index].trackRef()->pt();
659  HoverPt=linked_h/elements[track_index].trackRef()->pt();
660  GlobalVector rvtx(elements[track_index].trackRef()->innerPosition().X()-primaryvtx.x(),
661  elements[track_index].trackRef()->innerPosition().Y()-primaryvtx.y(),
662  elements[track_index].trackRef()->innerPosition().Z()-primaryvtx.z());
663  double vtx_phi=rvtx.phi();
664  //delta Phi between conversion vertex and track
665  del_phi=fabs(deltaPhi(vtx_phi, elements[track_index].trackRef()->innerMomentum().Phi()));
666  mvaValue = tmvaReader_->EvaluateMVA("BDT");
667  if(mvaValue > MVACUT)convtkfound=true;
668  return convtkfound;
669 }
double MVACUT
Definition: PFPhotonAlgo.h:70
double deltaPhi(float phi1, float phi2)
Definition: VectorUtil.h:30
double y() const
y coordinate
Definition: Vertex.h:97
std::map< unsigned int, Link > LinkData
Definition: PFBlock.h:46
Geom::Phi< T > phi() const
Definition: PV3DBase.h:63
float track_pt
Definition: PFPhotonAlgo.h:76
#define X(str)
Definition: MuonsGrabber.cc:49
list elements
Definition: asciidump.py:414
const edm::OwnVector< reco::PFBlockElement > & elements() const
Definition: PFBlock.h:107
const LinkData & linkData() const
Definition: PFBlock.h:112
double mvaValue
Definition: PFPhotonAlgo.h:77
TMVA::Reader * tmvaReader_
Definition: PFPhotonAlgo.h:72
double z() const
y coordinate
Definition: Vertex.h:99
double x() const
x coordinate
Definition: Vertex.h:95
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
Block of elements.
Definition: PFBlock.h:30
bool PFPhotonAlgo::isPhotonValidCandidate ( const reco::PFBlockRef blockRef,
std::vector< bool > &  active,
std::auto_ptr< reco::PFCandidateCollection > &  pfPhotonCandidates,
std::auto_ptr< reco::PFCandidateCollection > &   
)
inline

Definition at line 37 of file PFPhotonAlgo.h.

References isvalid_, and RunPFPhoton().

Referenced by PFAlgo::processBlock().

42  {
43  isvalid_=false;
44 
45  // RunPFPhoton has to set isvalid_ to TRUE in case it finds a valid candidate
46  // ... TODO: maybe can be replaced by checking for the size of the CandCollection.....
47  RunPFPhoton(blockRef,
48  active,
49  pfPhotonCandidates);
50 
51  return isvalid_;
52  };
void RunPFPhoton(const reco::PFBlockRef &blockRef, std::vector< bool > &active, std::auto_ptr< reco::PFCandidateCollection > &pfPhotonCandidates)
Definition: PFPhotonAlgo.cc:46
void PFPhotonAlgo::RunPFPhoton ( const reco::PFBlockRef blockRef,
std::vector< bool > &  active,
std::auto_ptr< reco::PFCandidateCollection > &  pfPhotonCandidates 
)
private

Definition at line 46 of file PFPhotonAlgo.cc.

References reco::PFCandidate::addElementInBlock(), edm::OwnVector< T, P >::begin(), Chatty, convBrem_cff::convTracks, reco::PFBlockElement::ECAL, asciidump::elements, edm::OwnVector< T, P >::end(), EvaluateSingleLegMVA(), reco::PFBlockElementSuperCluster::fromPhoton(), reco::PFCandidate::gamma, reco::PFCandidate::GAMMA_TO_GAMMACONV, reco::PFBlockElement::HCAL, i, isvalid_, reco::PFBlock::LINKTEST_ALL, mvaValue, primaryVertex_, reco::PFBlockElement::PS1, reco::PFBlockElement::PS2, edm::OwnVector< T, P >::push_back(), reco::PFBlockElement::SC, reco::PFCandidate::set_mva_nothing_gamma(), reco::PFCandidate::setEcalEnergy(), reco::PFCandidate::setFlag(), reco::PFCandidate::setHcalEnergy(), reco::PFCandidate::setPs1Energy(), reco::PFCandidate::setPs2Energy(), reco::PFCandidate::setSuperClusterRef(), edm::OwnVector< T, P >::size(), mathSSE::sqrt(), reco::PFBlockElementSuperCluster::superClusterRef(), reco::PFBlockElement::T_FROM_GAMMACONV, thePFEnergyCalibration_, reco::PFBlockElement::TRACK, reco::PFBlockElementTrack::trackType(), and verbosityLevel_.

Referenced by isPhotonValidCandidate().

48  {
49 
50  //std::cout<<" calling RunPFPhoton "<<std::endl;
51 
52  /* For now we construct the PhotonCandidate simply from
53  a) adding the CORRECTED energies of each participating ECAL cluster
54  b) build the energy-weighted direction for the Photon
55  */
56 
57 
58  // define how much is printed out for debugging.
59  // ... will be setable via CFG file parameter
60  verbosityLevel_ = Chatty; // Chatty mode.
61 
62 
63  // loop over all elements in the Block
64  const edm::OwnVector< reco::PFBlockElement >& elements = blockRef->elements();
66  std::vector<bool>::const_iterator actIter = active.begin();
67  PFBlock::LinkData linkData = blockRef->linkData();
68  bool isActive = true;
69 
70  if(elements.size() != active.size()) {
71  // throw excpetion...
72  //std::cout<<" WARNING: Size of collection and active-vectro don't agree!"<<std::endl;
73  return;
74  }
75 
76  // local vecotr to keep track of the indices of the 'elements' for the Photon candidate
77  // once we decide to keep the candidate, the 'active' entriesd for them must be set to false
78  std::vector<unsigned int> elemsToLock;
79  elemsToLock.resize(0);
80 
81  for( ; ele != elements.end(); ++ele, ++actIter ) {
82 
83  // if it's not a SuperCluster, go to the next element
84  if( !( ele->type() == reco::PFBlockElement::SC ) ) continue;
85 
86  // Photon kienmatics, will be updated for each identified participating element
87  float photonEnergy_ = 0.;
88  float photonX_ = 0.;
89  float photonY_ = 0.;
90  float photonZ_ = 0.;
91  float RawEcalEne = 0.;
92 
93  // Total pre-shower energy
94  float ps1TotEne = 0.;
95  float ps2TotEne = 0.;
96 
97  bool hasConvTrack=false;
98  bool hasSingleleg=false;
99  std::vector<unsigned int> AddClusters(0);
100  std::vector<unsigned int> IsoTracks(0);
101  std::multimap<unsigned int, unsigned int>ClusterAddPS1;
102  std::multimap<unsigned int, unsigned int>ClusterAddPS2;
103 
104  isActive = *(actIter);
105  //cout << " Found a SuperCluster. Energy " ;
106  const reco::PFBlockElementSuperCluster *sc = dynamic_cast<const reco::PFBlockElementSuperCluster*>(&(*ele));
107  //std::cout << sc->superClusterRef()->energy () << " Track/Ecal/Hcal Iso " << sc->trackIso()<< " " << sc->ecalIso() ;
108  //std::cout << " " << sc->hcalIso() <<std::endl;
109  if (!(sc->fromPhoton()))continue;
110 
111  // check the status of the SC Element...
112  // ..... I understand it should *always* be active, since PFElectronAlgo does not touch this (yet?) RISHI: YES
113  if( !isActive ) {
114  //std::cout<<" SuperCluster is NOT active.... "<<std::endl;
115  continue;
116  }
117  elemsToLock.push_back(ele-elements.begin()); //add SC to elements to lock
118  // loop over its constituent ECAL cluster
119  std::multimap<double, unsigned int> ecalAssoPFClusters;
120  blockRef->associatedElements( ele-elements.begin(),
121  linkData,
122  ecalAssoPFClusters,
125 
126  // loop over the ECAL clusters linked to the iEle
127  if( ! ecalAssoPFClusters.size() ) {
128  // This SC element has NO ECAL elements asigned... *SHOULD NOT HAPPEN*
129  //std::cout<<" Found SC element with no ECAL assigned "<<std::endl;
130  continue;
131  }
132 
133  // This is basically CASE 2
134  // .... we loop over all ECAL cluster linked to each other by this SC
135  for(std::multimap<double, unsigned int>::iterator itecal = ecalAssoPFClusters.begin();
136  itecal != ecalAssoPFClusters.end(); ++itecal) {
137 
138  // to get the reference to the PF clusters, this is needed.
139  reco::PFClusterRef clusterRef = elements[itecal->second].clusterRef();
140 
141  // from the clusterRef get the energy, direction, etc
142  // float ClustRawEnergy = clusterRef->energy();
143  // float ClustEta = clusterRef->position().eta();
144  // float ClustPhi = clusterRef->position().phi();
145 
146  // initialize the vectors for the PS energies
147  vector<double> ps1Ene(0);
148  vector<double> ps2Ene(0);
149  double ps1=0;
150  double ps2=0;
151  hasSingleleg=false;
152  hasConvTrack=false;
153 
154  /*
155  cout << " My cluster index " << itecal->second
156  << " energy " << ClustRawEnergy
157  << " eta " << ClustEta
158  << " phi " << ClustPhi << endl;
159  */
160  // check if this ECAL element is still active (could have been eaten by PFElectronAlgo)
161  // ......for now we give the PFElectron Algo *ALWAYS* Shot-Gun on the ECAL elements to the PFElectronAlgo
162 
163  if( !( active[itecal->second] ) ) {
164  //std::cout<< " .... this ECAL element is NOT active anymore. Is skipped. "<<std::endl;
165  continue;
166  }
167 
168  // ------------------------------------------------------------------------------------------
169  // TODO: do some tests on the ECAL cluster itself, deciding to use it or not for the Photons
170  // ..... ??? Do we need this?
171  if ( false ) {
172  // Check if there are a large number tracks that do not pass pre-ID around this ECAL cluster
173  bool useIt = true;
174  int mva_reject=0;
175  bool isClosest=false;
176  std::multimap<double, unsigned int> Trackscheck;
177  blockRef->associatedElements( itecal->second,
178  linkData,
179  Trackscheck,
182  for(std::multimap<double, unsigned int>::iterator track = Trackscheck.begin();
183  track != Trackscheck.end(); ++track) {
184 
185  // first check if is it's still active
186  if( ! (active[track->second]) ) continue;
187  hasSingleleg=EvaluateSingleLegMVA(blockRef, primaryVertex_, track->second);
188  //check if it is the closest linked track
189  std::multimap<double, unsigned int> closecheck;
190  blockRef->associatedElements(track->second,
191  linkData,
192  closecheck,
193  reco::PFBlockElement::ECAL,
195  if(closecheck.begin()->second ==itecal->second)isClosest=true;
196  if(!hasSingleleg)mva_reject++;
197  }
198 
199  if(mva_reject>0 && isClosest)useIt=false;
200  //if(mva_reject==1 && isClosest)useIt=false;
201  if( !useIt ) continue; // Go to next ECAL cluster within SC
202  }
203  // ------------------------------------------------------------------------------------------
204 
205  // We decided to keep the ECAL cluster for this Photon Candidate ...
206  elemsToLock.push_back(itecal->second);
207 
208  // look for PS in this Block linked to this ECAL cluster
209  std::multimap<double, unsigned int> PS1Elems;
210  std::multimap<double, unsigned int> PS2Elems;
211  //PS Layer 1 linked to ECAL cluster
212  blockRef->associatedElements( itecal->second,
213  linkData,
214  PS1Elems,
217  //PS Layer 2 linked to the ECAL cluster
218  blockRef->associatedElements( itecal->second,
219  linkData,
220  PS2Elems,
223 
224  // loop over all PS1 and compute energy
225  for(std::multimap<double, unsigned int>::iterator iteps = PS1Elems.begin();
226  iteps != PS1Elems.end(); ++iteps) {
227 
228  // first chekc if it's still active
229  if( !(active[iteps->second]) ) continue;
230 
231  //Check if this PS1 is not closer to another ECAL cluster in this Block
232  std::multimap<double, unsigned int> ECALPS1check;
233  blockRef->associatedElements( iteps->second,
234  linkData,
235  ECALPS1check,
236  reco::PFBlockElement::ECAL,
238  if(itecal->second==ECALPS1check.begin()->second)//then it is closest linked
239  {
240  reco::PFClusterRef ps1ClusterRef = elements[iteps->second].clusterRef();
241  ps1Ene.push_back( ps1ClusterRef->energy() );
242  ps1=ps1+ps1ClusterRef->energy(); //add to total PS1
243  // incativate this PS1 Element
244  elemsToLock.push_back(iteps->second);
245  }
246  }
247  for(std::multimap<double, unsigned int>::iterator iteps = PS2Elems.begin();
248  iteps != PS2Elems.end(); ++iteps) {
249 
250  // first chekc if it's still active
251  if( !(active[iteps->second]) ) continue;
252 
253  // Check if this PS2 is not closer to another ECAL cluster in this Block:
254  std::multimap<double, unsigned int> ECALPS2check;
255  blockRef->associatedElements( iteps->second,
256  linkData,
257  ECALPS2check,
258  reco::PFBlockElement::ECAL,
260  if(itecal->second==ECALPS2check.begin()->second)//is closest linked
261  {
262  reco::PFClusterRef ps2ClusterRef = elements[iteps->second].clusterRef();
263  ps2Ene.push_back( ps2ClusterRef->energy() );
264  ps2=ps2ClusterRef->energy()+ps2; //add to total PS2
265  // incativate this PS2 Element
266  elemsToLock.push_back(iteps->second);
267  }
268  }
269 
270  // loop over the HCAL Clusters linked to the ECAL cluster (CASE 6)
271  std::multimap<double, unsigned int> hcalElems;
272  blockRef->associatedElements( itecal->second,linkData,
273  hcalElems,
276 
277  for(std::multimap<double, unsigned int>::iterator ithcal = hcalElems.begin();
278  ithcal != hcalElems.end(); ++ithcal) {
279 
280  if ( ! (active[ithcal->second] ) ) continue; // HCAL Cluster already used....
281 
282  // TODO: Decide if this HCAL cluster is to be used
283  // .... based on some Physics
284  // .... To we need to check if it's closer to any other ECAL/TRACK?
285 
286  bool useHcal = false;
287  if ( !useHcal ) continue;
288  //not locked
289  //elemsToLock.push_back(ithcal->second);
290  }
291 
292  // This is entry point for CASE 3.
293  // .... we loop over all Tracks linked to this ECAL and check if it's labeled as conversion
294  // This is the part for looping over all 'Conversion' Tracks
295  std::multimap<double, unsigned int> convTracks;
296  blockRef->associatedElements( itecal->second,
297  linkData,
298  convTracks,
301  for(std::multimap<double, unsigned int>::iterator track = convTracks.begin();
302  track != convTracks.end(); ++track) {
303 
304  // first check if is it's still active
305  if( ! (active[track->second]) ) continue;
306 
307  // check if it's a CONV track
308  const reco::PFBlockElementTrack * trackRef = dynamic_cast<const reco::PFBlockElementTrack*>((&elements[track->second]));
309 
310  //Check if track is a Single leg from a Conversion
311  mvaValue=-999;
312  hasSingleleg=EvaluateSingleLegMVA(blockRef, primaryVertex_, track->second);
313  //If it is not then it will be used to check Track Isolation at the end
314  if(!hasSingleleg)
315  {
316  bool included=false;
317  //check if this track is already included in the vector so it is linked to an ECAL cluster that is already examined
318  for(unsigned int i=0; i<IsoTracks.size(); i++)
319  {if(IsoTracks[i]==track->second)included=true;}
320  if(!included)IsoTracks.push_back(track->second);
321  }
322  //For now only Pre-ID tracks that are not already identified as Conversions
323  if(hasSingleleg &&!(trackRef->trackType(reco::PFBlockElement::T_FROM_GAMMACONV)))
324  {
325  elemsToLock.push_back(track->second);
326  //find all the clusters linked to this track
327  std::multimap<double, unsigned int> moreClusters;
328  blockRef->associatedElements( track->second,
329  linkData,
330  moreClusters,
331  reco::PFBlockElement::ECAL,
333 
334  float p_in=sqrt(elements[track->second].trackRef()->innerMomentum().x() * elements[track->second].trackRef()->innerMomentum().x() +
335  elements[track->second].trackRef()->innerMomentum().y()*elements[track->second].trackRef()->innerMomentum().y()+
336  elements[track->second].trackRef()->innerMomentum().z()*elements[track->second].trackRef()->innerMomentum().z());
337  float linked_E=0;
338  for(std::multimap<double, unsigned int>::iterator clust = moreClusters.begin();
339  clust != moreClusters.end(); ++clust)
340  {
341  if(!active[clust->second])continue;
342  //running sum of linked energy
343  linked_E=linked_E+elements[clust->second].clusterRef()->energy();
344  //prevent too much energy from being added
345  if(linked_E/p_in>1.5)break;
346  bool included=false;
347  //check if these ecal clusters are already included with the supercluster
348  for(std::multimap<double, unsigned int>::iterator cluscheck = ecalAssoPFClusters.begin();
349  cluscheck != ecalAssoPFClusters.end(); ++cluscheck)
350  {
351  if(cluscheck->second==clust->second)included=true;
352  }
353  if(!included)AddClusters.push_back(clust->second);//Add to a container of clusters to be Added to the Photon candidate
354  }
355  }
356 
357  // Possibly need to be more smart about them (CASE 5)
358  // .... for now we simply skip non id'ed tracks
359  if( ! (trackRef->trackType(reco::PFBlockElement::T_FROM_GAMMACONV) ) ) continue;
360  hasConvTrack=true;
361  elemsToLock.push_back(track->second);
362  //again look at the clusters linked to this track
363  std::multimap<double, unsigned int> moreClusters;
364  blockRef->associatedElements( track->second,
365  linkData,
366  moreClusters,
367  reco::PFBlockElement::ECAL,
369 
370  float p_in=sqrt(elements[track->second].trackRef()->innerMomentum().x() * elements[track->second].trackRef()->innerMomentum().x() +
371  elements[track->second].trackRef()->innerMomentum().y()*elements[track->second].trackRef()->innerMomentum().y()+
372  elements[track->second].trackRef()->innerMomentum().z()*elements[track->second].trackRef()->innerMomentum().z());
373  float linked_E=0;
374  for(std::multimap<double, unsigned int>::iterator clust = moreClusters.begin();
375  clust != moreClusters.end(); ++clust)
376  {
377  if(!active[clust->second])continue;
378  linked_E=linked_E+elements[clust->second].clusterRef()->energy();
379  if(linked_E/p_in>1.5)break;
380  bool included=false;
381  for(std::multimap<double, unsigned int>::iterator cluscheck = ecalAssoPFClusters.begin();
382  cluscheck != ecalAssoPFClusters.end(); ++cluscheck)
383  {
384  if(cluscheck->second==clust->second)included=true;
385  }
386  if(!included)AddClusters.push_back(clust->second);//again only add if it is not already included with the supercluster
387  }
388 
389  // we need to check for other TRACKS linked to this conversion track, that point possibly no an ECAL cluster not included in the SC
390  // .... This is basically CASE 4.
391 
392  std::multimap<double, unsigned int> moreTracks;
393  blockRef->associatedElements( track->second,
394  linkData,
395  moreTracks,
398 
399  for(std::multimap<double, unsigned int>::iterator track2 = moreTracks.begin();
400  track2 != moreTracks.end(); ++track2) {
401 
402  // first check if is it's still active
403  if( ! (active[track2->second]) ) continue;
404  //skip over the 1st leg already found above
405  if(track->second==track2->second)continue;
406  // check if it's a CONV track
407  const reco::PFBlockElementTrack * track2Ref = dynamic_cast<const reco::PFBlockElementTrack*>((&elements[track2->second]));
408  if( ! (track2Ref->trackType(reco::PFBlockElement::T_FROM_GAMMACONV) ) ) continue; // Possibly need to be more smart about them (CASE 5)
409  elemsToLock.push_back(track2->second);
410  // so it's another active conversion track, that is in the Block and linked to the conversion track we already found
411  // find the ECAL cluster linked to it...
412  std::multimap<double, unsigned int> convEcal;
413  blockRef->associatedElements( track2->second,
414  linkData,
415  convEcal,
416  reco::PFBlockElement::ECAL,
418  float p_in=sqrt(elements[track->second].trackRef()->innerMomentum().x()*elements[track->second].trackRef()->innerMomentum().x()+
419  elements[track->second].trackRef()->innerMomentum().y()*elements[track->second].trackRef()->innerMomentum().y()+
420  elements[track->second].trackRef()->innerMomentum().z()*elements[track->second].trackRef()->innerMomentum().z());
421 
422 
423  float linked_E=0;
424  for(std::multimap<double, unsigned int>::iterator itConvEcal = convEcal.begin();
425  itConvEcal != convEcal.end(); ++itConvEcal) {
426 
427  if( ! (active[itConvEcal->second]) ) continue;
428  bool included=false;
429  for(std::multimap<double, unsigned int>::iterator cluscheck = ecalAssoPFClusters.begin();
430  cluscheck != ecalAssoPFClusters.end(); ++cluscheck)
431  {
432  if(cluscheck->second==itConvEcal->second)included=true;
433  }
434  linked_E=linked_E+elements[itConvEcal->second].clusterRef()->energy();
435  if(linked_E/p_in>1.5)break;
436  if(!included){AddClusters.push_back(itConvEcal->second);
437  }
438 
439  // it's still active, so we have to add it.
440  // CAUTION: we don't care here if it's part of the SC or not, we include it anyways
441 
442  // loop over the HCAL Clusters linked to the ECAL cluster (CASE 6)
443  std::multimap<double, unsigned int> hcalElems_conv;
444  blockRef->associatedElements( itecal->second,linkData,
445  hcalElems_conv,
448 
449  for(std::multimap<double, unsigned int>::iterator ithcal2 = hcalElems_conv.begin();
450  ithcal2 != hcalElems_conv.end(); ++ithcal2) {
451 
452  if ( ! (active[ithcal2->second] ) ) continue; // HCAL Cluster already used....
453 
454  // TODO: Decide if this HCAL cluster is to be used
455  // .... based on some Physics
456  // .... To we need to check if it's closer to any other ECAL/TRACK?
457 
458  bool useHcal = true;
459  if ( !useHcal ) continue;
460 
461  //elemsToLock.push_back(ithcal2->second);
462 
463  } // end of loop over HCAL clusters linked to the ECAL cluster from second CONVERSION leg
464 
465  } // end of loop over ECALs linked to second T_FROM_GAMMACONV
466 
467  } // end of loop over SECOND conversion leg
468 
469  // TODO: Do we need to check separatly if there are HCAL cluster linked to the track?
470 
471  } // end of loop over tracks
472 
473 
474  // Calibrate the Added ECAL energy
475  float addedCalibEne=0;
476  float addedRawEne=0;
477  std::vector<double>AddedPS1(0);
478  std::vector<double>AddedPS2(0);
479  double addedps1=0;
480  double addedps2=0;
481  for(unsigned int i=0; i<AddClusters.size(); i++)
482  {
483  std::multimap<double, unsigned int> PS1Elems_conv;
484  std::multimap<double, unsigned int> PS2Elems_conv;
485  blockRef->associatedElements(AddClusters[i],
486  linkData,
487  PS1Elems_conv,
490  blockRef->associatedElements( AddClusters[i],
491  linkData,
492  PS2Elems_conv,
495 
496  for(std::multimap<double, unsigned int>::iterator iteps = PS1Elems_conv.begin();
497  iteps != PS1Elems_conv.end(); ++iteps)
498  {
499  if(!active[iteps->second])continue;
500  std::multimap<double, unsigned int> PS1Elems_check;
501  blockRef->associatedElements(iteps->second,
502  linkData,
503  PS1Elems_check,
504  reco::PFBlockElement::ECAL,
506  if(PS1Elems_check.begin()->second==AddClusters[i])
507  {
508 
509  reco::PFClusterRef ps1ClusterRef = elements[iteps->second].clusterRef();
510  AddedPS1.push_back(ps1ClusterRef->energy());
511  addedps1=addedps1+ps1ClusterRef->energy();
512  elemsToLock.push_back(iteps->second);
513  }
514  }
515 
516  for(std::multimap<double, unsigned int>::iterator iteps = PS2Elems_conv.begin();
517  iteps != PS2Elems_conv.end(); ++iteps) {
518  if(!active[iteps->second])continue;
519  std::multimap<double, unsigned int> PS2Elems_check;
520  blockRef->associatedElements(iteps->second,
521  linkData,
522  PS2Elems_check,
523  reco::PFBlockElement::ECAL,
525 
526  if(PS2Elems_check.begin()->second==AddClusters[i])
527  {
528  reco::PFClusterRef ps2ClusterRef = elements[iteps->second].clusterRef();
529  AddedPS2.push_back(ps2ClusterRef->energy());
530  addedps2=addedps2+ps2ClusterRef->energy();
531  elemsToLock.push_back(iteps->second);
532  }
533  }
534  reco::PFClusterRef AddclusterRef = elements[AddClusters[i]].clusterRef();
535  addedRawEne = AddclusterRef->energy()+addedRawEne;
536  addedCalibEne = thePFEnergyCalibration_->energyEm(*AddclusterRef,AddedPS1,AddedPS2,false)+addedCalibEne;
537  AddedPS2.clear();
538  AddedPS1.clear();
539  elemsToLock.push_back(AddClusters[i]);
540  }
541  AddClusters.clear();
542  float EE = thePFEnergyCalibration_->energyEm(*clusterRef,ps1Ene,ps2Ene,false)+addedCalibEne;
543  //cout<<"Original Energy "<<EE<<"Added Energy "<<addedCalibEne<<endl;
544 
545  photonEnergy_ += EE;
546  RawEcalEne += clusterRef->energy()+addedRawEne;
547  photonX_ += EE * clusterRef->position().X();
548  photonY_ += EE * clusterRef->position().Y();
549  photonZ_ += EE * clusterRef->position().Z();
550  ps1TotEne += ps1+addedps1;
551  ps2TotEne += ps2+addedps2;
552  } // end of loop over all ECAL cluster within this SC
553 
554  // we've looped over all ECAL clusters, ready to generate PhotonCandidate
555  if( ! (photonEnergy_ > 0.) ) continue; // This SC is not a Photon Candidate
556  float sum_track_pt=0;
557  //Now check if there are tracks failing isolation outside of the Jurassic isolation region
558  for(unsigned int i=0; i<IsoTracks.size(); i++)sum_track_pt=sum_track_pt+elements[IsoTracks[i]].trackRef()->pt();
559 
560 
561 
562  math::XYZVector photonPosition(photonX_,
563  photonY_,
564  photonZ_);
565 
566  math::XYZVector photonDirection=photonPosition.Unit();
567 
568  math::XYZTLorentzVector photonMomentum(photonEnergy_* photonDirection.X(),
569  photonEnergy_* photonDirection.Y(),
570  photonEnergy_* photonDirection.Z(),
571  photonEnergy_ );
572 
573  if(sum_track_pt>(2+ 0.001* photonMomentum.pt()))
574  continue;//THIS SC is not a Photon it fails track Isolation
575 
576  /*
577  std::cout<<" Created Photon with energy = "<<photonEnergy_<<std::endl;
578  std::cout<<" pT = "<<photonMomentum.pt()<<std::endl;
579  std::cout<<" RawEne = "<<RawEcalEne<<std::endl;
580  std::cout<<" E = "<<photonMomentum.e()<<std::endl;
581  std::cout<<" eta = "<<photonMomentum.eta()<<std::endl;
582  std::cout<<" TrackIsolation = "<< sum_track_pt <<std::endl;
583  */
584 
585  reco::PFCandidate photonCand(0,photonMomentum, reco::PFCandidate::gamma);
586 
587  photonCand.setPs1Energy(ps1TotEne);
588  photonCand.setPs2Energy(ps2TotEne);
589  photonCand.setEcalEnergy(RawEcalEne,photonEnergy_);
590  photonCand.setHcalEnergy(0.,0.);
591  photonCand.set_mva_nothing_gamma(1.);
592  photonCand.setSuperClusterRef(sc->superClusterRef());
593  if(hasConvTrack || hasSingleleg)photonCand.setFlag( reco::PFCandidate::GAMMA_TO_GAMMACONV, true);
594 
595  //photonCand.setPositionAtECALEntrance(math::XYZPointF(photonMom_.position()));
596 
597 
598  // set isvalid_ to TRUE since we've found at least one photon candidate
599  isvalid_ = true;
600  // push back the candidate into the collection ...
601 
602  // ... and lock all elemts used
603  for(std::vector<unsigned int>::const_iterator it = elemsToLock.begin();
604  it != elemsToLock.end(); ++it)
605  {
606  if(active[*it])photonCand.addElementInBlock(blockRef,*it);
607  active[*it] = false;
608  }
609  pfCandidates->push_back(photonCand);
610  // ... and reset the vector
611  elemsToLock.resize(0);
612  hasConvTrack=false;
613  hasSingleleg=false;
614  } // end of loops over all elements in block
615 
616  return;
617 
618 }
tuple convTracks
Definition: convBrem_cff.py:35
int i
Definition: DBlmapReader.cc:9
std::map< unsigned int, Link > LinkData
Definition: PFBlock.h:46
size_type size() const
Definition: OwnVector.h:262
verbosityLevel verbosityLevel_
Definition: PFPhotonAlgo.h:64
list elements
Definition: asciidump.py:414
reco::Vertex primaryVertex_
Definition: PFPhotonAlgo.h:71
std::vector< PFCandidatePtr > pfCandidates(const PFJet &jet, int particleId, bool sort=true)
iterator begin()
Definition: OwnVector.h:236
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:30
double mvaValue
Definition: PFPhotonAlgo.h:77
void push_back(D *&d)
Definition: OwnVector.h:290
T sqrt(T t)
Definition: SSEVec.h:28
boost::shared_ptr< PFEnergyCalibration > thePFEnergyCalibration_
Definition: PFPhotonAlgo.h:73
iterator end()
Definition: OwnVector.h:243
virtual bool trackType(TrackType trType) const
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:31
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

Member Data Documentation

float PFPhotonAlgo::chi2
private

Definition at line 76 of file PFPhotonAlgo.h.

Referenced by EvaluateSingleLegMVA(), and PFPhotonAlgo().

float PFPhotonAlgo::del_phi
private

Definition at line 76 of file PFPhotonAlgo.h.

Referenced by EvaluateSingleLegMVA(), and PFPhotonAlgo().

float PFPhotonAlgo::EoverPt
private

Definition at line 76 of file PFPhotonAlgo.h.

Referenced by EvaluateSingleLegMVA(), and PFPhotonAlgo().

float PFPhotonAlgo::HoverPt
private

Definition at line 76 of file PFPhotonAlgo.h.

Referenced by EvaluateSingleLegMVA(), and PFPhotonAlgo().

bool PFPhotonAlgo::isvalid_
private

Definition at line 63 of file PFPhotonAlgo.h.

Referenced by isPhotonValidCandidate(), and RunPFPhoton().

double PFPhotonAlgo::MVACUT
private

Definition at line 70 of file PFPhotonAlgo.h.

Referenced by EvaluateSingleLegMVA().

double PFPhotonAlgo::mvaValue
private

Definition at line 77 of file PFPhotonAlgo.h.

Referenced by EvaluateSingleLegMVA(), and RunPFPhoton().

float PFPhotonAlgo::nlayers
private

Definition at line 75 of file PFPhotonAlgo.h.

Referenced by EvaluateSingleLegMVA(), and PFPhotonAlgo().

float PFPhotonAlgo::nlost
private

Definition at line 75 of file PFPhotonAlgo.h.

Referenced by EvaluateSingleLegMVA(), and PFPhotonAlgo().

reco::Vertex PFPhotonAlgo::primaryVertex_
private

Definition at line 71 of file PFPhotonAlgo.h.

Referenced by PFPhotonAlgo(), and RunPFPhoton().

float PFPhotonAlgo::STIP
private

Definition at line 76 of file PFPhotonAlgo.h.

Referenced by EvaluateSingleLegMVA(), and PFPhotonAlgo().

boost::shared_ptr<PFEnergyCalibration> PFPhotonAlgo::thePFEnergyCalibration_
private

Definition at line 73 of file PFPhotonAlgo.h.

Referenced by RunPFPhoton().

TMVA::Reader* PFPhotonAlgo::tmvaReader_
private

Definition at line 72 of file PFPhotonAlgo.h.

Referenced by EvaluateSingleLegMVA(), PFPhotonAlgo(), and ~PFPhotonAlgo().

float PFPhotonAlgo::track_pt
private

Definition at line 76 of file PFPhotonAlgo.h.

Referenced by EvaluateSingleLegMVA(), and PFPhotonAlgo().

verbosityLevel PFPhotonAlgo::verbosityLevel_
private

Definition at line 64 of file PFPhotonAlgo.h.

Referenced by RunPFPhoton().