00001
00002
00003
00004
00005
00006
00007 #include "RecoParticleFlow/PFProducer/interface/PFEGammaAlgo.h"
00008 #include "RecoParticleFlow/PFProducer/interface/PFMuonAlgo.h"
00009 #include "DataFormats/ParticleFlowReco/interface/PFBlockElementBrem.h"
00010 #include "DataFormats/ParticleFlowReco/interface/PFRecHitFraction.h"
00011 #include "DataFormats/ParticleFlowReco/interface/PFRecHitFwd.h"
00012 #include "DataFormats/ParticleFlowReco/interface/PFBlockElementCluster.h"
00013 #include "DataFormats/ParticleFlowReco/interface/PFCluster.h"
00014 #include "DataFormats/ParticleFlowReco/interface/PFClusterFwd.h"
00015 #include "DataFormats/ParticleFlowReco/interface/PFBlockElementSuperCluster.h"
00016 #include "DataFormats/EgammaReco/interface/ElectronSeed.h"
00017 #include "DataFormats/ParticleFlowReco/interface/PFRecHit.h"
00018 #include "DataFormats/EcalDetId/interface/EBDetId.h"
00019 #include "DataFormats/EcalDetId/interface/EEDetId.h"
00020 #include "DataFormats/EgammaCandidates/interface/Photon.h"
00021 #include "RecoParticleFlow/PFClusterTools/interface/PFEnergyCalibration.h"
00022 #include "RecoParticleFlow/PFClusterTools/interface/PFPhotonClusters.h"
00023 #include "RecoParticleFlow/PFClusterTools/interface/PFEnergyCalibration.h"
00024 #include "RecoParticleFlow/PFClusterTools/interface/PFSCEnergyCalibration.h"
00025 #include "RecoParticleFlow/PFClusterTools/interface/PFEnergyResolution.h"
00026 #include "RecoParticleFlow/PFClusterTools/interface/PFClusterWidthAlgo.h"
00027 #include "RecoParticleFlow/PFProducer/interface/PFElectronExtraEqual.h"
00028 #include "RecoEcal/EgammaCoreTools/interface/Mustache.h"
00029 #include "DataFormats/Math/interface/deltaPhi.h"
00030 #include "DataFormats/Math/interface/deltaR.h"
00031 #include <TFile.h>
00032 #include <iomanip>
00033 #include <algorithm>
00034 #include <TMath.h>
00035 using namespace std;
00036 using namespace reco;
00037
00038
00039 PFEGammaAlgo::PFEGammaAlgo(const double mvaEleCut,
00040 std::string mvaWeightFileEleID,
00041 const boost::shared_ptr<PFSCEnergyCalibration>& thePFSCEnergyCalibration,
00042 const boost::shared_ptr<PFEnergyCalibration>& thePFEnergyCalibration,
00043 bool applyCrackCorrections,
00044 bool usePFSCEleCalib,
00045 bool useEGElectrons,
00046 bool useEGammaSupercluster,
00047 double sumEtEcalIsoForEgammaSC_barrel,
00048 double sumEtEcalIsoForEgammaSC_endcap,
00049 double coneEcalIsoForEgammaSC,
00050 double sumPtTrackIsoForEgammaSC_barrel,
00051 double sumPtTrackIsoForEgammaSC_endcap,
00052 unsigned int nTrackIsoForEgammaSC,
00053 double coneTrackIsoForEgammaSC,
00054 std::string mvaweightfile,
00055 double mvaConvCut,
00056 bool useReg,
00057 std::string X0_Map,
00058 const reco::Vertex& primary,
00059 double sumPtTrackIsoForPhoton,
00060 double sumPtTrackIsoSlopeForPhoton
00061 ) :
00062 mvaEleCut_(mvaEleCut),
00063 thePFSCEnergyCalibration_(thePFSCEnergyCalibration),
00064 thePFEnergyCalibration_(thePFEnergyCalibration),
00065 applyCrackCorrections_(applyCrackCorrections),
00066 usePFSCEleCalib_(usePFSCEleCalib),
00067 useEGElectrons_(useEGElectrons),
00068 useEGammaSupercluster_(useEGammaSupercluster),
00069 sumEtEcalIsoForEgammaSC_barrel_(sumEtEcalIsoForEgammaSC_barrel),
00070 sumEtEcalIsoForEgammaSC_endcap_(sumEtEcalIsoForEgammaSC_endcap),
00071 coneEcalIsoForEgammaSC_(coneEcalIsoForEgammaSC),
00072 sumPtTrackIsoForEgammaSC_barrel_(sumPtTrackIsoForEgammaSC_barrel),
00073 sumPtTrackIsoForEgammaSC_endcap_(sumPtTrackIsoForEgammaSC_endcap),
00074 nTrackIsoForEgammaSC_(nTrackIsoForEgammaSC),
00075 coneTrackIsoForEgammaSC_(coneTrackIsoForEgammaSC),
00076 isvalid_(false),
00077 verbosityLevel_(Silent),
00078 MVACUT(mvaConvCut),
00079 useReg_(useReg),
00080 sumPtTrackIsoForPhoton_(sumPtTrackIsoForPhoton),
00081 sumPtTrackIsoSlopeForPhoton_(sumPtTrackIsoSlopeForPhoton),
00082 nlost(0.0), nlayers(0.0),
00083 chi2(0.0), STIP(0.0), del_phi(0.0),HoverPt(0.0), EoverPt(0.0), track_pt(0.0),
00084 mvaValue(0.0),
00085 CrysPhi_(0.0), CrysEta_(0.0), VtxZ_(0.0), ClusPhi_(0.0), ClusEta_(0.0),
00086 ClusR9_(0.0), Clus5x5ratio_(0.0), PFCrysEtaCrack_(0.0), logPFClusE_(0.0), e3x3_(0.0),
00087 CrysIPhi_(0), CrysIEta_(0),
00088 CrysX_(0.0), CrysY_(0.0),
00089 EB(0.0),
00090 eSeed_(0.0), e1x3_(0.0),e3x1_(0.0), e1x5_(0.0), e2x5Top_(0.0), e2x5Bottom_(0.0), e2x5Left_(0.0), e2x5Right_(0.0),
00091 etop_(0.0), ebottom_(0.0), eleft_(0.0), eright_(0.0),
00092 e2x5Max_(0.0),
00093 PFPhoEta_(0.0), PFPhoPhi_(0.0), PFPhoR9_(0.0), PFPhoR9Corr_(0.0), SCPhiWidth_(0.0), SCEtaWidth_(0.0),
00094 PFPhoEt_(0.0), RConv_(0.0), PFPhoEtCorr_(0.0), PFPhoE_(0.0), PFPhoECorr_(0.0), MustE_(0.0), E3x3_(0.0),
00095 dEta_(0.0), dPhi_(0.0), LowClusE_(0.0), RMSAll_(0.0), RMSMust_(0.0), nPFClus_(0.0),
00096 TotPS1_(0.0), TotPS2_(0.0),
00097 nVtx_(0.0),
00098 x0inner_(0.0), x0middle_(0.0), x0outer_(0.0),
00099 excluded_(0.0), Mustache_EtRatio_(0.0), Mustache_Et_out_(0.0)
00100 {
00101
00102
00103
00104 tmvaReaderEle_ = new TMVA::Reader("!Color:Silent");
00105 tmvaReaderEle_->AddVariable("lnPt_gsf",&lnPt_gsf);
00106 tmvaReaderEle_->AddVariable("Eta_gsf",&Eta_gsf);
00107 tmvaReaderEle_->AddVariable("dPtOverPt_gsf",&dPtOverPt_gsf);
00108 tmvaReaderEle_->AddVariable("DPtOverPt_gsf",&DPtOverPt_gsf);
00109
00110 tmvaReaderEle_->AddVariable("chi2_gsf",&chi2_gsf);
00111
00112 tmvaReaderEle_->AddVariable("nhit_kf",&nhit_kf);
00113 tmvaReaderEle_->AddVariable("chi2_kf",&chi2_kf);
00114 tmvaReaderEle_->AddVariable("EtotPinMode",&EtotPinMode);
00115 tmvaReaderEle_->AddVariable("EGsfPoutMode",&EGsfPoutMode);
00116 tmvaReaderEle_->AddVariable("EtotBremPinPoutMode",&EtotBremPinPoutMode);
00117 tmvaReaderEle_->AddVariable("DEtaGsfEcalClust",&DEtaGsfEcalClust);
00118 tmvaReaderEle_->AddVariable("SigmaEtaEta",&SigmaEtaEta);
00119 tmvaReaderEle_->AddVariable("HOverHE",&HOverHE);
00120
00121 tmvaReaderEle_->AddVariable("lateBrem",&lateBrem);
00122 tmvaReaderEle_->AddVariable("firstBrem",&firstBrem);
00123 tmvaReaderEle_->BookMVA("BDT",mvaWeightFileEleID.c_str());
00124
00125
00126
00127 tmvaReader_ = new TMVA::Reader("!Color:Silent");
00128 tmvaReader_->AddVariable("del_phi",&del_phi);
00129 tmvaReader_->AddVariable("nlayers", &nlayers);
00130 tmvaReader_->AddVariable("chi2",&chi2);
00131 tmvaReader_->AddVariable("EoverPt",&EoverPt);
00132 tmvaReader_->AddVariable("HoverPt",&HoverPt);
00133 tmvaReader_->AddVariable("track_pt", &track_pt);
00134 tmvaReader_->AddVariable("STIP",&STIP);
00135 tmvaReader_->AddVariable("nlost", &nlost);
00136 tmvaReader_->BookMVA("BDT",mvaweightfile.c_str());
00137
00138
00139 TFile *XO_File = new TFile(X0_Map.c_str(),"READ");
00140 X0_sum=(TH2D*)XO_File->Get("TrackerSum");
00141 X0_inner = (TH2D*)XO_File->Get("Inner");
00142 X0_middle = (TH2D*)XO_File->Get("Middle");
00143 X0_outer = (TH2D*)XO_File->Get("Outer");
00144
00145 }
00146
00147 void PFEGammaAlgo::RunPFEG(const reco::PFBlockRef& blockRef,
00148 std::vector<bool>& active
00149 ){
00150
00151
00152
00153
00154
00155
00156 fifthStepKfTrack_.clear();
00157 convGsfTrack_.clear();
00158
00159 egCandidate_.clear();
00160 egExtra_.clear();
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172 verbosityLevel_ = Chatty;
00173
00174
00175
00176 const edm::OwnVector< reco::PFBlockElement >& elements = blockRef->elements();
00177 edm::OwnVector< reco::PFBlockElement >::const_iterator ele = elements.begin();
00178 std::vector<bool>::const_iterator actIter = active.begin();
00179 PFBlock::LinkData linkData = blockRef->linkData();
00180 bool isActive = true;
00181
00182
00183 if(elements.size() != active.size()) {
00184
00185
00186 return;
00187 }
00188
00189
00190
00191
00192 AssMap associatedToGsf;
00193 AssMap associatedToBrems;
00194 AssMap associatedToEcal;
00195
00196
00197 SetLinks(blockRef,associatedToGsf,
00198 associatedToBrems,associatedToEcal,
00199 active, *primaryVertex_);
00200
00201
00202
00203
00204
00205
00206 std::vector<unsigned int> elemsToLock;
00207 elemsToLock.resize(0);
00208
00209 for( ; ele != elements.end(); ++ele, ++actIter ) {
00210
00211
00212 if( !( ele->type() == reco::PFBlockElement::SC ) ) continue;
00213
00214
00215
00216
00217 float photonEnergy_ = 0.;
00218 float photonX_ = 0.;
00219 float photonY_ = 0.;
00220 float photonZ_ = 0.;
00221 float RawEcalEne = 0.;
00222
00223
00224 float ps1TotEne = 0.;
00225 float ps2TotEne = 0.;
00226
00227 bool hasConvTrack=false;
00228 bool hasSingleleg=false;
00229 std::vector<unsigned int> AddClusters(0);
00230 std::vector<unsigned int> IsoTracks(0);
00231 std::multimap<unsigned int, unsigned int>ClusterAddPS1;
00232 std::multimap<unsigned int, unsigned int>ClusterAddPS2;
00233 std::vector<reco::TrackRef>singleLegRef;
00234 std::vector<float>MVA_values(0);
00235 std::vector<float>MVALCorr;
00236 std::vector<CaloCluster>PFClusters;
00237 reco::ConversionRefVector ConversionsRef_;
00238 isActive = *(actIter);
00239
00240 const reco::PFBlockElementSuperCluster *sc = dynamic_cast<const reco::PFBlockElementSuperCluster*>(&(*ele));
00241
00242
00243
00244
00245
00246
00247 if( !isActive ) {
00248
00249 continue;
00250 }
00251 elemsToLock.push_back(ele-elements.begin());
00252
00253 std::multimap<double, unsigned int> ecalAssoPFClusters;
00254 blockRef->associatedElements( ele-elements.begin(),
00255 linkData,
00256 ecalAssoPFClusters,
00257 reco::PFBlockElement::ECAL,
00258 reco::PFBlock::LINKTEST_ALL );
00259
00260
00261 PFPhoR9_=1.0;
00262 E3x3_=PFPhoR9_*(sc->superClusterRef()->rawEnergy());
00263
00264 if( ! ecalAssoPFClusters.size() ) {
00265
00266
00267 continue;
00268 }
00269
00270
00271
00272
00273 std::vector<unsigned int> matchedGsf;
00274 for (map<unsigned int,vector<unsigned int> >::iterator igsf = associatedToGsf.begin();
00275 igsf != associatedToGsf.end(); igsf++) {
00276
00277 bool matched = false;
00278 if( !( active[igsf->first] ) ) continue;
00279
00280 vector<unsigned int> assogsf_index = igsf->second;
00281 for (unsigned int ielegsf=0;ielegsf<assogsf_index.size();ielegsf++) {
00282 unsigned int associdx = assogsf_index[ielegsf];
00283
00284 if( !( active[associdx] ) ) continue;
00285
00286 PFBlockElement::Type assoele_type = elements[associdx].type();
00287
00288 if(assoele_type == reco::PFBlockElement::ECAL) {
00289 for(std::multimap<double, unsigned int>::iterator itecal = ecalAssoPFClusters.begin();
00290 itecal != ecalAssoPFClusters.end(); ++itecal) {
00291
00292 if (itecal->second==associdx) {
00293 matchedGsf.push_back(igsf->first);
00294 matched = true;
00295 break;
00296 }
00297 }
00298 }
00299
00300 if (matched) break;
00301 }
00302
00303 }
00304
00305
00306
00307
00308
00309
00310 for(std::multimap<double, unsigned int>::iterator itecal = ecalAssoPFClusters.begin();
00311 itecal != ecalAssoPFClusters.end(); ++itecal) {
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339 reco::PFClusterRef clusterRef = elements[itecal->second].clusterRef();
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350 vector<double> ps1Ene(0);
00351 vector<double> ps2Ene(0);
00352 double ps1=0;
00353 double ps2=0;
00354 hasSingleleg=false;
00355 hasConvTrack=false;
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366 if( !( active[itecal->second] ) ) {
00367
00368 continue;
00369 }
00370
00371
00372
00373
00374 if ( false ) {
00375
00376 bool useIt = true;
00377 int mva_reject=0;
00378 bool isClosest=false;
00379 std::multimap<double, unsigned int> Trackscheck;
00380 blockRef->associatedElements( itecal->second,
00381 linkData,
00382 Trackscheck,
00383 reco::PFBlockElement::TRACK,
00384 reco::PFBlock::LINKTEST_ALL);
00385 for(std::multimap<double, unsigned int>::iterator track = Trackscheck.begin();
00386 track != Trackscheck.end(); ++track) {
00387
00388
00389 if( ! (active[track->second]) ) continue;
00390 hasSingleleg=EvaluateSingleLegMVA(blockRef, *primaryVertex_, track->second);
00391
00392 std::multimap<double, unsigned int> closecheck;
00393 blockRef->associatedElements(track->second,
00394 linkData,
00395 closecheck,
00396 reco::PFBlockElement::ECAL,
00397 reco::PFBlock::LINKTEST_ALL);
00398 if(closecheck.begin()->second ==itecal->second)isClosest=true;
00399 if(!hasSingleleg)mva_reject++;
00400 }
00401
00402 if(mva_reject>0 && isClosest)useIt=false;
00403
00404 if( !useIt ) continue;
00405 }
00406
00407
00408
00409 elemsToLock.push_back(itecal->second);
00410
00411
00412 std::multimap<double, unsigned int> PS1Elems;
00413 std::multimap<double, unsigned int> PS2Elems;
00414
00415 blockRef->associatedElements( itecal->second,
00416 linkData,
00417 PS1Elems,
00418 reco::PFBlockElement::PS1,
00419 reco::PFBlock::LINKTEST_ALL );
00420
00421 blockRef->associatedElements( itecal->second,
00422 linkData,
00423 PS2Elems,
00424 reco::PFBlockElement::PS2,
00425 reco::PFBlock::LINKTEST_ALL );
00426
00427
00428 for(std::multimap<double, unsigned int>::iterator iteps = PS1Elems.begin();
00429 iteps != PS1Elems.end(); ++iteps) {
00430
00431
00432 if( !(active[iteps->second]) ) continue;
00433
00434
00435 std::multimap<double, unsigned int> ECALPS1check;
00436 blockRef->associatedElements( iteps->second,
00437 linkData,
00438 ECALPS1check,
00439 reco::PFBlockElement::ECAL,
00440 reco::PFBlock::LINKTEST_ALL );
00441 if(itecal->second==ECALPS1check.begin()->second)
00442 {
00443 reco::PFClusterRef ps1ClusterRef = elements[iteps->second].clusterRef();
00444 ps1Ene.push_back( ps1ClusterRef->energy() );
00445 ps1=ps1+ps1ClusterRef->energy();
00446
00447 elemsToLock.push_back(iteps->second);
00448 }
00449 }
00450 for(std::multimap<double, unsigned int>::iterator iteps = PS2Elems.begin();
00451 iteps != PS2Elems.end(); ++iteps) {
00452
00453
00454 if( !(active[iteps->second]) ) continue;
00455
00456
00457 std::multimap<double, unsigned int> ECALPS2check;
00458 blockRef->associatedElements( iteps->second,
00459 linkData,
00460 ECALPS2check,
00461 reco::PFBlockElement::ECAL,
00462 reco::PFBlock::LINKTEST_ALL );
00463 if(itecal->second==ECALPS2check.begin()->second)
00464 {
00465 reco::PFClusterRef ps2ClusterRef = elements[iteps->second].clusterRef();
00466 ps2Ene.push_back( ps2ClusterRef->energy() );
00467 ps2=ps2ClusterRef->energy()+ps2;
00468
00469 elemsToLock.push_back(iteps->second);
00470 }
00471 }
00472
00473
00474 std::multimap<double, unsigned int> hcalElems;
00475 blockRef->associatedElements( itecal->second,linkData,
00476 hcalElems,
00477 reco::PFBlockElement::HCAL,
00478 reco::PFBlock::LINKTEST_ALL );
00479
00480 for(std::multimap<double, unsigned int>::iterator ithcal = hcalElems.begin();
00481 ithcal != hcalElems.end(); ++ithcal) {
00482
00483 if ( ! (active[ithcal->second] ) ) continue;
00484
00485
00486
00487
00488
00489 bool useHcal = false;
00490 if ( !useHcal ) continue;
00491
00492
00493 }
00494
00495
00496
00497
00498 std::multimap<double, unsigned int> convTracks;
00499 blockRef->associatedElements( itecal->second,
00500 linkData,
00501 convTracks,
00502 reco::PFBlockElement::TRACK,
00503 reco::PFBlock::LINKTEST_ALL);
00504 for(std::multimap<double, unsigned int>::iterator track = convTracks.begin();
00505 track != convTracks.end(); ++track) {
00506
00507
00508 if( ! (active[track->second]) ) continue;
00509
00510
00511 const reco::PFBlockElementTrack * trackRef = dynamic_cast<const reco::PFBlockElementTrack*>((&elements[track->second]));
00512
00513
00514 mvaValue=-999;
00515 hasSingleleg=EvaluateSingleLegMVA(blockRef, *primaryVertex_, track->second);
00516
00517
00518
00519
00520
00521
00522
00523 if(!hasSingleleg)
00524 {
00525 bool included=false;
00526
00527 for(unsigned int i=0; i<IsoTracks.size(); i++)
00528 {if(IsoTracks[i]==track->second)included=true;}
00529 if(!included)IsoTracks.push_back(track->second);
00530 }
00531
00532 if(hasSingleleg &&!(trackRef->trackType(reco::PFBlockElement::T_FROM_GAMMACONV)))
00533 {
00534 elemsToLock.push_back(track->second);
00535
00536 reco::TrackRef t_ref=elements[track->second].trackRef();
00537 bool matched=false;
00538 for(unsigned int ic=0; ic<singleLegRef.size(); ic++)
00539 if(singleLegRef[ic]==t_ref)matched=true;
00540
00541 if(!matched){
00542 singleLegRef.push_back(t_ref);
00543 MVA_values.push_back(mvaValue);
00544 }
00545
00546 std::multimap<double, unsigned int> moreClusters;
00547 blockRef->associatedElements( track->second,
00548 linkData,
00549 moreClusters,
00550 reco::PFBlockElement::ECAL,
00551 reco::PFBlock::LINKTEST_ALL);
00552
00553 float p_in=sqrt(elements[track->second].trackRef()->innerMomentum().x() * elements[track->second].trackRef()->innerMomentum().x() +
00554 elements[track->second].trackRef()->innerMomentum().y()*elements[track->second].trackRef()->innerMomentum().y()+
00555 elements[track->second].trackRef()->innerMomentum().z()*elements[track->second].trackRef()->innerMomentum().z());
00556 float linked_E=0;
00557 for(std::multimap<double, unsigned int>::iterator clust = moreClusters.begin();
00558 clust != moreClusters.end(); ++clust)
00559 {
00560 if(!active[clust->second])continue;
00561
00562 linked_E=linked_E+elements[clust->second].clusterRef()->energy();
00563
00564 if(linked_E/p_in>1.5)break;
00565 bool included=false;
00566
00567 for(std::multimap<double, unsigned int>::iterator cluscheck = ecalAssoPFClusters.begin();
00568 cluscheck != ecalAssoPFClusters.end(); ++cluscheck)
00569 {
00570 if(cluscheck->second==clust->second)included=true;
00571 }
00572 if(!included)AddClusters.push_back(clust->second);
00573 }
00574 }
00575
00576
00577
00578 if( ! (trackRef->trackType(reco::PFBlockElement::T_FROM_GAMMACONV) ) ) continue;
00579 hasConvTrack=true;
00580 elemsToLock.push_back(track->second);
00581
00582
00583
00584
00585
00586 std::multimap<double, unsigned int> moreClusters;
00587 blockRef->associatedElements( track->second,
00588 linkData,
00589 moreClusters,
00590 reco::PFBlockElement::ECAL,
00591 reco::PFBlock::LINKTEST_ALL);
00592
00593 float p_in=sqrt(elements[track->second].trackRef()->innerMomentum().x() * elements[track->second].trackRef()->innerMomentum().x() +
00594 elements[track->second].trackRef()->innerMomentum().y()*elements[track->second].trackRef()->innerMomentum().y()+
00595 elements[track->second].trackRef()->innerMomentum().z()*elements[track->second].trackRef()->innerMomentum().z());
00596 float linked_E=0;
00597 for(std::multimap<double, unsigned int>::iterator clust = moreClusters.begin();
00598 clust != moreClusters.end(); ++clust)
00599 {
00600 if(!active[clust->second])continue;
00601 linked_E=linked_E+elements[clust->second].clusterRef()->energy();
00602 if(linked_E/p_in>1.5)break;
00603 bool included=false;
00604 for(std::multimap<double, unsigned int>::iterator cluscheck = ecalAssoPFClusters.begin();
00605 cluscheck != ecalAssoPFClusters.end(); ++cluscheck)
00606 {
00607 if(cluscheck->second==clust->second)included=true;
00608 }
00609 if(!included)AddClusters.push_back(clust->second);
00610 }
00611
00612
00613
00614
00615 std::multimap<double, unsigned int> moreTracks;
00616 blockRef->associatedElements( track->second,
00617 linkData,
00618 moreTracks,
00619 reco::PFBlockElement::TRACK,
00620 reco::PFBlock::LINKTEST_ALL);
00621
00622 for(std::multimap<double, unsigned int>::iterator track2 = moreTracks.begin();
00623 track2 != moreTracks.end(); ++track2) {
00624
00625
00626 if( ! (active[track2->second]) ) continue;
00627
00628 if(track->second==track2->second)continue;
00629
00630 const reco::PFBlockElementTrack * track2Ref = dynamic_cast<const reco::PFBlockElementTrack*>((&elements[track2->second]));
00631 if( ! (track2Ref->trackType(reco::PFBlockElement::T_FROM_GAMMACONV) ) ) continue;
00632 elemsToLock.push_back(track2->second);
00633
00634
00635 std::multimap<double, unsigned int> convEcalAll;
00636 blockRef->associatedElements( track2->second,
00637 linkData,
00638 convEcalAll,
00639 reco::PFBlockElement::ECAL,
00640 reco::PFBlock::LINKTEST_ALL);
00641
00642
00643
00644
00645 std::multimap<double, unsigned int> convEcal;
00646 for(std::multimap<double, unsigned int>::iterator itecal = convEcalAll.begin();
00647 itecal != convEcalAll.end(); ++itecal) {
00648
00649
00650 reco::PFClusterRef clusterRef = elements[itecal->second].clusterRef();
00651
00652 if (clusterRef->hitsAndFractions().at(0).first.subdetId()==sc->superClusterRef()->seed()->hitsAndFractions().at(0).first.subdetId()) {
00653 convEcal.insert(*itecal);
00654 }
00655 }
00656
00657 float p_in=sqrt(elements[track->second].trackRef()->innerMomentum().x()*elements[track->second].trackRef()->innerMomentum().x()+
00658 elements[track->second].trackRef()->innerMomentum().y()*elements[track->second].trackRef()->innerMomentum().y()+
00659 elements[track->second].trackRef()->innerMomentum().z()*elements[track->second].trackRef()->innerMomentum().z());
00660
00661
00662 float linked_E=0;
00663 for(std::multimap<double, unsigned int>::iterator itConvEcal = convEcal.begin();
00664 itConvEcal != convEcal.end(); ++itConvEcal) {
00665
00666 if( ! (active[itConvEcal->second]) ) continue;
00667 bool included=false;
00668 for(std::multimap<double, unsigned int>::iterator cluscheck = ecalAssoPFClusters.begin();
00669 cluscheck != ecalAssoPFClusters.end(); ++cluscheck)
00670 {
00671 if(cluscheck->second==itConvEcal->second)included=true;
00672 }
00673 linked_E=linked_E+elements[itConvEcal->second].clusterRef()->energy();
00674 if(linked_E/p_in>1.5)break;
00675 if(!included){AddClusters.push_back(itConvEcal->second);
00676 }
00677
00678
00679
00680
00681
00682 std::multimap<double, unsigned int> hcalElems_conv;
00683 blockRef->associatedElements( itecal->second,linkData,
00684 hcalElems_conv,
00685 reco::PFBlockElement::HCAL,
00686 reco::PFBlock::LINKTEST_ALL );
00687
00688 for(std::multimap<double, unsigned int>::iterator ithcal2 = hcalElems_conv.begin();
00689 ithcal2 != hcalElems_conv.end(); ++ithcal2) {
00690
00691 if ( ! (active[ithcal2->second] ) ) continue;
00692
00693
00694
00695
00696
00697 bool useHcal = true;
00698 if ( !useHcal ) continue;
00699
00700
00701
00702 }
00703
00704 }
00705
00706 }
00707
00708
00709
00710 }
00711
00712
00713
00714 float addedCalibEne=0;
00715 float addedRawEne=0;
00716 std::vector<double>AddedPS1(0);
00717 std::vector<double>AddedPS2(0);
00718 double addedps1=0;
00719 double addedps2=0;
00720 for(unsigned int i=0; i<AddClusters.size(); i++)
00721 {
00722 std::multimap<double, unsigned int> PS1Elems_conv;
00723 std::multimap<double, unsigned int> PS2Elems_conv;
00724 blockRef->associatedElements(AddClusters[i],
00725 linkData,
00726 PS1Elems_conv,
00727 reco::PFBlockElement::PS1,
00728 reco::PFBlock::LINKTEST_ALL );
00729 blockRef->associatedElements( AddClusters[i],
00730 linkData,
00731 PS2Elems_conv,
00732 reco::PFBlockElement::PS2,
00733 reco::PFBlock::LINKTEST_ALL );
00734
00735 for(std::multimap<double, unsigned int>::iterator iteps = PS1Elems_conv.begin();
00736 iteps != PS1Elems_conv.end(); ++iteps)
00737 {
00738 if(!active[iteps->second])continue;
00739 std::multimap<double, unsigned int> PS1Elems_check;
00740 blockRef->associatedElements(iteps->second,
00741 linkData,
00742 PS1Elems_check,
00743 reco::PFBlockElement::ECAL,
00744 reco::PFBlock::LINKTEST_ALL );
00745 if(PS1Elems_check.begin()->second==AddClusters[i])
00746 {
00747
00748 reco::PFClusterRef ps1ClusterRef = elements[iteps->second].clusterRef();
00749 AddedPS1.push_back(ps1ClusterRef->energy());
00750 addedps1=addedps1+ps1ClusterRef->energy();
00751 elemsToLock.push_back(iteps->second);
00752 }
00753 }
00754
00755 for(std::multimap<double, unsigned int>::iterator iteps = PS2Elems_conv.begin();
00756 iteps != PS2Elems_conv.end(); ++iteps) {
00757 if(!active[iteps->second])continue;
00758 std::multimap<double, unsigned int> PS2Elems_check;
00759 blockRef->associatedElements(iteps->second,
00760 linkData,
00761 PS2Elems_check,
00762 reco::PFBlockElement::ECAL,
00763 reco::PFBlock::LINKTEST_ALL );
00764
00765 if(PS2Elems_check.begin()->second==AddClusters[i])
00766 {
00767 reco::PFClusterRef ps2ClusterRef = elements[iteps->second].clusterRef();
00768 AddedPS2.push_back(ps2ClusterRef->energy());
00769 addedps2=addedps2+ps2ClusterRef->energy();
00770 elemsToLock.push_back(iteps->second);
00771 }
00772 }
00773 reco::PFClusterRef AddclusterRef = elements[AddClusters[i]].clusterRef();
00774 addedRawEne = AddclusterRef->energy()+addedRawEne;
00775 addedCalibEne = thePFEnergyCalibration_->energyEm(*AddclusterRef,AddedPS1,AddedPS2,false)+addedCalibEne;
00776 AddedPS2.clear();
00777 AddedPS1.clear();
00778 elemsToLock.push_back(AddClusters[i]);
00779 }
00780 AddClusters.clear();
00781 float EE=thePFEnergyCalibration_->energyEm(*clusterRef,ps1Ene,ps2Ene,false)+addedCalibEne;
00782 PFClusters.push_back(*clusterRef);
00783 if(useReg_){
00784 float LocCorr=EvaluateLCorrMVA(clusterRef);
00785 EE=LocCorr*clusterRef->energy()+addedCalibEne;
00786 }
00787 else{
00788 float LocCorr=EvaluateLCorrMVA(clusterRef);
00789 MVALCorr.push_back(LocCorr*clusterRef->energy());
00790 }
00791
00792
00793
00794 photonEnergy_ += EE;
00795 RawEcalEne += clusterRef->energy()+addedRawEne;
00796 photonX_ += EE * clusterRef->position().X();
00797 photonY_ += EE * clusterRef->position().Y();
00798 photonZ_ += EE * clusterRef->position().Z();
00799 ps1TotEne += ps1+addedps1;
00800 ps2TotEne += ps2+addedps2;
00801 }
00802
00803
00804
00805 bool goodelectron = false;
00806 if (matchedGsf.size()>0) {
00807
00808 int eleidx = matchedGsf.front();
00809 AddElectronElements(eleidx, elemsToLock, blockRef, associatedToGsf, associatedToBrems, associatedToEcal);
00810 goodelectron = AddElectronCandidate(eleidx, sc->superClusterRef(), elemsToLock, blockRef, associatedToGsf, associatedToBrems, associatedToEcal, active);
00811
00812 }
00813
00814 if (goodelectron) continue;
00815
00816
00817
00818
00819 if( ! (photonEnergy_ > 0.) ) continue;
00820 float sum_track_pt=0;
00821
00822 for(unsigned int i=0; i<IsoTracks.size(); i++)sum_track_pt=sum_track_pt+elements[IsoTracks[i]].trackRef()->pt();
00823
00824
00825
00826 math::XYZVector photonPosition(photonX_,
00827 photonY_,
00828 photonZ_);
00829 math::XYZVector photonPositionwrtVtx(
00830 photonX_- primaryVertex_->x(),
00831 photonY_-primaryVertex_->y(),
00832 photonZ_-primaryVertex_->z()
00833 );
00834 math::XYZVector photonDirection=photonPositionwrtVtx.Unit();
00835
00836 math::XYZTLorentzVector photonMomentum(photonEnergy_* photonDirection.X(),
00837 photonEnergy_* photonDirection.Y(),
00838 photonEnergy_* photonDirection.Z(),
00839 photonEnergy_ );
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861 reco::PFCandidate photonCand(0,photonMomentum, reco::PFCandidate::gamma);
00862 photonCand.setPs1Energy(ps1TotEne);
00863 photonCand.setPs2Energy(ps2TotEne);
00864 photonCand.setEcalEnergy(RawEcalEne,photonEnergy_);
00865 photonCand.setHcalEnergy(0.,0.);
00866 photonCand.set_mva_nothing_gamma(1.);
00867 photonCand.setSuperClusterRef(sc->superClusterRef());
00868 math::XYZPoint v(primaryVertex_->x(), primaryVertex_->y(), primaryVertex_->z());
00869 photonCand.setVertex( v );
00870 if(hasConvTrack || hasSingleleg)photonCand.setFlag( reco::PFCandidate::GAMMA_TO_GAMMACONV, true);
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881 isvalid_ = true;
00882
00883
00884 for(std::vector<unsigned int>::const_iterator it =
00885 AddFromElectron_.begin();
00886 it != AddFromElectron_.end(); ++it)photonCand.addElementInBlock(blockRef,*it);
00887
00888
00889 for(std::vector<unsigned int>::const_iterator it = elemsToLock.begin();
00890 it != elemsToLock.end(); ++it)
00891 {
00892 if(active[*it])
00893 {
00894 photonCand.addElementInBlock(blockRef,*it);
00895 if( elements[*it].type() == reco::PFBlockElement::TRACK )
00896 {
00897 if(elements[*it].convRef().isNonnull())
00898 {
00899
00900 bool matched=false;
00901 for(unsigned int ic = 0; ic < ConversionsRef_.size(); ic++)
00902 {
00903 if(ConversionsRef_[ic]==elements[*it].convRef())matched=true;
00904 }
00905 if(!matched)ConversionsRef_.push_back(elements[*it].convRef());
00906 }
00907 }
00908 }
00909 active[*it] = false;
00910 }
00911 PFPhoECorr_=0;
00912
00913
00914 PFCandidateEGammaExtra myExtra;
00915
00916 myExtra.setSuperClusterBoxRef(sc->superClusterRef());
00917
00918
00919 for(unsigned int l=0; l<MVALCorr.size(); ++l)
00920 {
00921
00922 PFPhoECorr_=PFPhoECorr_+MVALCorr[l];
00923 }
00924 TotPS1_=ps1TotEne;
00925 TotPS2_=ps2TotEne;
00926
00927 float GCorr=EvaluateGCorrMVA(photonCand, PFClusters);
00928 if(useReg_){
00929 math::XYZTLorentzVector photonCorrMomentum(GCorr*PFPhoECorr_* photonDirection.X(),
00930 GCorr*PFPhoECorr_* photonDirection.Y(),
00931 GCorr*PFPhoECorr_* photonDirection.Z(),
00932 GCorr * photonEnergy_ );
00933 photonCand.setP4(photonCorrMomentum);
00934 }
00935
00936 std::multimap<float, unsigned int>OrderedClust;
00937 for(unsigned int i=0; i<PFClusters.size(); ++i){
00938 float et=PFClusters[i].energy()*sin(PFClusters[i].position().theta());
00939 OrderedClust.insert(make_pair(et, i));
00940 }
00941 std::multimap<float, unsigned int>::reverse_iterator rit;
00942 rit=OrderedClust.rbegin();
00943 unsigned int highEindex=(*rit).second;
00944
00945 photonCand.setPositionAtECALEntrance(math::XYZPointF(PFClusters[highEindex].position()));
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964 for(unsigned int ic = 0; ic < MVA_values.size(); ic++)
00965 {
00966 myExtra.addSingleLegConvMva(MVA_values[ic]);
00967 myExtra.addSingleLegConvTrackRef(singleLegRef[ic]);
00968
00969 }
00970 for(unsigned int ic = 0; ic < ConversionsRef_.size(); ic++)
00971 {
00972 myExtra.addConversionRef(ConversionsRef_[ic]);
00973
00974 }
00975 egExtra_.push_back(myExtra);
00976 egCandidate_.push_back(photonCand);
00977
00978 elemsToLock.resize(0);
00979 hasConvTrack=false;
00980 hasSingleleg=false;
00981 }
00982
00983 return;
00984 }
00985
00986 float PFEGammaAlgo::EvaluateResMVA(reco::PFCandidate photon, std::vector<reco::CaloCluster>PFClusters){
00987 float BDTG=1;
00988 PFPhoEta_=photon.eta();
00989 PFPhoPhi_=photon.phi();
00990 PFPhoE_=photon.energy();
00991
00992 int ix = X0_sum->GetXaxis()->FindBin(PFPhoEta_);
00993 int iy = X0_sum->GetYaxis()->FindBin(PFPhoPhi_);
00994 x0inner_= X0_inner->GetBinContent(ix,iy);
00995 x0middle_=X0_middle->GetBinContent(ix,iy);
00996 x0outer_=X0_outer->GetBinContent(ix,iy);
00997 SCPhiWidth_=photon.superClusterRef()->phiWidth();
00998 SCEtaWidth_=photon.superClusterRef()->etaWidth();
00999 Mustache Must;
01000 std::vector<unsigned int>insideMust;
01001 std::vector<unsigned int>outsideMust;
01002 std::multimap<float, unsigned int>OrderedClust;
01003 Must.FillMustacheVar(PFClusters);
01004 MustE_=Must.MustacheE();
01005 LowClusE_=Must.LowestMustClust();
01006 PFPhoR9Corr_=E3x3_/MustE_;
01007 Must.MustacheClust(PFClusters,insideMust, outsideMust );
01008 for(unsigned int i=0; i<insideMust.size(); ++i){
01009 int index=insideMust[i];
01010 OrderedClust.insert(make_pair(PFClusters[index].energy(),index));
01011 }
01012 std::multimap<float, unsigned int>::iterator it;
01013 it=OrderedClust.begin();
01014 unsigned int lowEindex=(*it).second;
01015 std::multimap<float, unsigned int>::reverse_iterator rit;
01016 rit=OrderedClust.rbegin();
01017 unsigned int highEindex=(*rit).second;
01018 if(insideMust.size()>1){
01019 dEta_=fabs(PFClusters[highEindex].eta()-PFClusters[lowEindex].eta());
01020 dPhi_=asin(PFClusters[highEindex].phi()-PFClusters[lowEindex].phi());
01021 }
01022 else{
01023 dEta_=0;
01024 dPhi_=0;
01025 LowClusE_=0;
01026 }
01027
01028 RMSAll_=ClustersPhiRMS(PFClusters, PFPhoPhi_);
01029 std::vector<reco::CaloCluster>PFMustClusters;
01030 if(insideMust.size()>2){
01031 for(unsigned int i=0; i<insideMust.size(); ++i){
01032 unsigned int index=insideMust[i];
01033 if(index==lowEindex)continue;
01034 PFMustClusters.push_back(PFClusters[index]);
01035 }
01036 }
01037 else{
01038 for(unsigned int i=0; i<insideMust.size(); ++i){
01039 unsigned int index=insideMust[i];
01040 PFMustClusters.push_back(PFClusters[index]);
01041 }
01042 }
01043 RMSMust_=ClustersPhiRMS(PFMustClusters, PFPhoPhi_);
01044
01045 RConv_=310;
01046 PFCandidate::ElementsInBlocks eleInBlocks = photon.elementsInBlocks();
01047 for(unsigned i=0; i<eleInBlocks.size(); i++)
01048 {
01049 PFBlockRef blockRef = eleInBlocks[i].first;
01050 unsigned indexInBlock = eleInBlocks[i].second;
01051 const edm::OwnVector< reco::PFBlockElement >& elements=eleInBlocks[i].first->elements();
01052 const reco::PFBlockElement& element = elements[indexInBlock];
01053 if(element.type()==reco::PFBlockElement::TRACK){
01054 float R=sqrt(element.trackRef()->innerPosition().X()*element.trackRef()->innerPosition().X()+element.trackRef()->innerPosition().Y()*element.trackRef()->innerPosition().Y());
01055 if(RConv_>R)RConv_=R;
01056 }
01057 else continue;
01058 }
01059 float GC_Var[17];
01060 GC_Var[0]=PFPhoEta_;
01061 GC_Var[1]=PFPhoEt_;
01062 GC_Var[2]=PFPhoR9Corr_;
01063 GC_Var[3]=PFPhoPhi_;
01064 GC_Var[4]=SCEtaWidth_;
01065 GC_Var[5]=SCPhiWidth_;
01066 GC_Var[6]=x0inner_;
01067 GC_Var[7]=x0middle_;
01068 GC_Var[8]=x0outer_;
01069 GC_Var[9]=RConv_;
01070 GC_Var[10]=LowClusE_;
01071 GC_Var[11]=RMSMust_;
01072 GC_Var[12]=RMSAll_;
01073 GC_Var[13]=dEta_;
01074 GC_Var[14]=dPhi_;
01075 GC_Var[15]=nVtx_;
01076 GC_Var[16]=MustE_;
01077
01078 BDTG=ReaderRes_->GetResponse(GC_Var);
01079
01080
01081
01082
01083
01084
01085
01086 return BDTG;
01087
01088 }
01089
01090 float PFEGammaAlgo::EvaluateGCorrMVA(reco::PFCandidate photon, std::vector<CaloCluster>PFClusters){
01091 float BDTG=1;
01092 PFPhoEta_=photon.eta();
01093 PFPhoPhi_=photon.phi();
01094 PFPhoE_=photon.energy();
01095
01096 int ix = X0_sum->GetXaxis()->FindBin(PFPhoEta_);
01097 int iy = X0_sum->GetYaxis()->FindBin(PFPhoPhi_);
01098 x0inner_= X0_inner->GetBinContent(ix,iy);
01099 x0middle_=X0_middle->GetBinContent(ix,iy);
01100 x0outer_=X0_outer->GetBinContent(ix,iy);
01101 SCPhiWidth_=photon.superClusterRef()->phiWidth();
01102 SCEtaWidth_=photon.superClusterRef()->etaWidth();
01103 Mustache Must;
01104 std::vector<unsigned int>insideMust;
01105 std::vector<unsigned int>outsideMust;
01106 std::multimap<float, unsigned int>OrderedClust;
01107 Must.FillMustacheVar(PFClusters);
01108 MustE_=Must.MustacheE();
01109 LowClusE_=Must.LowestMustClust();
01110 PFPhoR9Corr_=E3x3_/MustE_;
01111 Must.MustacheClust(PFClusters,insideMust, outsideMust );
01112 for(unsigned int i=0; i<insideMust.size(); ++i){
01113 int index=insideMust[i];
01114 OrderedClust.insert(make_pair(PFClusters[index].energy(),index));
01115 }
01116 std::multimap<float, unsigned int>::iterator it;
01117 it=OrderedClust.begin();
01118 unsigned int lowEindex=(*it).second;
01119 std::multimap<float, unsigned int>::reverse_iterator rit;
01120 rit=OrderedClust.rbegin();
01121 unsigned int highEindex=(*rit).second;
01122 if(insideMust.size()>1){
01123 dEta_=fabs(PFClusters[highEindex].eta()-PFClusters[lowEindex].eta());
01124 dPhi_=asin(PFClusters[highEindex].phi()-PFClusters[lowEindex].phi());
01125 }
01126 else{
01127 dEta_=0;
01128 dPhi_=0;
01129 LowClusE_=0;
01130 }
01131
01132 RMSAll_=ClustersPhiRMS(PFClusters, PFPhoPhi_);
01133 std::vector<reco::CaloCluster>PFMustClusters;
01134 if(insideMust.size()>2){
01135 for(unsigned int i=0; i<insideMust.size(); ++i){
01136 unsigned int index=insideMust[i];
01137 if(index==lowEindex)continue;
01138 PFMustClusters.push_back(PFClusters[index]);
01139 }
01140 }
01141 else{
01142 for(unsigned int i=0; i<insideMust.size(); ++i){
01143 unsigned int index=insideMust[i];
01144 PFMustClusters.push_back(PFClusters[index]);
01145 }
01146 }
01147 RMSMust_=ClustersPhiRMS(PFMustClusters, PFPhoPhi_);
01148
01149 RConv_=310;
01150 PFCandidate::ElementsInBlocks eleInBlocks = photon.elementsInBlocks();
01151 for(unsigned i=0; i<eleInBlocks.size(); i++)
01152 {
01153 PFBlockRef blockRef = eleInBlocks[i].first;
01154 unsigned indexInBlock = eleInBlocks[i].second;
01155 const edm::OwnVector< reco::PFBlockElement >& elements=eleInBlocks[i].first->elements();
01156 const reco::PFBlockElement& element = elements[indexInBlock];
01157 if(element.type()==reco::PFBlockElement::TRACK){
01158 float R=sqrt(element.trackRef()->innerPosition().X()*element.trackRef()->innerPosition().X()+element.trackRef()->innerPosition().Y()*element.trackRef()->innerPosition().Y());
01159 if(RConv_>R)RConv_=R;
01160 }
01161 else continue;
01162 }
01163
01164 if(fabs(PFPhoEta_)<1.4446){
01165 float GC_Var[17];
01166 GC_Var[0]=PFPhoEta_;
01167 GC_Var[1]=PFPhoECorr_;
01168 GC_Var[2]=PFPhoR9Corr_;
01169 GC_Var[3]=SCEtaWidth_;
01170 GC_Var[4]=SCPhiWidth_;
01171 GC_Var[5]=PFPhoPhi_;
01172 GC_Var[6]=x0inner_;
01173 GC_Var[7]=x0middle_;
01174 GC_Var[8]=x0outer_;
01175 GC_Var[9]=RConv_;
01176 GC_Var[10]=LowClusE_;
01177 GC_Var[11]=RMSMust_;
01178 GC_Var[12]=RMSAll_;
01179 GC_Var[13]=dEta_;
01180 GC_Var[14]=dPhi_;
01181 GC_Var[15]=nVtx_;
01182 GC_Var[16]=MustE_;
01183 BDTG=ReaderGCEB_->GetResponse(GC_Var);
01184 }
01185 else if(PFPhoR9_>0.94){
01186 float GC_Var[19];
01187 GC_Var[0]=PFPhoEta_;
01188 GC_Var[1]=PFPhoECorr_;
01189 GC_Var[2]=PFPhoR9Corr_;
01190 GC_Var[3]=SCEtaWidth_;
01191 GC_Var[4]=SCPhiWidth_;
01192 GC_Var[5]=PFPhoPhi_;
01193 GC_Var[6]=x0inner_;
01194 GC_Var[7]=x0middle_;
01195 GC_Var[8]=x0outer_;
01196 GC_Var[9]=RConv_;
01197 GC_Var[10]=LowClusE_;
01198 GC_Var[11]=RMSMust_;
01199 GC_Var[12]=RMSAll_;
01200 GC_Var[13]=dEta_;
01201 GC_Var[14]=dPhi_;
01202 GC_Var[15]=nVtx_;
01203 GC_Var[16]=TotPS1_;
01204 GC_Var[17]=TotPS2_;
01205 GC_Var[18]=MustE_;
01206 BDTG=ReaderGCEEhR9_->GetResponse(GC_Var);
01207 }
01208
01209 else{
01210 float GC_Var[19];
01211 GC_Var[0]=PFPhoEta_;
01212 GC_Var[1]=PFPhoE_;
01213 GC_Var[2]=PFPhoR9Corr_;
01214 GC_Var[3]=SCEtaWidth_;
01215 GC_Var[4]=SCPhiWidth_;
01216 GC_Var[5]=PFPhoPhi_;
01217 GC_Var[6]=x0inner_;
01218 GC_Var[7]=x0middle_;
01219 GC_Var[8]=x0outer_;
01220 GC_Var[9]=RConv_;
01221 GC_Var[10]=LowClusE_;
01222 GC_Var[11]=RMSMust_;
01223 GC_Var[12]=RMSAll_;
01224 GC_Var[13]=dEta_;
01225 GC_Var[14]=dPhi_;
01226 GC_Var[15]=nVtx_;
01227 GC_Var[16]=TotPS1_;
01228 GC_Var[17]=TotPS2_;
01229 GC_Var[18]=MustE_;
01230 BDTG=ReaderGCEElR9_->GetResponse(GC_Var);
01231 }
01232
01233
01234 return BDTG;
01235
01236 }
01237
01238 double PFEGammaAlgo::ClustersPhiRMS(std::vector<reco::CaloCluster>PFClusters, float PFPhoPhi){
01239 double PFClustPhiRMS=0;
01240 double delPhi2=0;
01241 double delPhiSum=0;
01242 double ClusSum=0;
01243 for(unsigned int c=0; c<PFClusters.size(); ++c){
01244 delPhi2=(acos(cos(PFPhoPhi-PFClusters[c].phi()))* acos(cos(PFPhoPhi-PFClusters[c].phi())) )+delPhi2;
01245 delPhiSum=delPhiSum+ acos(cos(PFPhoPhi-PFClusters[c].phi()))*PFClusters[c].energy();
01246 ClusSum=ClusSum+PFClusters[c].energy();
01247 }
01248 double meandPhi=delPhiSum/ClusSum;
01249 PFClustPhiRMS=sqrt(fabs(delPhi2/ClusSum - (meandPhi*meandPhi)));
01250
01251 return PFClustPhiRMS;
01252 }
01253
01254 float PFEGammaAlgo::EvaluateLCorrMVA(reco::PFClusterRef clusterRef ){
01255 float BDTG=1;
01256 PFPhotonClusters ClusterVar(clusterRef);
01257 std::pair<double, double>ClusCoor=ClusterVar.GetCrysCoor();
01258 std::pair<int, int>ClusIndex=ClusterVar.GetCrysIndex();
01259
01260 if(clusterRef->layer()==PFLayer:: ECAL_BARREL ){
01261 PFCrysEtaCrack_=ClusterVar.EtaCrack();
01262 CrysEta_=ClusCoor.first;
01263 CrysPhi_=ClusCoor.second;
01264 CrysIEta_=ClusIndex.first;
01265 CrysIPhi_=ClusIndex.second;
01266 }
01267 else{
01268 CrysX_=ClusCoor.first;
01269 CrysY_=ClusCoor.second;
01270 }
01271
01272 eSeed_= ClusterVar.E5x5Element(0, 0)/clusterRef->energy();
01273 etop_=ClusterVar.E5x5Element(0,1)/clusterRef->energy();
01274 ebottom_=ClusterVar.E5x5Element(0,-1)/clusterRef->energy();
01275 eleft_=ClusterVar.E5x5Element(-1,0)/clusterRef->energy();
01276 eright_=ClusterVar.E5x5Element(1,0)/clusterRef->energy();
01277 e1x3_=(ClusterVar.E5x5Element(0,0)+ClusterVar.E5x5Element(0,1)+ClusterVar.E5x5Element(0,-1))/clusterRef->energy();
01278 e3x1_=(ClusterVar.E5x5Element(0,0)+ClusterVar.E5x5Element(-1,0)+ClusterVar.E5x5Element(1,0))/clusterRef->energy();
01279 e1x5_=ClusterVar.E5x5Element(0,0)+ClusterVar.E5x5Element(0,-2)+ClusterVar.E5x5Element(0,-1)+ClusterVar.E5x5Element(0,1)+ClusterVar.E5x5Element(0,2);
01280
01281 e2x5Top_=(ClusterVar.E5x5Element(-2,2)+ClusterVar.E5x5Element(-1, 2)+ClusterVar.E5x5Element(0, 2)
01282 +ClusterVar.E5x5Element(1, 2)+ClusterVar.E5x5Element(2, 2)
01283 +ClusterVar.E5x5Element(-2,1)+ClusterVar.E5x5Element(-1,1)+ClusterVar.E5x5Element(0,1)
01284 +ClusterVar.E5x5Element(1,1)+ClusterVar.E5x5Element(2,1))/clusterRef->energy();
01285 e2x5Bottom_=(ClusterVar.E5x5Element(-2,-2)+ClusterVar.E5x5Element(-1,-2)+ClusterVar.E5x5Element(0,-2)
01286 +ClusterVar.E5x5Element(1,-2)+ClusterVar.E5x5Element(2,-2)
01287 +ClusterVar.E5x5Element(-2,1)+ClusterVar.E5x5Element(-1,1)
01288 +ClusterVar.E5x5Element(0,1)+ClusterVar.E5x5Element(1,1)+ClusterVar.E5x5Element(2,1))/clusterRef->energy();
01289 e2x5Left_= (ClusterVar.E5x5Element(-2,-2)+ClusterVar.E5x5Element(-2,-1)
01290 +ClusterVar.E5x5Element(-2,0)
01291 +ClusterVar.E5x5Element(-2,1)+ClusterVar.E5x5Element(-2,2)
01292 +ClusterVar.E5x5Element(-1,-2)+ClusterVar.E5x5Element(-1,-1)+ClusterVar.E5x5Element(-1,0)
01293 +ClusterVar.E5x5Element(-1,1)+ClusterVar.E5x5Element(-1,2))/clusterRef->energy();
01294
01295 e2x5Right_ =(ClusterVar.E5x5Element(2,-2)+ClusterVar.E5x5Element(2,-1)
01296 +ClusterVar.E5x5Element(2,0)+ClusterVar.E5x5Element(2,1)+ClusterVar.E5x5Element(2,2)
01297 +ClusterVar.E5x5Element(1,-2)+ClusterVar.E5x5Element(1,-1)+ClusterVar.E5x5Element(1,0)
01298 +ClusterVar.E5x5Element(1,1)+ClusterVar.E5x5Element(1,2))/clusterRef->energy();
01299 float centerstrip=ClusterVar.E5x5Element(0,0)+ClusterVar.E5x5Element(0, -2)
01300 +ClusterVar.E5x5Element(0,-1)+ClusterVar.E5x5Element(0,1)+ClusterVar.E5x5Element(0,2);
01301 float rightstrip=ClusterVar.E5x5Element(1, 0)+ClusterVar.E5x5Element(1,1)
01302 +ClusterVar.E5x5Element(1,2)+ClusterVar.E5x5Element(1,-1)+ClusterVar.E5x5Element(1,-2);
01303 float leftstrip=ClusterVar.E5x5Element(-1,0)+ClusterVar.E5x5Element(-1,-1)+ClusterVar.E5x5Element(-1,2)
01304 +ClusterVar.E5x5Element(-1,1)+ClusterVar.E5x5Element(-1,2);
01305
01306 if(rightstrip>leftstrip)e2x5Max_=rightstrip+centerstrip;
01307 else e2x5Max_=leftstrip+centerstrip;
01308 e2x5Max_=e2x5Max_/clusterRef->energy();
01309
01310
01311 VtxZ_=primaryVertex_->z();
01312 ClusPhi_=clusterRef->position().phi();
01313 ClusEta_=fabs(clusterRef->position().eta());
01314 EB=fabs(clusterRef->position().eta())/clusterRef->position().eta();
01315 logPFClusE_=log(clusterRef->energy());
01316 if(ClusEta_<1.4446){
01317 float LC_Var[26];
01318 LC_Var[0]=VtxZ_;
01319 LC_Var[1]=EB;
01320 LC_Var[2]=ClusEta_;
01321 LC_Var[3]=ClusPhi_;
01322 LC_Var[4]=logPFClusE_;
01323 LC_Var[5]=eSeed_;
01324
01325 LC_Var[6]=etop_;
01326 LC_Var[7]=ebottom_;
01327 LC_Var[8]=eleft_;
01328 LC_Var[9]=eright_;
01329 LC_Var[10]=ClusR9_;
01330 LC_Var[11]=e1x3_;
01331 LC_Var[12]=e3x1_;
01332 LC_Var[13]=Clus5x5ratio_;
01333 LC_Var[14]=e1x5_;
01334 LC_Var[15]=e2x5Max_;
01335 LC_Var[16]=e2x5Top_;
01336 LC_Var[17]=e2x5Bottom_;
01337 LC_Var[18]=e2x5Left_;
01338 LC_Var[19]=e2x5Right_;
01339 LC_Var[20]=CrysEta_;
01340 LC_Var[21]=CrysPhi_;
01341 float CrysIphiMod2=CrysIPhi_%2;
01342 float CrysIetaMod5=CrysIEta_%5;
01343 float CrysIphiMod20=CrysIPhi_%20;
01344 LC_Var[22]=CrysIphiMod2;
01345 LC_Var[23]=CrysIetaMod5;
01346 LC_Var[24]=CrysIphiMod20;
01347 LC_Var[25]=PFCrysEtaCrack_;
01348 BDTG=ReaderLCEB_->GetResponse(LC_Var);
01349
01350 }
01351 else{
01352 float LC_Var[22];
01353 LC_Var[0]=VtxZ_;
01354 LC_Var[1]=EB;
01355 LC_Var[2]=ClusEta_;
01356 LC_Var[3]=ClusPhi_;
01357 LC_Var[4]=logPFClusE_;
01358 LC_Var[5]=eSeed_;
01359
01360 LC_Var[6]=etop_;
01361 LC_Var[7]=ebottom_;
01362 LC_Var[8]=eleft_;
01363 LC_Var[9]=eright_;
01364 LC_Var[10]=ClusR9_;
01365 LC_Var[11]=e1x3_;
01366 LC_Var[12]=e3x1_;
01367 LC_Var[13]=Clus5x5ratio_;
01368 LC_Var[14]=e1x5_;
01369 LC_Var[15]=e2x5Max_;
01370 LC_Var[16]=e2x5Top_;
01371 LC_Var[17]=e2x5Bottom_;
01372 LC_Var[18]=e2x5Left_;
01373 LC_Var[19]=e2x5Right_;
01374 LC_Var[20]=CrysX_;
01375 LC_Var[21]=CrysY_;
01376 BDTG=ReaderLCEE_->GetResponse(LC_Var);
01377
01378 }
01379 return BDTG;
01380
01381 }
01382
01383 bool PFEGammaAlgo::EvaluateSingleLegMVA(const reco::PFBlockRef& blockref, const reco::Vertex& primaryvtx, unsigned int track_index)
01384 {
01385 bool convtkfound=false;
01386 const reco::PFBlock& block = *blockref;
01387 const edm::OwnVector< reco::PFBlockElement >& elements = block.elements();
01388
01389 PFBlock::LinkData linkData = block.linkData();
01390
01391 chi2=elements[track_index].trackRef()->chi2()/elements[track_index].trackRef()->ndof();
01392 nlost=elements[track_index].trackRef()->trackerExpectedHitsInner().numberOfLostHits();
01393 nlayers=elements[track_index].trackRef()->hitPattern().trackerLayersWithMeasurement();
01394 track_pt=elements[track_index].trackRef()->pt();
01395 STIP=elements[track_index].trackRefPF()->STIP();
01396
01397 float linked_e=0;
01398 float linked_h=0;
01399 std::multimap<double, unsigned int> ecalAssoTrack;
01400 block.associatedElements( track_index,linkData,
01401 ecalAssoTrack,
01402 reco::PFBlockElement::ECAL,
01403 reco::PFBlock::LINKTEST_ALL );
01404 std::multimap<double, unsigned int> hcalAssoTrack;
01405 block.associatedElements( track_index,linkData,
01406 hcalAssoTrack,
01407 reco::PFBlockElement::HCAL,
01408 reco::PFBlock::LINKTEST_ALL );
01409 if(ecalAssoTrack.size() > 0) {
01410 for(std::multimap<double, unsigned int>::iterator itecal = ecalAssoTrack.begin();
01411 itecal != ecalAssoTrack.end(); ++itecal) {
01412 linked_e=linked_e+elements[itecal->second].clusterRef()->energy();
01413 }
01414 }
01415 if(hcalAssoTrack.size() > 0) {
01416 for(std::multimap<double, unsigned int>::iterator ithcal = hcalAssoTrack.begin();
01417 ithcal != hcalAssoTrack.end(); ++ithcal) {
01418 linked_h=linked_h+elements[ithcal->second].clusterRef()->energy();
01419 }
01420 }
01421 EoverPt=linked_e/elements[track_index].trackRef()->pt();
01422 HoverPt=linked_h/elements[track_index].trackRef()->pt();
01423 GlobalVector rvtx(elements[track_index].trackRef()->innerPosition().X()-primaryvtx.x(),
01424 elements[track_index].trackRef()->innerPosition().Y()-primaryvtx.y(),
01425 elements[track_index].trackRef()->innerPosition().Z()-primaryvtx.z());
01426 double vtx_phi=rvtx.phi();
01427
01428 del_phi=fabs(deltaPhi(vtx_phi, elements[track_index].trackRef()->innerMomentum().Phi()));
01429 mvaValue = tmvaReader_->EvaluateMVA("BDT");
01430 if(mvaValue > MVACUT)convtkfound=true;
01431 return convtkfound;
01432 }
01433
01434
01435 void PFEGammaAlgo::EarlyConversion(
01436
01437
01438 std::vector<reco::PFCandidate>&
01439 tempElectronCandidates,
01440 const reco::PFBlockElementSuperCluster* sc
01441 ){
01442
01443
01444 int count=0;
01445 for ( std::vector<reco::PFCandidate>::const_iterator ec=tempElectronCandidates.begin(); ec != tempElectronCandidates.end(); ++ec )
01446 {
01447
01448 int mh=ec->gsfTrackRef()->trackerExpectedHitsInner().numberOfLostHits();
01449
01450
01451 reco::GsfTrackRef gsf=ec->gsfTrackRef();
01452
01453
01454 if(gsf->extra().isAvailable() && gsf->extra()->seedRef().isAvailable() && mh>0)
01455 {
01456 reco::ElectronSeedRef seedRef= gsf->extra()->seedRef().castTo<reco::ElectronSeedRef>();
01457 if(seedRef.isAvailable() && seedRef->isEcalDriven())
01458 {
01459 reco::SuperClusterRef ElecscRef = seedRef->caloCluster().castTo<reco::SuperClusterRef>();
01460
01461 if(ElecscRef.isNonnull()){
01462
01463 reco::SuperClusterRef PhotscRef=sc->superClusterRef();
01464 if(PhotscRef==ElecscRef)
01465 {
01466 match_ind.push_back(count);
01467
01468
01469
01470 reco::PFCandidate::ElementsInBlocks eleInBlocks = ec->elementsInBlocks();
01471 for(unsigned i=0; i<eleInBlocks.size(); i++)
01472 {
01473 reco::PFBlockRef blockRef = eleInBlocks[i].first;
01474 unsigned indexInBlock = eleInBlocks[i].second;
01475
01476
01477
01478 AddFromElectron_.push_back(indexInBlock);
01479 }
01480 }
01481 }
01482 }
01483 }
01484 count++;
01485 }
01486 }
01487
01488 bool PFEGammaAlgo::SetLinks(const reco::PFBlockRef& blockRef,
01489 AssMap& associatedToGsf_,
01490 AssMap& associatedToBrems_,
01491 AssMap& associatedToEcal_,
01492 std::vector<bool>& active,
01493 const reco::Vertex & primaryVertex) {
01494 unsigned int CutIndex = 100000;
01495 double CutGSFECAL = 10000. ;
01496
01497
01498 bool DebugSetLinksSummary = false;
01499 bool DebugSetLinksDetailed = false;
01500
01501 const reco::PFBlock& block = *blockRef;
01502 const edm::OwnVector< reco::PFBlockElement >& elements = block.elements();
01503 PFBlock::LinkData linkData = block.linkData();
01504
01505 bool IsThereAGSFTrack = false;
01506 bool IsThereAGoodGSFTrack = false;
01507
01508 vector<unsigned int> trackIs(0);
01509 vector<unsigned int> gsfIs(0);
01510 vector<unsigned int> ecalIs(0);
01511
01512 std::vector<bool> localactive(elements.size(),true);
01513
01514
01515
01516 std::multimap<double, unsigned int> kfElems;
01517 for(unsigned int iEle=0; iEle<elements.size(); iEle++) {
01518 localactive[iEle] = active[iEle];
01519 bool thisIsAMuon = false;
01520 PFBlockElement::Type type = elements[iEle].type();
01521 switch( type ) {
01522 case PFBlockElement::TRACK:
01523
01524 thisIsAMuon = PFMuonAlgo::isMuon(elements[iEle]);
01525
01526 if ( !thisIsAMuon && active[iEle] ) {
01527 trackIs.push_back( iEle );
01528 if (DebugSetLinksDetailed)
01529 cout<<"TRACK, stored index, continue "<< iEle << endl;
01530 }
01531 continue;
01532 case PFBlockElement::GSF:
01533
01534 block.associatedElements( iEle,linkData,
01535 kfElems,
01536 reco::PFBlockElement::TRACK,
01537 reco::PFBlock::LINKTEST_ALL );
01538 thisIsAMuon = kfElems.size() ?
01539 PFMuonAlgo::isMuon(elements[kfElems.begin()->second]) : false;
01540
01541 if ( !thisIsAMuon && active[iEle] ) {
01542 IsThereAGSFTrack = true;
01543 gsfIs.push_back( iEle );
01544 if (DebugSetLinksDetailed)
01545 cout<<"GSF, stored index, continue "<< iEle << endl;
01546 }
01547 continue;
01548 case PFBlockElement::ECAL:
01549 if ( active[iEle] ) {
01550 ecalIs.push_back( iEle );
01551 if (DebugSetLinksDetailed)
01552 cout<<"ECAL, stored index, continue "<< iEle << endl;
01553 }
01554 continue;
01555 default:
01556 continue;
01557 }
01558 }
01559
01560
01561 if(IsThereAGSFTrack) {
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572 if (DebugSetLinksDetailed) {
01573 cout<<"#########################################################"<<endl;
01574 cout<<"##### Process Block: #####"<<endl;
01575 cout<<"#########################################################"<<endl;
01576 cout<<block<<endl;
01577 }
01578
01579
01580 for(unsigned int iEle=0; iEle<trackIs.size(); iEle++) {
01581 std::multimap<double, unsigned int> gsfElems;
01582 block.associatedElements( trackIs[iEle], linkData,
01583 gsfElems ,
01584 reco::PFBlockElement::GSF,
01585 reco::PFBlock::LINKTEST_ALL );
01586 if(gsfElems.size() == 0){
01587
01588
01589 std::multimap<double, unsigned int> ecalKfElems;
01590 block.associatedElements( trackIs[iEle],linkData,
01591 ecalKfElems,
01592 reco::PFBlockElement::ECAL,
01593 reco::PFBlock::LINKTEST_ALL );
01594 if(ecalKfElems.size() > 0) {
01595 unsigned int ecalKf_index = ecalKfElems.begin()->second;
01596 if(localactive[ecalKf_index]==true) {
01597
01598
01599
01600 bool isGsfLinked = false;
01601 for(unsigned int iGsf=0; iGsf<gsfIs.size(); iGsf++) {
01602
01603
01604
01605 const reco::PFBlockElementGsfTrack * GsfEl =
01606 dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[gsfIs[iGsf]]));
01607 if(GsfEl->trackType(reco::PFBlockElement::T_FROM_GAMMACONV)) continue;
01608
01609 std::multimap<double, unsigned int> ecalGsfElems;
01610 block.associatedElements( gsfIs[iGsf],linkData,
01611 ecalGsfElems,
01612 reco::PFBlockElement::ECAL,
01613 reco::PFBlock::LINKTEST_ALL );
01614 if(ecalGsfElems.size() > 0) {
01615 if (ecalGsfElems.begin()->second == ecalKf_index) {
01616 isGsfLinked = true;
01617 }
01618 }
01619 }
01620 if(isGsfLinked == false) {
01621
01622
01623 const reco::PFBlockElementTrack * kfEle =
01624 dynamic_cast<const reco::PFBlockElementTrack*>((&elements[(trackIs[iEle])]));
01625 reco::TrackRef refKf = kfEle->trackRef();
01626
01627 int nexhits = refKf->trackerExpectedHitsInner().numberOfLostHits();
01628
01629 unsigned int Algo = 0;
01630 if (refKf.isNonnull())
01631 Algo = refKf->algo();
01632
01633 bool trackIsFromPrimaryVertex = false;
01634 for (Vertex::trackRef_iterator trackIt = primaryVertex.tracks_begin(); trackIt != primaryVertex.tracks_end(); ++trackIt) {
01635 if ( (*trackIt).castTo<TrackRef>() == refKf ) {
01636 trackIsFromPrimaryVertex = true;
01637 break;
01638 }
01639 }
01640
01641 if(Algo < 9 && nexhits == 0 && trackIsFromPrimaryVertex) {
01642 localactive[ecalKf_index] = false;
01643 } else {
01644 fifthStepKfTrack_.push_back(make_pair(ecalKf_index,trackIs[iEle]));
01645 }
01646 }
01647 }
01648 }
01649 }
01650 }
01651
01652
01653
01654 for(unsigned int iEle=0; iEle<gsfIs.size(); iEle++) {
01655
01656 if (!localactive[(gsfIs[iEle])]) continue;
01657
01658 localactive[gsfIs[iEle]] = false;
01659 bool ClosestEcalWithKf = false;
01660
01661 if (DebugSetLinksDetailed) cout << " Gsf Index " << gsfIs[iEle] << endl;
01662
01663 const reco::PFBlockElementGsfTrack * GsfEl =
01664 dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[(gsfIs[iEle])]));
01665
01666
01667 if(GsfEl->trackType(reco::PFBlockElement::T_FROM_GAMMACONV)) continue;
01668 IsThereAGoodGSFTrack = true;
01669 float eta_gsf = GsfEl->positionAtECALEntrance().eta();
01670 float etaOut_gsf = GsfEl->Pout().eta();
01671 float diffOutEcalEta = fabs(eta_gsf-etaOut_gsf);
01672 reco::GsfTrackRef RefGSF = GsfEl->GsftrackRef();
01673 float Pin_gsf = 0.01;
01674 if (RefGSF.isNonnull() )
01675 Pin_gsf = RefGSF->pMode();
01676
01677
01678
01679 unsigned int KfGsf_index = CutIndex;
01680 unsigned int KfGsf_secondIndex = CutIndex;
01681 std::multimap<double, unsigned int> kfElems;
01682 block.associatedElements( gsfIs[iEle],linkData,
01683 kfElems,
01684 reco::PFBlockElement::TRACK,
01685 reco::PFBlock::LINKTEST_ALL );
01686 std::multimap<double, unsigned int> ecalKfElems;
01687 if (kfElems.size() > 0) {
01688
01689
01690
01691 for(std::multimap<double, unsigned int>::iterator itkf = kfElems.begin();
01692 itkf != kfElems.end(); ++itkf) {
01693 const reco::PFBlockElementTrack * TrkEl =
01694 dynamic_cast<const reco::PFBlockElementTrack*>((&elements[itkf->second]));
01695
01696 bool isPrim = isPrimaryTrack(*TrkEl,*GsfEl);
01697 if(!isPrim)
01698 continue;
01699
01700 if(localactive[itkf->second] == true) {
01701
01702 KfGsf_index = itkf->second;
01703 localactive[KfGsf_index] = false;
01704
01705 block.associatedElements( KfGsf_index, linkData,
01706 ecalKfElems ,
01707 reco::PFBlockElement::ECAL,
01708 reco::PFBlock::LINKTEST_ALL );
01709 }
01710 else {
01711 KfGsf_secondIndex = itkf->second;
01712 }
01713 }
01714 }
01715
01716
01717 std::multimap<double, unsigned int> ecalGsfElems;
01718 block.associatedElements( gsfIs[iEle],linkData,
01719 ecalGsfElems,
01720 reco::PFBlockElement::ECAL,
01721 reco::PFBlock::LINKTEST_ALL );
01722 double ecalGsf_dist = CutGSFECAL;
01723 unsigned int ClosestEcalGsf_index = CutIndex;
01724 if (ecalGsfElems.size() > 0) {
01725 if(localactive[(ecalGsfElems.begin()->second)] == true) {
01726
01727 bool compatibleEPout = true;
01728 if(diffOutEcalEta > 0.3) {
01729 reco::PFClusterRef clusterRef = elements[(ecalGsfElems.begin()->second)].clusterRef();
01730 float EoPout = (clusterRef->energy())/(GsfEl->Pout().t());
01731 if(EoPout > 5)
01732 compatibleEPout = false;
01733 }
01734 if(compatibleEPout) {
01735 ClosestEcalGsf_index = ecalGsfElems.begin()->second;
01736 ecalGsf_dist = block.dist(gsfIs[iEle],ClosestEcalGsf_index,
01737 linkData,reco::PFBlock::LINKTEST_ALL);
01738
01739
01740
01741 std::multimap<double, unsigned int> ecalOtherGsfElems;
01742 block.associatedElements( ClosestEcalGsf_index,linkData,
01743 ecalOtherGsfElems,
01744 reco::PFBlockElement::GSF,
01745 reco::PFBlock::LINKTEST_ALL);
01746
01747 if(ecalOtherGsfElems.size()>0) {
01748
01749 const reco::PFBlockElementGsfTrack * gsfCheck =
01750 dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[ecalOtherGsfElems.begin()->second]));
01751
01752 if(ecalOtherGsfElems.begin()->second != gsfIs[iEle]&&
01753 gsfCheck->trackType(reco::PFBlockElement::T_FROM_GAMMACONV) == false) {
01754 ecalGsf_dist = CutGSFECAL;
01755 ClosestEcalGsf_index = CutIndex;
01756 }
01757 }
01758 }
01759
01760 }
01761 }
01762
01763 else if(ecalKfElems.size() > 0) {
01764 if(localactive[(ecalKfElems.begin()->second)] == true) {
01765 ClosestEcalGsf_index = ecalKfElems.begin()->second;
01766 ecalGsf_dist = block.dist(gsfIs[iEle],ClosestEcalGsf_index,
01767 linkData,reco::PFBlock::LINKTEST_ALL);
01768 ClosestEcalWithKf = true;
01769
01770
01771 std::multimap<double, unsigned int> ecalOtherGsfElems;
01772 block.associatedElements( ClosestEcalGsf_index,linkData,
01773 ecalOtherGsfElems,
01774 reco::PFBlockElement::GSF,
01775 reco::PFBlock::LINKTEST_ALL);
01776 if(ecalOtherGsfElems.size() > 0) {
01777 const reco::PFBlockElementGsfTrack * gsfCheck =
01778 dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[ecalOtherGsfElems.begin()->second]));
01779
01780 if(ecalOtherGsfElems.begin()->second != gsfIs[iEle] &&
01781 gsfCheck->trackType(reco::PFBlockElement::T_FROM_GAMMACONV) == false) {
01782 ecalGsf_dist = CutGSFECAL;
01783 ClosestEcalGsf_index = CutIndex;
01784 ClosestEcalWithKf = false;
01785 }
01786 }
01787 }
01788 }
01789
01790 if (DebugSetLinksDetailed)
01791 cout << " Closest Ecal to the Gsf/Kf: index " << ClosestEcalGsf_index
01792 << " dist " << ecalGsf_dist << endl;
01793
01794
01795
01796
01797 std::multimap<double, unsigned int> bremElems;
01798 block.associatedElements( gsfIs[iEle],linkData,
01799 bremElems,
01800 reco::PFBlockElement::BREM,
01801 reco::PFBlock::LINKTEST_ALL );
01802
01803
01804 multimap<unsigned int,unsigned int> cleanedEcalBremElems;
01805 vector<unsigned int> keyBremIndex(0);
01806 unsigned int latestBrem_trajP = 0;
01807 unsigned int latestBrem_index = CutIndex;
01808 for(std::multimap<double, unsigned int>::iterator ieb = bremElems.begin();
01809 ieb != bremElems.end(); ++ieb ) {
01810 unsigned int brem_index = ieb->second;
01811 if(localactive[brem_index] == false) continue;
01812
01813
01814
01815 std::multimap<double, unsigned int> ecalBremsElems;
01816
01817 block.associatedElements( brem_index, linkData,
01818 ecalBremsElems,
01819 reco::PFBlockElement::ECAL,
01820 reco::PFBlock::LINKTEST_ALL );
01821
01822 for (std::multimap<double, unsigned int>::iterator ie = ecalBremsElems.begin();
01823 ie != ecalBremsElems.end();ie++) {
01824 unsigned int ecalBrem_index = ie->second;
01825 if(localactive[ecalBrem_index] == false) continue;
01826
01827
01828 float ecalBrem_dist = block.dist(brem_index,ecalBrem_index,
01829 linkData,reco::PFBlock::LINKTEST_ALL);
01830
01831
01832 if (ecalBrem_index == ClosestEcalGsf_index && (ecalBrem_dist + 0.0012) > ecalGsf_dist) continue;
01833
01834
01835 std::multimap<double, unsigned int> sortedBremElems;
01836 block.associatedElements( ecalBrem_index,linkData,
01837 sortedBremElems,
01838 reco::PFBlockElement::BREM,
01839 reco::PFBlock::LINKTEST_ALL);
01840
01841 bool isGoodBrem = false;
01842 unsigned int sortedBrem_index = CutIndex;
01843 for (std::multimap<double, unsigned int>::iterator ibs = sortedBremElems.begin();
01844 ibs != sortedBremElems.end();ibs++) {
01845 unsigned int temp_sortedBrem_index = ibs->second;
01846 std::multimap<double, unsigned int> sortedGsfElems;
01847 block.associatedElements( temp_sortedBrem_index,linkData,
01848 sortedGsfElems,
01849 reco::PFBlockElement::GSF,
01850 reco::PFBlock::LINKTEST_ALL);
01851 bool enteredInPrimaryGsf = false;
01852 for (std::multimap<double, unsigned int>::iterator igs = sortedGsfElems.begin();
01853 igs != sortedGsfElems.end();igs++) {
01854 const reco::PFBlockElementGsfTrack * gsfCheck =
01855 dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[igs->second]));
01856
01857 if(gsfCheck->trackType(reco::PFBlockElement::T_FROM_GAMMACONV) == false) {
01858 if(igs->second == gsfIs[iEle]) {
01859 isGoodBrem = true;
01860 sortedBrem_index = temp_sortedBrem_index;
01861 }
01862 enteredInPrimaryGsf = true;
01863 break;
01864 }
01865 }
01866 if(enteredInPrimaryGsf)
01867 break;
01868 }
01869
01870 if(isGoodBrem) {
01871
01872
01873
01874 std::multimap<double, unsigned int> ecalOtherGsfElems;
01875 block.associatedElements( ecalBrem_index,linkData,
01876 ecalOtherGsfElems,
01877 reco::PFBlockElement::GSF,
01878 reco::PFBlock::LINKTEST_ALL);
01879 if (ecalOtherGsfElems.size() > 0) {
01880 const reco::PFBlockElementGsfTrack * gsfCheck =
01881 dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[ecalOtherGsfElems.begin()->second]));
01882 if(ecalOtherGsfElems.begin()->second != gsfIs[iEle] &&
01883 gsfCheck->trackType(reco::PFBlockElement::T_FROM_GAMMACONV) == false) {
01884 continue;
01885 }
01886 }
01887
01888 const reco::PFBlockElementBrem * BremEl =
01889 dynamic_cast<const reco::PFBlockElementBrem*>((&elements[sortedBrem_index]));
01890
01891 reco::PFClusterRef clusterRef =
01892 elements[ecalBrem_index].clusterRef();
01893
01894
01895 float sortedBremEcal_deta = fabs(clusterRef->position().eta() - BremEl->positionAtECALEntrance().eta());
01896
01897
01898 if(sortedBremEcal_deta < 0.015) {
01899
01900 cleanedEcalBremElems.insert(pair<unsigned int,unsigned int>(sortedBrem_index,ecalBrem_index));
01901
01902 unsigned int BremTrajP = BremEl->indTrajPoint();
01903 if (BremTrajP > latestBrem_trajP) {
01904 latestBrem_trajP = BremTrajP;
01905 latestBrem_index = sortedBrem_index;
01906 }
01907 if (DebugSetLinksDetailed)
01908 cout << " brem Index " << sortedBrem_index
01909 << " associated cluster " << ecalBrem_index << " BremTrajP " << BremTrajP <<endl;
01910
01911
01912
01913
01914 localactive[ecalBrem_index] = false;
01915 bool alreadyfound = false;
01916 for(unsigned int ii=0;ii<keyBremIndex.size();ii++) {
01917 if (sortedBrem_index == keyBremIndex[ii]) alreadyfound = true;
01918 }
01919 if (alreadyfound == false) {
01920 keyBremIndex.push_back(sortedBrem_index);
01921 localactive[sortedBrem_index] = false;
01922 }
01923 }
01924 }
01925 }
01926 }
01927
01928
01929
01930 vector<unsigned int> GsfElemIndex(0);
01931 vector<unsigned int> EcalIndex(0);
01932
01933
01934 if (ClosestEcalGsf_index < CutIndex) {
01935 GsfElemIndex.push_back(ClosestEcalGsf_index);
01936 localactive[ClosestEcalGsf_index] = false;
01937 for (std::multimap<double, unsigned int>::iterator ii = ecalGsfElems.begin();
01938 ii != ecalGsfElems.end();ii++) {
01939 if(localactive[ii->second]) {
01940
01941 std::multimap<double, unsigned int> ecalOtherGsfElems;
01942 block.associatedElements( ii->second,linkData,
01943 ecalOtherGsfElems,
01944 reco::PFBlockElement::GSF,
01945 reco::PFBlock::LINKTEST_ALL);
01946 if(ecalOtherGsfElems.size()) {
01947 if(ecalOtherGsfElems.begin()->second != gsfIs[iEle]) continue;
01948 }
01949
01950
01951 reco::PFClusterRef clusterRef = elements[(ii->second)].clusterRef();
01952 float etacl = clusterRef->eta();
01953 if( fabs(eta_gsf-etacl) < 0.05) {
01954 GsfElemIndex.push_back(ii->second);
01955 localactive[ii->second] = false;
01956 if (DebugSetLinksDetailed)
01957 cout << " ExtraCluster From Gsf " << ii->second << endl;
01958 }
01959 }
01960 }
01961 }
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994 if(GsfElemIndex.size() == 0){
01995 if(latestBrem_index < CutIndex) {
01996 unsigned int ckey = cleanedEcalBremElems.count(latestBrem_index);
01997 if(ckey == 1) {
01998 unsigned int temp_cal =
01999 cleanedEcalBremElems.find(latestBrem_index)->second;
02000 GsfElemIndex.push_back(temp_cal);
02001 if (DebugSetLinksDetailed)
02002 cout << "******************** Gsf Cluster From Brem " << temp_cal
02003 << " Latest Brem index " << latestBrem_index
02004 << " ************************* " << endl;
02005 }
02006 else{
02007 pair<multimap<unsigned int,unsigned int>::iterator,multimap<unsigned int,unsigned int>::iterator> ret;
02008 ret = cleanedEcalBremElems.equal_range(latestBrem_index);
02009 multimap<unsigned int,unsigned int>::iterator it;
02010 for(it=ret.first; it!=ret.second; ++it) {
02011 GsfElemIndex.push_back((*it).second);
02012 if (DebugSetLinksDetailed)
02013 cout << "******************** Gsf Cluster From Brem " << (*it).second
02014 << " Latest Brem index " << latestBrem_index
02015 << " ************************* " << endl;
02016 }
02017 }
02018
02019 unsigned int elToErase = 0;
02020 for(unsigned int i = 0; i<keyBremIndex.size();i++) {
02021 if(latestBrem_index == keyBremIndex[i]) {
02022 elToErase = i;
02023 }
02024 }
02025 keyBremIndex.erase(keyBremIndex.begin()+elToErase);
02026 }
02027 }
02028
02029
02030
02031
02032
02033 for(unsigned int iConv=0; iConv<gsfIs.size(); iConv++) {
02034 if(iConv != iEle) {
02035
02036 const reco::PFBlockElementGsfTrack * gsfConv =
02037 dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[(gsfIs[iConv])]));
02038
02039
02040 if(gsfConv->trackType(reco::PFBlockElement::T_FROM_GAMMACONV)){
02041 if (DebugSetLinksDetailed)
02042 cout << " PFElectronAlgo:: I'm running on convGsfBrem " << endl;
02043
02044 float conv_dist = block.dist(gsfIs[iConv],gsfIs[iEle],
02045 linkData,reco::PFBlock::LINKTEST_ALL);
02046 if(conv_dist > 0.) {
02047
02048
02049 std::multimap<double, unsigned int> ecalConvElems;
02050 block.associatedElements( gsfIs[iConv],linkData,
02051 ecalConvElems,
02052 reco::PFBlockElement::ECAL,
02053 reco::PFBlock::LINKTEST_ALL );
02054 if(ecalConvElems.size() > 0) {
02055
02056 if(localactive[(ecalConvElems.begin()->second)] == true) {
02057 if (DebugSetLinksDetailed)
02058 cout << " PFElectronAlgo:: convGsfBrem has a ECAL cluster linked and free" << endl;
02059
02060 std::multimap<double, unsigned int> ecalOtherGsfPrimElems;
02061 block.associatedElements( ecalConvElems.begin()->second,linkData,
02062 ecalOtherGsfPrimElems,
02063 reco::PFBlockElement::GSF,
02064 reco::PFBlock::LINKTEST_ALL);
02065 if(ecalOtherGsfPrimElems.size()>0) {
02066 unsigned int gsfprimcheck_index = ecalOtherGsfPrimElems.begin()->second;
02067 const reco::PFBlockElementGsfTrack * gsfCheck =
02068 dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[gsfprimcheck_index]));
02069 if(gsfCheck->trackType(reco::PFBlockElement::T_FROM_GAMMACONV) == false) continue;
02070
02071 reco::PFClusterRef clusterRef = elements[ecalConvElems.begin()->second].clusterRef();
02072 if (DebugSetLinksDetailed)
02073 cout << " PFElectronAlgo: !!!!!!! convGsfBrem ECAL cluster has been stored !!!!!!! "
02074 << " Energy " << clusterRef->energy() << " eta,phi " << clusterRef->position().eta()
02075 <<", " << clusterRef->position().phi() << endl;
02076
02077 GsfElemIndex.push_back(ecalConvElems.begin()->second);
02078 convGsfTrack_.push_back(make_pair(ecalConvElems.begin()->second,gsfIs[iConv]));
02079 localactive[ecalConvElems.begin()->second] = false;
02080
02081 }
02082 }
02083 }
02084 }
02085 }
02086 }
02087 }
02088
02089
02090
02091 EcalIndex.insert(EcalIndex.end(),GsfElemIndex.begin(),GsfElemIndex.end());
02092
02093
02094
02095
02096 for(unsigned int i =0;i<keyBremIndex.size();i++) {
02097 unsigned int ikey = keyBremIndex[i];
02098 unsigned int ckey = cleanedEcalBremElems.count(ikey);
02099 vector<unsigned int> BremElemIndex(0);
02100 if(ckey == 1) {
02101 unsigned int temp_cal =
02102 cleanedEcalBremElems.find(ikey)->second;
02103 BremElemIndex.push_back(temp_cal);
02104 }
02105 else{
02106 pair<multimap<unsigned int,unsigned int>::iterator,multimap<unsigned int,unsigned int>::iterator> ret;
02107 ret = cleanedEcalBremElems.equal_range(ikey);
02108 multimap<unsigned int,unsigned int>::iterator it;
02109 for(it=ret.first; it!=ret.second; ++it) {
02110 BremElemIndex.push_back((*it).second);
02111 }
02112 }
02113 EcalIndex.insert(EcalIndex.end(),BremElemIndex.begin(),BremElemIndex.end());
02114 associatedToBrems_.insert(pair<unsigned int,vector<unsigned int> >(ikey,BremElemIndex));
02115 }
02116
02117
02118
02119 vector<unsigned int> convBremKFTrack;
02120 convBremKFTrack.clear();
02121 if (kfElems.size() > 0) {
02122 for(std::multimap<double, unsigned int>::iterator itkf = kfElems.begin();
02123 itkf != kfElems.end(); ++itkf) {
02124 const reco::PFBlockElementTrack * TrkEl =
02125 dynamic_cast<const reco::PFBlockElementTrack*>((&elements[itkf->second]));
02126 bool isPrim = isPrimaryTrack(*TrkEl,*GsfEl);
02127
02128 if(!isPrim) {
02129
02130
02131 std::multimap<double, unsigned int> ecalConvElems;
02132 block.associatedElements( itkf->second,linkData,
02133 ecalConvElems,
02134 reco::PFBlockElement::ECAL,
02135 reco::PFBlock::LINKTEST_ALL );
02136 if(ecalConvElems.size() > 0) {
02137
02138 TrackRef trkRef = TrkEl->trackRef();
02139
02140 unsigned int Algo = whichTrackAlgo(trkRef);
02141
02142 float secpin = trkRef->p();
02143
02144 const reco::PFBlockElementCluster * clust =
02145 dynamic_cast<const reco::PFBlockElementCluster*>((&elements[(ecalConvElems.begin()->second)]));
02146 float eneclust =clust->clusterRef()->energy();
02147
02148
02149
02150
02151
02152 std::multimap<double, unsigned int> hcalConvElems;
02153 block.associatedElements( itkf->second,linkData,
02154 hcalConvElems,
02155 reco::PFBlockElement::HCAL,
02156 reco::PFBlock::LINKTEST_ALL );
02157
02158 bool isHoHE = false;
02159 bool isHoE = false;
02160 bool isPoHE = false;
02161
02162 float enehcalclust = -1;
02163 if(hcalConvElems.size() > 0) {
02164 const reco::PFBlockElementCluster * clusthcal =
02165 dynamic_cast<const reco::PFBlockElementCluster*>((&elements[(hcalConvElems.begin()->second)]));
02166 enehcalclust =clusthcal->clusterRef()->energy();
02167
02168 if( (enehcalclust / (enehcalclust+eneclust) ) > 0.1 && Algo < 3) {
02169 isHoHE = true;
02170 if(enehcalclust > eneclust)
02171 isHoE = true;
02172 if(secpin > (enehcalclust+eneclust) )
02173 isPoHE = true;
02174 }
02175 }
02176
02177
02178 if(localactive[(ecalConvElems.begin()->second)] == false) {
02179
02180 if(isHoE || isPoHE) {
02181 if (DebugSetLinksDetailed)
02182 cout << "PFElectronAlgo:: LOCKED ECAL REJECTED TRACK FOR H/E or P/(H+E) "
02183 << " H/H+E " << enehcalclust/(enehcalclust+eneclust)
02184 << " H/E " << enehcalclust/eneclust
02185 << " P/(H+E) " << secpin/(enehcalclust+eneclust)
02186 << " HCAL ENE " << enehcalclust
02187 << " ECAL ENE " << eneclust
02188 << " secPIN " << secpin
02189 << " Algo Track " << Algo << endl;
02190 continue;
02191 }
02192
02193
02194 for(unsigned int iecal =0; iecal < EcalIndex.size(); iecal++) {
02195
02196
02197 if(EcalIndex[iecal] == ecalConvElems.begin()->second) {
02198 if (DebugSetLinksDetailed)
02199 cout << " PFElectronAlgo:: Conv Brem Recovery locked cluster and I will lock also the KF track " << endl;
02200 convBremKFTrack.push_back(itkf->second);
02201 }
02202 }
02203 }
02204 else{
02205
02206
02207
02208 if(isHoHE){
02209 if (DebugSetLinksDetailed)
02210 cout << "PFElectronAlgo:: FREE ECAL REJECTED TRACK FOR H/H+E "
02211 << " H/H+E " << (enehcalclust / (enehcalclust+eneclust) )
02212 << " H/E " << enehcalclust/eneclust
02213 << " P/(H+E) " << secpin/(enehcalclust+eneclust)
02214 << " HCAL ENE " << enehcalclust
02215 << " ECAL ENE " << eneclust
02216 << " secPIN " << secpin
02217 << " Algo Track " << Algo << endl;
02218 continue;
02219 }
02220
02221
02222 std::multimap<double, unsigned int> ecalOtherKFPrimElems;
02223 block.associatedElements( ecalConvElems.begin()->second,linkData,
02224 ecalOtherKFPrimElems,
02225 reco::PFBlockElement::TRACK,
02226 reco::PFBlock::LINKTEST_ALL);
02227 if(ecalOtherKFPrimElems.size() > 0) {
02228
02229
02230
02231 bool isFromGSF = false;
02232 for(std::multimap<double, unsigned int>::iterator itclos = kfElems.begin();
02233 itclos != kfElems.end(); ++itclos) {
02234 if(ecalOtherKFPrimElems.begin()->second == itclos->second) {
02235 isFromGSF = true;
02236 break;
02237 }
02238 }
02239 if(isFromGSF){
02240
02241
02242
02243
02244 float Epin = eneclust/secpin;
02245
02246
02247 float totenergy = 0.;
02248 for(unsigned int ikeyecal = 0;
02249 ikeyecal<EcalIndex.size(); ikeyecal++){
02250
02251 bool foundcluster = false;
02252 if(ikeyecal > 0) {
02253 for(unsigned int i2 = 0; i2<ikeyecal-1; i2++) {
02254 if(EcalIndex[ikeyecal] == EcalIndex[i2])
02255 foundcluster = true;
02256 }
02257 }
02258 if(foundcluster) continue;
02259 const reco::PFBlockElementCluster * clusasso =
02260 dynamic_cast<const reco::PFBlockElementCluster*>((&elements[(EcalIndex[ikeyecal])]));
02261 totenergy += clusasso->clusterRef()->energy();
02262 }
02263
02264
02265
02266 if(totenergy == 0.) {
02267 if (DebugSetLinksDetailed)
02268 cout << "PFElectronAlgo:: REJECTED_NULLTOT totenergy " << totenergy << endl;
02269 continue;
02270 }
02271
02272
02273 if(Epin > 3) {
02274 double res_before = fabs((totenergy-Pin_gsf)/Pin_gsf);
02275 double res_after = fabs(((totenergy+eneclust)-Pin_gsf)/Pin_gsf);
02276
02277 if(res_before < res_after) {
02278 if (DebugSetLinksDetailed)
02279 cout << "PFElectronAlgo::REJECTED_RES totenergy " << totenergy << " Pin_gsf " << Pin_gsf << " cluster to secondary " << eneclust
02280 << " Res before " << res_before << " res_after " << res_after << endl;
02281 continue;
02282 }
02283 }
02284
02285 if (DebugSetLinksDetailed)
02286 cout << "PFElectronAlgo:: conv brem found asso to ECAL linked to a secondary KF " << endl;
02287 convBremKFTrack.push_back(itkf->second);
02288 GsfElemIndex.push_back(ecalConvElems.begin()->second);
02289 EcalIndex.push_back(ecalConvElems.begin()->second);
02290 localactive[(ecalConvElems.begin()->second)] = false;
02291 localactive[(itkf->second)] = false;
02292 }
02293 }
02294 }
02295 }
02296 }
02297 }
02298 }
02299
02300
02301 if(EcalIndex.size() > 0 && useEGammaSupercluster_) {
02302 double sumEtEcalInTheCone = 0.;
02303
02304
02305 const reco::PFBlockElementCluster * clust =
02306 dynamic_cast<const reco::PFBlockElementCluster*>((&elements[EcalIndex[0]]));
02307 double PhiFC = clust->clusterRef()->position().Phi();
02308 double EtaFC = clust->clusterRef()->position().Eta();
02309
02310
02311 for(unsigned int iEcal=0; iEcal<ecalIs.size(); iEcal++) {
02312 bool foundcluster = false;
02313 for(unsigned int ikeyecal = 0;
02314 ikeyecal<EcalIndex.size(); ikeyecal++){
02315 if(ecalIs[iEcal] == EcalIndex[ikeyecal])
02316 foundcluster = true;
02317 }
02318
02319
02320 if(foundcluster == false) {
02321 const reco::PFBlockElementCluster * clustExt =
02322 dynamic_cast<const reco::PFBlockElementCluster*>((&elements[ecalIs[iEcal]]));
02323 double eta_clust = clustExt->clusterRef()->position().Eta();
02324 double phi_clust = clustExt->clusterRef()->position().Phi();
02325 double theta_clust = clustExt->clusterRef()->position().Theta();
02326 double deta_clust = eta_clust - EtaFC;
02327 double dphi_clust = phi_clust - PhiFC;
02328 if ( dphi_clust < -M_PI )
02329 dphi_clust = dphi_clust + 2.*M_PI;
02330 else if ( dphi_clust > M_PI )
02331 dphi_clust = dphi_clust - 2.*M_PI;
02332 double DR = sqrt(deta_clust*deta_clust+
02333 dphi_clust*dphi_clust);
02334
02335
02336 if(fabs(deta_clust) > 0.05 && DR < coneEcalIsoForEgammaSC_) {
02337 vector<double> ps1Ene(0);
02338 vector<double> ps2Ene(0);
02339 double ps1,ps2;
02340 ps1=ps2=0.;
02341 double EE_calib = thePFEnergyCalibration_->energyEm(*(clustExt->clusterRef()),ps1Ene,ps2Ene,ps1,ps2,applyCrackCorrections_);
02342 double ET_calib = EE_calib*sin(theta_clust);
02343 sumEtEcalInTheCone += ET_calib;
02344 }
02345 }
02346 }
02347
02348
02349 unsigned int sumNTracksInTheCone = 0;
02350 double sumPtTracksInTheCone = 0.;
02351 for(unsigned int iTrack=0; iTrack<trackIs.size(); iTrack++) {
02352
02353 if(localactive[(trackIs[iTrack])]==true) {
02354 const reco::PFBlockElementTrack * kfEle =
02355 dynamic_cast<const reco::PFBlockElementTrack*>((&elements[(trackIs[iTrack])]));
02356 reco::TrackRef trkref = kfEle->trackRef();
02357 if (trkref.isNonnull()) {
02358 double deta_trk = trkref->eta() - RefGSF->etaMode();
02359 double dphi_trk = trkref->phi() - RefGSF->phiMode();
02360 if ( dphi_trk < -M_PI )
02361 dphi_trk = dphi_trk + 2.*M_PI;
02362 else if ( dphi_trk > M_PI )
02363 dphi_trk = dphi_trk - 2.*M_PI;
02364 double DR = sqrt(deta_trk*deta_trk+
02365 dphi_trk*dphi_trk);
02366
02367 reco::HitPattern kfHitPattern = trkref->hitPattern();
02368 int NValPixelHit = kfHitPattern.numberOfValidPixelHits();
02369
02370 if(DR < coneTrackIsoForEgammaSC_ && NValPixelHit >=3) {
02371 sumNTracksInTheCone++;
02372 sumPtTracksInTheCone+=trkref->pt();
02373 }
02374 }
02375 }
02376 }
02377
02378
02379 bool isBarrelIsolated = false;
02380 if( fabs(EtaFC < 1.478) &&
02381 (sumEtEcalInTheCone < sumEtEcalIsoForEgammaSC_barrel_ &&
02382 (sumNTracksInTheCone < nTrackIsoForEgammaSC_ || sumPtTracksInTheCone < sumPtTrackIsoForEgammaSC_barrel_)))
02383 isBarrelIsolated = true;
02384
02385
02386 bool isEndcapIsolated = false;
02387 if( fabs(EtaFC >= 1.478) &&
02388 (sumEtEcalInTheCone < sumEtEcalIsoForEgammaSC_endcap_ &&
02389 (sumNTracksInTheCone < nTrackIsoForEgammaSC_ || sumPtTracksInTheCone < sumPtTrackIsoForEgammaSC_endcap_)))
02390 isEndcapIsolated = true;
02391
02392
02393
02394 if(DebugSetLinksDetailed) {
02395 if(fabs(EtaFC < 1.478) && isBarrelIsolated == false) {
02396 cout << "**** PFElectronAlgo:: SUPERCLUSTER FOUND BUT FAILS ISOLATION:BARREL *** "
02397 << " sumEtEcalInTheCone " <<sumEtEcalInTheCone
02398 << " sumNTracksInTheCone " << sumNTracksInTheCone
02399 << " sumPtTracksInTheCone " << sumPtTracksInTheCone << endl;
02400 }
02401 if(fabs(EtaFC >= 1.478) && isEndcapIsolated == false) {
02402 cout << "**** PFElectronAlgo:: SUPERCLUSTER FOUND BUT FAILS ISOLATION:ENDCAP *** "
02403 << " sumEtEcalInTheCone " <<sumEtEcalInTheCone
02404 << " sumNTracksInTheCone " << sumNTracksInTheCone
02405 << " sumPtTracksInTheCone " << sumPtTracksInTheCone << endl;
02406 }
02407 }
02408
02409
02410
02411
02412 if(isBarrelIsolated || isEndcapIsolated ) {
02413
02414
02415
02416 double totenergy = 0.;
02417 for(unsigned int ikeyecal = 0;
02418 ikeyecal<EcalIndex.size(); ikeyecal++){
02419
02420 bool foundcluster = false;
02421 if(ikeyecal > 0) {
02422 for(unsigned int i2 = 0; i2<ikeyecal-1; i2++) {
02423 if(EcalIndex[ikeyecal] == EcalIndex[i2])
02424 foundcluster = true;;
02425 }
02426 }
02427 if(foundcluster) continue;
02428 const reco::PFBlockElementCluster * clusasso =
02429 dynamic_cast<const reco::PFBlockElementCluster*>((&elements[(EcalIndex[ikeyecal])]));
02430 totenergy += clusasso->clusterRef()->energy();
02431 }
02432
02433
02434
02435
02436 for(unsigned int ikeyecal = 0;
02437 ikeyecal<EcalIndex.size(); ikeyecal++){
02438
02439 bool foundcluster = false;
02440 if(ikeyecal > 0) {
02441 for(unsigned int i2 = 0; i2<ikeyecal-1; i2++) {
02442 if(EcalIndex[ikeyecal] == EcalIndex[i2])
02443 foundcluster = true;
02444 }
02445 }
02446 if(foundcluster) continue;
02447
02448
02449 std::multimap<double, unsigned int> ecalFromSuperClusterElems;
02450 block.associatedElements( EcalIndex[ikeyecal],linkData,
02451 ecalFromSuperClusterElems,
02452 reco::PFBlockElement::ECAL,
02453 reco::PFBlock::LINKTEST_ALL);
02454 if(ecalFromSuperClusterElems.size() > 0) {
02455 for(std::multimap<double, unsigned int>::iterator itsc = ecalFromSuperClusterElems.begin();
02456 itsc != ecalFromSuperClusterElems.end(); ++itsc) {
02457 if(localactive[itsc->second] == false) {
02458 continue;
02459 }
02460
02461 std::multimap<double, unsigned int> ecalOtherKFPrimElems;
02462 block.associatedElements( itsc->second,linkData,
02463 ecalOtherKFPrimElems,
02464 reco::PFBlockElement::TRACK,
02465 reco::PFBlock::LINKTEST_ALL);
02466 if(ecalOtherKFPrimElems.size() > 0) {
02467 if(localactive[ecalOtherKFPrimElems.begin()->second] == true) {
02468 if (DebugSetLinksDetailed)
02469 cout << "**** PFElectronAlgo:: SUPERCLUSTER FOUND BUT FAILS KF VETO *** " << endl;
02470 continue;
02471 }
02472 }
02473 bool isInTheEtaRange = false;
02474 const reco::PFBlockElementCluster * clustToAdd =
02475 dynamic_cast<const reco::PFBlockElementCluster*>((&elements[itsc->second]));
02476 double deta_clustToAdd = clustToAdd->clusterRef()->position().Eta() - EtaFC;
02477 double ene_clustToAdd = clustToAdd->clusterRef()->energy();
02478
02479 if(fabs(deta_clustToAdd) < 0.05)
02480 isInTheEtaRange = true;
02481
02482
02483 bool isBetterEpin = false;
02484 if(isInTheEtaRange == false ) {
02485 if (DebugSetLinksDetailed)
02486 cout << "**** PFElectronAlgo:: SUPERCLUSTER FOUND BUT FAILS GAMMA DETA RANGE *** "
02487 << fabs(deta_clustToAdd) << endl;
02488
02489 if(KfGsf_index < CutIndex) {
02490
02491 double res_before_gsf = fabs((totenergy-Pin_gsf)/Pin_gsf);
02492 double res_after_gsf = fabs(((totenergy+ene_clustToAdd)-Pin_gsf)/Pin_gsf);
02493
02494
02495 const reco::PFBlockElementTrack * trackEl =
02496 dynamic_cast<const reco::PFBlockElementTrack*>((&elements[KfGsf_index]));
02497 double Pin_kf = trackEl->trackRef()->p();
02498 double res_before_kf = fabs((totenergy-Pin_kf)/Pin_kf);
02499 double res_after_kf = fabs(((totenergy+ene_clustToAdd)-Pin_kf)/Pin_kf);
02500
02501
02502 if(res_after_gsf < res_before_gsf && res_after_kf < res_before_kf ) {
02503 isBetterEpin = true;
02504 }
02505 else {
02506 if (DebugSetLinksDetailed)
02507 cout << "**** PFElectronAlgo:: SUPERCLUSTER FOUND AND FAILS ALSO RES_EPIN"
02508 << " tot energy " << totenergy
02509 << " Pin_gsf " << Pin_gsf
02510 << " Pin_kf " << Pin_kf
02511 << " cluster from SC to ADD " << ene_clustToAdd
02512 << " Res before GSF " << res_before_gsf << " res_after_gsf " << res_after_gsf
02513 << " Res before KF " << res_before_kf << " res_after_kf " << res_after_kf << endl;
02514 }
02515 }
02516 }
02517
02518 if(isInTheEtaRange || isBetterEpin) {
02519 if (DebugSetLinksDetailed)
02520 cout << "!!!! PFElectronAlgo:: ECAL from SUPERCLUSTER FOUND !!!!! " << endl;
02521 GsfElemIndex.push_back(itsc->second);
02522 EcalIndex.push_back(itsc->second);
02523 localactive[(itsc->second)] = false;
02524 }
02525 }
02526 }
02527 }
02528 }
02529 }
02530
02531
02532 if(KfGsf_index < CutIndex)
02533 GsfElemIndex.push_back(KfGsf_index);
02534 else if(KfGsf_secondIndex < CutIndex)
02535 GsfElemIndex.push_back(KfGsf_secondIndex);
02536
02537
02538 GsfElemIndex.insert(GsfElemIndex.end(),convBremKFTrack.begin(),convBremKFTrack.end());
02539 GsfElemIndex.insert(GsfElemIndex.end(),keyBremIndex.begin(),keyBremIndex.end());
02540 associatedToGsf_.insert(pair<unsigned int, vector<unsigned int> >(gsfIs[iEle],GsfElemIndex));
02541
02542
02543 for(unsigned int ikeyecal = 0;
02544 ikeyecal<EcalIndex.size(); ikeyecal++){
02545
02546
02547 vector<unsigned int> EcalElemsIndex(0);
02548
02549 std::multimap<double, unsigned int> PS1Elems;
02550 block.associatedElements( EcalIndex[ikeyecal],linkData,
02551 PS1Elems,
02552 reco::PFBlockElement::PS1,
02553 reco::PFBlock::LINKTEST_ALL );
02554 for( std::multimap<double, unsigned int>::iterator it = PS1Elems.begin();
02555 it != PS1Elems.end();it++) {
02556 unsigned int index = it->second;
02557 if(localactive[index] == true) {
02558
02559
02560 std::multimap<double, unsigned> sortedECAL;
02561 block.associatedElements( index, linkData,
02562 sortedECAL,
02563 reco::PFBlockElement::ECAL,
02564 reco::PFBlock::LINKTEST_ALL );
02565 unsigned jEcal = sortedECAL.begin()->second;
02566 if ( jEcal != EcalIndex[ikeyecal]) continue;
02567
02568
02569 EcalElemsIndex.push_back(index);
02570 localactive[index] = false;
02571 }
02572 }
02573
02574 std::multimap<double, unsigned int> PS2Elems;
02575 block.associatedElements( EcalIndex[ikeyecal],linkData,
02576 PS2Elems,
02577 reco::PFBlockElement::PS2,
02578 reco::PFBlock::LINKTEST_ALL );
02579 for( std::multimap<double, unsigned int>::iterator it = PS2Elems.begin();
02580 it != PS2Elems.end();it++) {
02581 unsigned int index = it->second;
02582 if(localactive[index] == true) {
02583
02584 std::multimap<double, unsigned> sortedECAL;
02585 block.associatedElements( index, linkData,
02586 sortedECAL,
02587 reco::PFBlockElement::ECAL,
02588 reco::PFBlock::LINKTEST_ALL );
02589 unsigned jEcal = sortedECAL.begin()->second;
02590 if ( jEcal != EcalIndex[ikeyecal]) continue;
02591
02592 EcalElemsIndex.push_back(index);
02593 localactive[index] = false;
02594 }
02595 }
02596 if(ikeyecal == 0) {
02597
02598
02599
02600 std::multimap<double, unsigned int> hcalGsfElems;
02601 block.associatedElements( gsfIs[iEle],linkData,
02602 hcalGsfElems,
02603 reco::PFBlockElement::HCAL,
02604 reco::PFBlock::LINKTEST_ALL );
02605 for( std::multimap<double, unsigned int>::iterator it = hcalGsfElems.begin();
02606 it != hcalGsfElems.end();it++) {
02607 unsigned int index = it->second;
02608
02609
02610
02611
02612
02613
02614
02615
02616
02617
02618
02619
02620 EcalElemsIndex.push_back(index);
02621 localactive[index] = false;
02622
02623
02624 }
02625
02626 if(hcalGsfElems.size() == 0 && ClosestEcalWithKf == true) {
02627 std::multimap<double, unsigned int> hcalKfElems;
02628 block.associatedElements( KfGsf_index,linkData,
02629 hcalKfElems,
02630 reco::PFBlockElement::HCAL,
02631 reco::PFBlock::LINKTEST_ALL );
02632 for( std::multimap<double, unsigned int>::iterator it = hcalKfElems.begin();
02633 it != hcalKfElems.end();it++) {
02634 unsigned int index = it->second;
02635 if(localactive[index] == true) {
02636
02637
02638 std::multimap<double, unsigned> sortedKf;
02639 block.associatedElements( index, linkData,
02640 sortedKf,
02641 reco::PFBlockElement::TRACK,
02642 reco::PFBlock::LINKTEST_ALL );
02643 unsigned jKf = sortedKf.begin()->second;
02644 if ( jKf != KfGsf_index) continue;
02645 EcalElemsIndex.push_back(index);
02646 localactive[index] = false;
02647 }
02648 }
02649 }
02650
02651 std::multimap<double, unsigned int> kfEtraElems;
02652 block.associatedElements( EcalIndex[ikeyecal],linkData,
02653 kfEtraElems,
02654 reco::PFBlockElement::TRACK,
02655 reco::PFBlock::LINKTEST_ALL );
02656 if(kfEtraElems.size() > 0) {
02657 for( std::multimap<double, unsigned int>::iterator it = kfEtraElems.begin();
02658 it != kfEtraElems.end();it++) {
02659 unsigned int index = it->second;
02660
02661
02662
02663
02664
02665
02666
02667 bool thisIsAMuon = false;
02668 thisIsAMuon = PFMuonAlgo::isMuon(elements[index]);
02669 if (DebugSetLinksDetailed && thisIsAMuon)
02670 cout << " This is a Muon: index " << index << endl;
02671 if(localactive[index] == true && !thisIsAMuon) {
02672 if(index != KfGsf_index) {
02673
02674
02675 std::multimap<double, unsigned> sortedECAL;
02676 block.associatedElements( index, linkData,
02677 sortedECAL,
02678 reco::PFBlockElement::ECAL,
02679 reco::PFBlock::LINKTEST_ALL );
02680 unsigned jEcal = sortedECAL.begin()->second;
02681 if ( jEcal != EcalIndex[ikeyecal]) continue;
02682 EcalElemsIndex.push_back(index);
02683 localactive[index] = false;
02684 }
02685 }
02686 }
02687 }
02688
02689 }
02690 associatedToEcal_.insert(pair<unsigned int,vector<unsigned int> >(EcalIndex[ikeyecal],EcalElemsIndex));
02691 }
02692 }
02693 }
02694
02695
02696
02697
02698
02699 if (DebugSetLinksSummary) {
02700 if(IsThereAGoodGSFTrack) {
02701 if (DebugSetLinksSummary) cout << " -- The Link Summary --" << endl;
02702 for(map<unsigned int,vector<unsigned int> >::iterator it = associatedToGsf_.begin();
02703 it != associatedToGsf_.end(); it++) {
02704
02705 if (DebugSetLinksSummary) cout << " AssoGsf " << it->first << endl;
02706 vector<unsigned int> eleasso = it->second;
02707 for(unsigned int i=0;i<eleasso.size();i++) {
02708 PFBlockElement::Type type = elements[eleasso[i]].type();
02709 if(type == reco::PFBlockElement::BREM) {
02710 if (DebugSetLinksSummary)
02711 cout << " AssoGsfElements BREM " << eleasso[i] << endl;
02712 }
02713 else if(type == reco::PFBlockElement::ECAL) {
02714 if (DebugSetLinksSummary)
02715 cout << " AssoGsfElements ECAL " << eleasso[i] << endl;
02716 }
02717 else if(type == reco::PFBlockElement::TRACK) {
02718 if (DebugSetLinksSummary)
02719 cout << " AssoGsfElements KF " << eleasso[i] << endl;
02720 }
02721 else {
02722 if (DebugSetLinksSummary)
02723 cout << " AssoGsfElements ????? " << eleasso[i] << endl;
02724 }
02725 }
02726 }
02727
02728 for(map<unsigned int,vector<unsigned int> >::iterator it = associatedToBrems_.begin();
02729 it != associatedToBrems_.end(); it++) {
02730 if (DebugSetLinksSummary) cout << " AssoBrem " << it->first << endl;
02731 vector<unsigned int> eleasso = it->second;
02732 for(unsigned int i=0;i<eleasso.size();i++) {
02733 PFBlockElement::Type type = elements[eleasso[i]].type();
02734 if(type == reco::PFBlockElement::ECAL) {
02735 if (DebugSetLinksSummary)
02736 cout << " AssoBremElements ECAL " << eleasso[i] << endl;
02737 }
02738 else {
02739 if (DebugSetLinksSummary)
02740 cout << " AssoBremElements ????? " << eleasso[i] << endl;
02741 }
02742 }
02743 }
02744
02745 for(map<unsigned int,vector<unsigned int> >::iterator it = associatedToEcal_.begin();
02746 it != associatedToEcal_.end(); it++) {
02747 if (DebugSetLinksSummary) cout << " AssoECAL " << it->first << endl;
02748 vector<unsigned int> eleasso = it->second;
02749 for(unsigned int i=0;i<eleasso.size();i++) {
02750 PFBlockElement::Type type = elements[eleasso[i]].type();
02751 if(type == reco::PFBlockElement::PS1) {
02752 if (DebugSetLinksSummary)
02753 cout << " AssoECALElements PS1 " << eleasso[i] << endl;
02754 }
02755 else if(type == reco::PFBlockElement::PS2) {
02756 if (DebugSetLinksSummary)
02757 cout << " AssoECALElements PS2 " << eleasso[i] << endl;
02758 }
02759 else if(type == reco::PFBlockElement::HCAL) {
02760 if (DebugSetLinksSummary)
02761 cout << " AssoECALElements HCAL " << eleasso[i] << endl;
02762 }
02763 else {
02764 if (DebugSetLinksSummary)
02765 cout << " AssoHCALElements ????? " << eleasso[i] << endl;
02766 }
02767 }
02768 }
02769 if (DebugSetLinksSummary)
02770 cout << "-- End Summary --" << endl;
02771 }
02772
02773 }
02774
02775 return IsThereAGoodGSFTrack;
02776 }
02777
02778 unsigned int PFEGammaAlgo::whichTrackAlgo(const reco::TrackRef& trackRef) {
02779 unsigned int Algo = 0;
02780 switch (trackRef->algo()) {
02781 case TrackBase::ctf:
02782 case TrackBase::iter0:
02783 case TrackBase::iter1:
02784 case TrackBase::iter2:
02785 Algo = 0;
02786 break;
02787 case TrackBase::iter3:
02788 Algo = 1;
02789 break;
02790 case TrackBase::iter4:
02791 Algo = 2;
02792 break;
02793 case TrackBase::iter5:
02794 Algo = 3;
02795 break;
02796 case TrackBase::iter6:
02797 Algo = 4;
02798 break;
02799 default:
02800 Algo = 5;
02801 break;
02802 }
02803 return Algo;
02804 }
02805 bool PFEGammaAlgo::isPrimaryTrack(const reco::PFBlockElementTrack& KfEl,
02806 const reco::PFBlockElementGsfTrack& GsfEl) {
02807 bool isPrimary = false;
02808
02809 GsfPFRecTrackRef gsfPfRef = GsfEl.GsftrackRefPF();
02810
02811 if(gsfPfRef.isNonnull()) {
02812 PFRecTrackRef kfPfRef = KfEl.trackRefPF();
02813 PFRecTrackRef kfPfRef_fromGsf = (*gsfPfRef).kfPFRecTrackRef();
02814 if(kfPfRef.isNonnull() && kfPfRef_fromGsf.isNonnull()) {
02815 reco::TrackRef kfref= (*kfPfRef).trackRef();
02816 reco::TrackRef kfref_fromGsf = (*kfPfRef_fromGsf).trackRef();
02817 if(kfref.isNonnull() && kfref_fromGsf.isNonnull()) {
02818 if(kfref == kfref_fromGsf)
02819 isPrimary = true;
02820 }
02821 }
02822 }
02823
02824 return isPrimary;
02825 }
02826
02827 void PFEGammaAlgo::AddElectronElements(unsigned int gsf_index,
02828 std::vector<unsigned int> &elemsToLock,
02829 const reco::PFBlockRef& blockRef,
02830 AssMap& associatedToGsf_,
02831 AssMap& associatedToBrems_,
02832 AssMap& associatedToEcal_){
02833 const reco::PFBlock& block = *blockRef;
02834 PFBlock::LinkData linkData = block.linkData();
02835
02836 const edm::OwnVector< reco::PFBlockElement >& elements = block.elements();
02837
02838 const reco::PFBlockElementGsfTrack * GsfEl =
02839 dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[gsf_index]));
02840 reco::GsfTrackRef RefGSF = GsfEl->GsftrackRef();
02841
02842
02843
02844
02845
02846
02847
02848
02849
02850
02851
02852
02853
02854
02855
02856 elemsToLock.push_back(gsf_index);
02857 vector<unsigned int> &assogsf_index = associatedToGsf_[gsf_index];
02858 for (unsigned int ielegsf=0;ielegsf<assogsf_index.size();ielegsf++) {
02859 PFBlockElement::Type assoele_type = elements[(assogsf_index[ielegsf])].type();
02860
02861 elemsToLock.push_back((assogsf_index[ielegsf]));
02862 if (assoele_type == reco::PFBlockElement::ECAL) {
02863 unsigned int keyecalgsf = assogsf_index[ielegsf];
02864
02865
02866 if(fifthStepKfTrack_.size() > 0) {
02867 for(unsigned int itr = 0; itr < fifthStepKfTrack_.size(); itr++) {
02868 if(fifthStepKfTrack_[itr].first == keyecalgsf) {
02869 elemsToLock.push_back((fifthStepKfTrack_[itr].second));
02870 }
02871 }
02872 }
02873
02874
02875 if(convGsfTrack_.size() > 0) {
02876 for(unsigned int iconv = 0; iconv < convGsfTrack_.size(); iconv++) {
02877 if(convGsfTrack_[iconv].first == keyecalgsf) {
02878
02879 elemsToLock.push_back(convGsfTrack_[iconv].second);
02880
02881 std::multimap<double, unsigned> convKf;
02882 block.associatedElements( convGsfTrack_[iconv].second,
02883 linkData,
02884 convKf,
02885 reco::PFBlockElement::TRACK,
02886 reco::PFBlock::LINKTEST_ALL );
02887 if(convKf.size() > 0) {
02888 elemsToLock.push_back(convKf.begin()->second);
02889 }
02890 }
02891 }
02892 }
02893
02894
02895 vector<unsigned int> assoecalgsf_index = associatedToEcal_.find(keyecalgsf)->second;
02896 for(unsigned int ips =0; ips<assoecalgsf_index.size();ips++) {
02897
02898 if (elements[(assoecalgsf_index[ips])].type() == reco::PFBlockElement::PS1)
02899 elemsToLock.push_back((assoecalgsf_index[ips]));
02900 if (elements[(assoecalgsf_index[ips])].type() == reco::PFBlockElement::PS2)
02901 elemsToLock.push_back(assoecalgsf_index[ips]);
02902 if (elements[(assoecalgsf_index[ips])].type() == reco::PFBlockElement::TRACK) {
02903
02904
02905
02906
02907 }
02908 }
02909 }
02910 if (assoele_type == reco::PFBlockElement::BREM) {
02911 unsigned int brem_index = assogsf_index[ielegsf];
02912 vector<unsigned int> assobrem_index = associatedToBrems_.find(brem_index)->second;
02913 for (unsigned int ibrem = 0; ibrem < assobrem_index.size(); ibrem++){
02914 if (elements[(assobrem_index[ibrem])].type() == reco::PFBlockElement::ECAL) {
02915 unsigned int keyecalbrem = assobrem_index[ibrem];
02916
02917 elemsToLock.push_back(assobrem_index[ibrem]);
02918
02919
02920 if(fifthStepKfTrack_.size() > 0) {
02921 for(unsigned int itr = 0; itr < fifthStepKfTrack_.size(); itr++) {
02922 if(fifthStepKfTrack_[itr].first == keyecalbrem) {
02923 elemsToLock.push_back(fifthStepKfTrack_[itr].second);
02924 }
02925 }
02926 }
02927
02928 vector<unsigned int> assoelebrem_index = associatedToEcal_.find(keyecalbrem)->second;
02929
02930 for (unsigned int ielebrem=0; ielebrem<assoelebrem_index.size();ielebrem++) {
02931 if (elements[(assoelebrem_index[ielebrem])].type() == reco::PFBlockElement::PS1)
02932 elemsToLock.push_back(assoelebrem_index[ielebrem]);
02933 if (elements[(assoelebrem_index[ielebrem])].type() == reco::PFBlockElement::PS2)
02934 elemsToLock.push_back(assoelebrem_index[ielebrem]);
02935 }
02936 }
02937 }
02938 }
02939 }
02940 return;
02941 }
02942
02943
02944
02945
02946 bool PFEGammaAlgo::AddElectronCandidate(unsigned int gsf_index,
02947 reco::SuperClusterRef scref,
02948 std::vector<unsigned int> &elemsToLock,
02949 const reco::PFBlockRef& blockRef,
02950 AssMap& associatedToGsf_,
02951 AssMap& associatedToBrems_,
02952 AssMap& associatedToEcal_,
02953 std::vector<bool>& active) {
02954
02955 const reco::PFBlock& block = *blockRef;
02956 PFBlock::LinkData linkData = block.linkData();
02957 const edm::OwnVector< reco::PFBlockElement >& elements = block.elements();
02958 PFEnergyResolution pfresol_;
02959
02960
02961 bool DebugIDCandidates = false;
02962
02963
02964
02965
02966
02967 int eecal=0;
02968 int hcal=0;
02969 int charge =0;
02970
02971 math::XYZTLorentzVector momentum_kf,momentum_gsf,momentum,momentum_mean;
02972 float dpt=0; float dpt_gsf=0;
02973 float Eene=0; float dene=0; float Hene=0.;
02974 float RawEene = 0.;
02975 double posX=0.;
02976 double posY=0.;
02977 double posZ=0.;
02978 std::vector<float> bremEnergyVec;
02979
02980 std::vector<const PFCluster*> pfSC_Clust_vec;
02981
02982 float de_gs = 0., de_me = 0., de_kf = 0.;
02983 float m_el=0.00051;
02984 int nhit_kf=0; int nhit_gsf=0;
02985 bool has_gsf=false;
02986 bool has_kf=false;
02987 math::XYZTLorentzVector newmomentum;
02988 float ps1TotEne = 0;
02989 float ps2TotEne = 0;
02990 vector<unsigned int> elementsToAdd(0);
02991 reco::TrackRef RefKF;
02992
02993
02994
02995 elementsToAdd.push_back(gsf_index);
02996 const reco::PFBlockElementGsfTrack * GsfEl =
02997 dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[gsf_index]));
02998 const math::XYZPointF& posGsfEcalEntrance = GsfEl->positionAtECALEntrance();
02999 reco::GsfTrackRef RefGSF = GsfEl->GsftrackRef();
03000 if (RefGSF.isNonnull()) {
03001
03002 has_gsf=true;
03003
03004 charge= RefGSF->chargeMode();
03005 nhit_gsf= RefGSF->hitPattern().trackerLayersWithMeasurement();
03006
03007 momentum_gsf.SetPx(RefGSF->pxMode());
03008 momentum_gsf.SetPy(RefGSF->pyMode());
03009 momentum_gsf.SetPz(RefGSF->pzMode());
03010 float ENE=sqrt(RefGSF->pMode()*
03011 RefGSF->pMode()+m_el*m_el);
03012
03013 if( DebugIDCandidates )
03014 cout << "SetCandidates:: GsfTrackRef: Ene " << ENE
03015 << " charge " << charge << " nhits " << nhit_gsf <<endl;
03016
03017 momentum_gsf.SetE(ENE);
03018 dpt_gsf=RefGSF->ptModeError()*
03019 (RefGSF->pMode()/RefGSF->ptMode());
03020
03021 momentum_mean.SetPx(RefGSF->px());
03022 momentum_mean.SetPy(RefGSF->py());
03023 momentum_mean.SetPz(RefGSF->pz());
03024 float ENEm=sqrt(RefGSF->p()*
03025 RefGSF->p()+m_el*m_el);
03026 momentum_mean.SetE(ENEm);
03027
03028
03029 }
03030 else {
03031 if( DebugIDCandidates )
03032 cout << "SetCandidates:: !!!! NULL GSF Track Ref " << endl;
03033 }
03034
03035
03036 vector<unsigned int> &assogsf_index = associatedToGsf_[gsf_index];
03037 unsigned int ecalGsf_index = 100000;
03038 bool FirstEcalGsf = true;
03039 for (unsigned int ielegsf=0;ielegsf<assogsf_index.size();ielegsf++) {
03040 PFBlockElement::Type assoele_type = elements[(assogsf_index[ielegsf])].type();
03041 if (assoele_type == reco::PFBlockElement::TRACK) {
03042 elementsToAdd.push_back((assogsf_index[ielegsf]));
03043 const reco::PFBlockElementTrack * KfTk =
03044 dynamic_cast<const reco::PFBlockElementTrack*>((&elements[(assogsf_index[ielegsf])]));
03045
03046 bool isPrim = isPrimaryTrack(*KfTk,*GsfEl);
03047 if(!isPrim) continue;
03048
03049 RefKF = KfTk->trackRef();
03050 if (RefKF.isNonnull()) {
03051 has_kf = true;
03052
03053 nhit_kf=RefKF->hitPattern().trackerLayersWithMeasurement();
03054 momentum_kf.SetPx(RefKF->px());
03055 momentum_kf.SetPy(RefKF->py());
03056 momentum_kf.SetPz(RefKF->pz());
03057 float ENE=sqrt(RefKF->p()*RefKF->p()+m_el*m_el);
03058 if( DebugIDCandidates )
03059 cout << "SetCandidates:: KFTrackRef: Ene " << ENE << " nhits " << nhit_kf << endl;
03060
03061 momentum_kf.SetE(ENE);
03062 }
03063 else {
03064 if( DebugIDCandidates )
03065 cout << "SetCandidates:: !!!! NULL KF Track Ref " << endl;
03066 }
03067 }
03068
03069 if (assoele_type == reco::PFBlockElement::ECAL) {
03070 unsigned int keyecalgsf = assogsf_index[ielegsf];
03071 vector<unsigned int> assoecalgsf_index = associatedToEcal_.find(keyecalgsf)->second;
03072 vector<double> ps1Ene(0);
03073 vector<double> ps2Ene(0);
03074
03075
03076
03077 for(unsigned int ips =0; ips<assoecalgsf_index.size();ips++) {
03078 PFBlockElement::Type typeassoecal = elements[(assoecalgsf_index[ips])].type();
03079 if (typeassoecal == reco::PFBlockElement::PS1) {
03080 PFClusterRef psref = elements[(assoecalgsf_index[ips])].clusterRef();
03081 ps1Ene.push_back(psref->energy());
03082 elementsToAdd.push_back((assoecalgsf_index[ips]));
03083 }
03084 if (typeassoecal == reco::PFBlockElement::PS2) {
03085 PFClusterRef psref = elements[(assoecalgsf_index[ips])].clusterRef();
03086 ps2Ene.push_back(psref->energy());
03087 elementsToAdd.push_back((assoecalgsf_index[ips]));
03088 }
03089 if (typeassoecal == reco::PFBlockElement::HCAL) {
03090 const reco::PFBlockElementCluster * clust =
03091 dynamic_cast<const reco::PFBlockElementCluster*>((&elements[(assoecalgsf_index[ips])]));
03092 elementsToAdd.push_back((assoecalgsf_index[ips]));
03093 Hene+=clust->clusterRef()->energy();
03094 hcal++;
03095 }
03096 }
03097 elementsToAdd.push_back((assogsf_index[ielegsf]));
03098
03099
03100 const reco::PFBlockElementCluster * clust =
03101 dynamic_cast<const reco::PFBlockElementCluster*>((&elements[(assogsf_index[ielegsf])]));
03102
03103 eecal++;
03104
03105 const reco::PFCluster& cl(*clust->clusterRef());
03106
03107
03108
03109 double ps1,ps2;
03110 ps1=ps2=0.;
03111
03112 float EE = thePFEnergyCalibration_->energyEm(cl,ps1Ene,ps2Ene,ps1,ps2,applyCrackCorrections_);
03113
03114
03115 float ceta=cl.position().eta();
03116 float cphi=cl.position().phi();
03117
03118
03119
03120
03121
03122
03123
03124
03125
03126
03127
03128 float dE=pfresol_.getEnergyResolutionEm(EE,cl.position().eta());
03129 if( DebugIDCandidates )
03130 cout << "SetCandidates:: EcalCluster: EneNoCalib " << clust->clusterRef()->energy()
03131 << " eta,phi " << ceta << "," << cphi << " Calib " << EE << " dE " << dE <<endl;
03132
03133 bool elecCluster=false;
03134 if (FirstEcalGsf) {
03135 FirstEcalGsf = false;
03136 elecCluster=true;
03137 ecalGsf_index = assogsf_index[ielegsf];
03138
03139 RawEene += EE;
03140 }
03141
03142
03143 math::XYZTLorentzVector clusterMomentum;
03144 math::XYZPoint direction=cl.position()/cl.position().R();
03145 clusterMomentum.SetPxPyPzE(EE*direction.x(),
03146 EE*direction.y(),
03147 EE*direction.z(),
03148 EE);
03149 reco::PFCandidate cluster_Candidate((elecCluster)?charge:0,
03150 clusterMomentum,
03151 (elecCluster)? reco::PFCandidate::e : reco::PFCandidate::gamma);
03152
03153 cluster_Candidate.setPs1Energy(ps1);
03154 cluster_Candidate.setPs2Energy(ps2);
03155
03156
03157 cluster_Candidate.setEcalEnergy(EE-ps1-ps2,EE);
03158
03159 cluster_Candidate.setPositionAtECALEntrance(math::XYZPointF(cl.position()));
03160 cluster_Candidate.addElementInBlock(blockRef,assogsf_index[ielegsf]);
03161
03162
03163
03164
03165
03166
03167
03168
03169
03170
03171
03172
03173
03174
03175
03176
03177 Eene+=EE;
03178 posX += EE * cl.position().X();
03179 posY += EE * cl.position().Y();
03180 posZ += EE * cl.position().Z();
03181 ps1TotEne+=ps1;
03182 ps2TotEne+=ps2;
03183 dene+=dE*dE;
03184
03185
03186 pfSC_Clust_vec.push_back( &cl );
03187
03188 }
03189
03190
03191
03192
03193 if (assoele_type == reco::PFBlockElement::BREM) {
03194 unsigned int brem_index = assogsf_index[ielegsf];
03195 vector<unsigned int> assobrem_index = associatedToBrems_.find(brem_index)->second;
03196 elementsToAdd.push_back(brem_index);
03197 for (unsigned int ibrem = 0; ibrem < assobrem_index.size(); ibrem++){
03198 if (elements[(assobrem_index[ibrem])].type() == reco::PFBlockElement::ECAL) {
03199
03200 if( assobrem_index[ibrem] != ecalGsf_index) {
03201 unsigned int keyecalbrem = assobrem_index[ibrem];
03202 const vector<unsigned int>& assoelebrem_index = associatedToEcal_.find(keyecalbrem)->second;
03203 vector<double> ps1EneFromBrem(0);
03204 vector<double> ps2EneFromBrem(0);
03205 for (unsigned int ielebrem=0; ielebrem<assoelebrem_index.size();ielebrem++) {
03206 if (elements[(assoelebrem_index[ielebrem])].type() == reco::PFBlockElement::PS1) {
03207 PFClusterRef psref = elements[(assoelebrem_index[ielebrem])].clusterRef();
03208 ps1EneFromBrem.push_back(psref->energy());
03209 elementsToAdd.push_back(assoelebrem_index[ielebrem]);
03210 }
03211 if (elements[(assoelebrem_index[ielebrem])].type() == reco::PFBlockElement::PS2) {
03212 PFClusterRef psref = elements[(assoelebrem_index[ielebrem])].clusterRef();
03213 ps2EneFromBrem.push_back(psref->energy());
03214 elementsToAdd.push_back(assoelebrem_index[ielebrem]);
03215 }
03216 }
03217 elementsToAdd.push_back(assobrem_index[ibrem]);
03218 reco::PFClusterRef clusterRef = elements[(assobrem_index[ibrem])].clusterRef();
03219
03220
03221 double ps1=0;
03222 double ps2=0;
03223 float EE = thePFEnergyCalibration_->energyEm(*clusterRef,ps1EneFromBrem,ps2EneFromBrem,ps1,ps2,applyCrackCorrections_);
03224 bremEnergyVec.push_back(EE);
03225
03226 float ceta = clusterRef->position().eta();
03227
03228 float dE=pfresol_.getEnergyResolutionEm(EE,ceta);
03229 if( DebugIDCandidates )
03230 cout << "SetCandidates:: BremCluster: Ene " << EE << " dE " << dE <<endl;
03231
03232 Eene+=EE;
03233 posX += EE * clusterRef->position().X();
03234 posY += EE * clusterRef->position().Y();
03235 posZ += EE * clusterRef->position().Z();
03236 ps1TotEne+=ps1;
03237 ps2TotEne+=ps2;
03238
03239
03240 dene+=dE*dE;
03241
03242
03243 pfSC_Clust_vec.push_back( clusterRef.get() );
03244
03245
03246
03247 math::XYZTLorentzVector photonMomentum;
03248 math::XYZPoint direction=clusterRef->position()/clusterRef->position().R();
03249
03250 photonMomentum.SetPxPyPzE(EE*direction.x(),
03251 EE*direction.y(),
03252 EE*direction.z(),
03253 EE);
03254 reco::PFCandidate photon_Candidate(0,photonMomentum, reco::PFCandidate::gamma);
03255
03256 photon_Candidate.setPs1Energy(ps1);
03257 photon_Candidate.setPs2Energy(ps2);
03258
03259
03260 photon_Candidate.setEcalEnergy(EE-ps1-ps2,EE);
03261
03262 photon_Candidate.setPositionAtECALEntrance(math::XYZPointF(clusterRef->position()));
03263 photon_Candidate.addElementInBlock(blockRef,assobrem_index[ibrem]);
03264
03265
03266
03267
03268
03269
03270
03271
03272
03273
03274
03275
03276
03277
03278
03279
03280
03281 }
03282 }
03283 }
03284 }
03285 }
03286 if (has_gsf) {
03287
03288
03289 double unCorrEene = Eene;
03290 double absEta = fabs(momentum_gsf.Eta());
03291 double emTheta = momentum_gsf.Theta();
03292 PFClusterWidthAlgo pfSCwidth(pfSC_Clust_vec);
03293 double brLinear = pfSCwidth.pflowPhiWidth()/pfSCwidth.pflowEtaWidth();
03294 pfSC_Clust_vec.clear();
03295
03296 if( DebugIDCandidates )
03297 cout << "PFEelectronAlgo:: absEta " << absEta << " theta " << emTheta
03298 << " EneRaw " << Eene << " Err " << dene;
03299
03300
03301
03302 if(usePFSCEleCalib_ && unCorrEene > 0.) {
03303 if( absEta < 1.5) {
03304 double Etene = Eene*sin(emTheta);
03305 double emBR_e = thePFSCEnergyCalibration_->SCCorrFBremBarrel(Eene, Etene, brLinear);
03306 double emBR_et = emBR_e*sin(emTheta);
03307 double emCorrFull_et = thePFSCEnergyCalibration_->SCCorrEtEtaBarrel(emBR_et, absEta);
03308 Eene = emCorrFull_et/sin(emTheta);
03309 }
03310 else {
03311
03312 double emBR_e = thePFSCEnergyCalibration_->SCCorrFBremEndcap(Eene, absEta, brLinear);
03313 double emBR_et = emBR_e*sin(emTheta);
03314 double emCorrFull_et = thePFSCEnergyCalibration_->SCCorrEtEtaEndcap(emBR_et, absEta);
03315 Eene = emCorrFull_et/sin(emTheta);
03316 }
03317 dene = sqrt(dene)*(Eene/unCorrEene);
03318 dene = dene*dene;
03319 }
03320
03321 if( DebugIDCandidates )
03322 cout << " EneCorrected " << Eene << " Err " << dene << endl;
03323
03324
03325
03326
03327 if(has_kf && unCorrEene > 0.) {
03328 posX /=unCorrEene;
03329 posY /=unCorrEene;
03330 posZ /=unCorrEene;
03331 math::XYZPoint sc_pflow(posX,posY,posZ);
03332
03333 std::multimap<double, unsigned int> bremElems;
03334 block.associatedElements( gsf_index,linkData,
03335 bremElems,
03336 reco::PFBlockElement::BREM,
03337 reco::PFBlock::LINKTEST_ALL );
03338
03339 double phiTrack = RefGSF->phiMode();
03340 if(bremElems.size()>0) {
03341 unsigned int brem_index = bremElems.begin()->second;
03342 const reco::PFBlockElementBrem * BremEl =
03343 dynamic_cast<const reco::PFBlockElementBrem*>((&elements[brem_index]));
03344 phiTrack = BremEl->positionAtECALEntrance().phi();
03345 }
03346
03347 double dphi_normalsc = sc_pflow.Phi() - phiTrack;
03348 if ( dphi_normalsc < -M_PI )
03349 dphi_normalsc = dphi_normalsc + 2.*M_PI;
03350 else if ( dphi_normalsc > M_PI )
03351 dphi_normalsc = dphi_normalsc - 2.*M_PI;
03352
03353 int chargeGsf = RefGSF->chargeMode();
03354 int chargeKf = RefKF->charge();
03355
03356 int chargeSC = 0;
03357 if(dphi_normalsc < 0.)
03358 chargeSC = 1;
03359 else
03360 chargeSC = -1;
03361
03362 if(chargeKf == chargeGsf)
03363 charge = chargeGsf;
03364 else if(chargeGsf == chargeSC)
03365 charge = chargeGsf;
03366 else
03367 charge = chargeKf;
03368
03369 if( DebugIDCandidates )
03370 cout << "PFElectronAlgo:: charge determination "
03371 << " charge GSF " << chargeGsf
03372 << " charge KF " << chargeKf
03373 << " charge SC " << chargeSC
03374 << " Final Charge " << charge << endl;
03375
03376 }
03377
03378
03379 if ((nhit_gsf<8) && (has_kf)){
03380
03381
03382
03383 momentum=momentum_kf;
03384 float Fe=Eene;
03385 float scale= Fe/momentum.E();
03386
03387
03388 if (Eene < 0.0001) {
03389 Fe = momentum.E();
03390 scale = 1.;
03391 }
03392
03393
03394 newmomentum.SetPxPyPzE(scale*momentum.Px(),
03395 scale*momentum.Py(),
03396 scale*momentum.Pz(),Fe);
03397 if( DebugIDCandidates )
03398 cout << "SetCandidates:: (nhit_gsf<8) && (has_kf):: pt " << newmomentum.pt() << " Ene " << Fe <<endl;
03399
03400
03401 }
03402 if ((nhit_gsf>7) || (has_kf==false)){
03403 if(Eene > 0.0001) {
03404 de_gs=1-momentum_gsf.E()/Eene;
03405 de_me=1-momentum_mean.E()/Eene;
03406 de_kf=1-momentum_kf.E()/Eene;
03407 }
03408
03409 momentum=momentum_gsf;
03410 dpt=1/(dpt_gsf*dpt_gsf);
03411
03412 if(dene > 0.)
03413 dene= 1./dene;
03414
03415 float Fe = 0.;
03416 if(Eene > 0.0001) {
03417 Fe =((dene*Eene) +(dpt*momentum.E()))/(dene+dpt);
03418 }
03419 else {
03420 Fe=momentum.E();
03421 }
03422
03423 if ((de_gs>0.05)&&(de_kf>0.05)){
03424 Fe=Eene;
03425 }
03426 if ((de_gs<-0.1)&&(de_me<-0.1) &&(de_kf<0.) &&
03427 (momentum.E()/dpt_gsf) > 5. && momentum_gsf.pt() < 30.){
03428 Fe=momentum.E();
03429 }
03430 float scale= Fe/momentum.E();
03431
03432 newmomentum.SetPxPyPzE(scale*momentum.Px(),
03433 scale*momentum.Py(),
03434 scale*momentum.Pz(),Fe);
03435 if( DebugIDCandidates )
03436 cout << "SetCandidates::(nhit_gsf>7) || (has_kf==false) " << newmomentum.pt() << " Ene " << Fe <<endl;
03437
03438
03439 }
03440 if (newmomentum.pt()>0.5){
03441
03442
03443
03444
03445 if( DebugIDCandidates )
03446 cout << "SetCandidates:: I am before doing candidate " <<endl;
03447
03448
03449 std::vector<float> clusterEnergyVec;
03450 clusterEnergyVec.push_back(RawEene);
03451 clusterEnergyVec.insert(clusterEnergyVec.end(),bremEnergyVec.begin(),bremEnergyVec.end());
03452
03453
03454
03455
03456 PFCandidateEGammaExtra myExtraEqual(RefGSF);
03457
03458 myExtraEqual.setSuperClusterBoxRef(scref);
03459 myExtraEqual.setClusterEnergies(clusterEnergyVec);
03460
03461
03462
03463
03464
03465
03466
03467
03468 reco::PFCandidate::ParticleType particleType
03469 = reco::PFCandidate::e;
03470
03471 reco::PFCandidate temp_Candidate(charge,newmomentum,particleType);
03472
03473
03474 temp_Candidate.setEcalEnergy(RawEene,Eene);
03475
03476 temp_Candidate.setHcalEnergy(Hene,Hene);
03477 temp_Candidate.setPs1Energy(ps1TotEne);
03478 temp_Candidate.setPs2Energy(ps2TotEne);
03479 temp_Candidate.setTrackRef(RefKF);
03480
03481 temp_Candidate.setGsfTrackRef(RefGSF);
03482 temp_Candidate.setPositionAtECALEntrance(posGsfEcalEntrance);
03483
03484 temp_Candidate.setVertexSource(PFCandidate::kGSFVertex);
03485
03486
03487 temp_Candidate.setSuperClusterRef(scref);
03488
03489
03490
03491
03492
03493
03494
03495
03496
03497
03498
03499
03500 if( DebugIDCandidates )
03501 cout << "SetCandidates:: I am after doing candidate " <<endl;
03502
03503
03504
03505
03506
03507
03508
03509
03510
03511
03512
03513
03514
03515
03516
03517
03518
03519
03520
03521
03522
03523
03524
03525
03526
03527
03528
03529
03530
03531
03532
03533
03534
03535
03536
03537
03538
03539
03540
03541
03542
03543
03544
03545
03546
03547
03548
03549
03550
03551 myExtraEqual.setStatus(PFCandidateEGammaExtra::Selected,true);
03552
03553
03554 for(std::vector<unsigned int>::const_iterator it = elemsToLock.begin();
03555 it != elemsToLock.end(); ++it)
03556 {
03557 if(active[*it])
03558 {
03559 temp_Candidate.addElementInBlock(blockRef,*it);
03560 }
03561 active[*it] = false;
03562 }
03563
03564 egCandidate_.push_back(temp_Candidate);
03565 egExtra_.push_back(myExtraEqual);
03566
03567 return true;
03568
03569
03570
03571
03572
03573
03574
03575
03576
03577
03578
03579
03580
03581
03582
03583
03584
03585
03586
03587
03588 }
03589 else {
03590
03591
03592 if( DebugIDCandidates )
03593 cout << "SetCandidates:: No Candidate Produced because of Pt cut: 0.5 " <<endl;
03594 return false;
03595 }
03596 }
03597 else {
03598
03599 if( DebugIDCandidates )
03600 cout << "SetCandidates:: No Candidate Produced because of No GSF Track Ref " <<endl;
03601 return false;
03602 }
03603 return false;
03604 }