00001
00002
00003
00004
00005 #include "RecoParticleFlow/PFProducer/interface/PFElectronAlgo.h"
00006 #include "RecoParticleFlow/PFProducer/interface/PFMuonAlgo.h"
00007
00008 #include "DataFormats/ParticleFlowReco/interface/PFBlockElementCluster.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/PFRecHit.h"
00013 #include "DataFormats/ParticleFlowReco/interface/PFCluster.h"
00014 #include "DataFormats/GsfTrackReco/interface/GsfTrack.h"
00015 #include "DataFormats/GsfTrackReco/interface/GsfTrackFwd.h"
00016 #include "RecoParticleFlow/PFProducer/interface/PFElectronExtraEqual.h"
00017 #include "RecoParticleFlow/PFProducer/interface/GsfElectronEqual.h"
00018 #include "RecoParticleFlow/PFClusterTools/interface/PFEnergyCalibration.h"
00019 #include "RecoParticleFlow/PFClusterTools/interface/PFSCEnergyCalibration.h"
00020 #include "RecoParticleFlow/PFClusterTools/interface/PFEnergyResolution.h"
00021 #include "RecoParticleFlow/PFClusterTools/interface/PFClusterWidthAlgo.h"
00022 #include "DataFormats/ParticleFlowReco/interface/PFRecTrack.h"
00023 #include "DataFormats/ParticleFlowReco/interface/GsfPFRecTrack.h"
00024 #include "DataFormats/EgammaReco/interface/ElectronSeedFwd.h"
00025 #include "DataFormats/EgammaReco/interface/ElectronSeed.h"
00026
00027 #include <iomanip>
00028 #include <algorithm>
00029
00030 using namespace std;
00031 using namespace reco;
00032 PFElectronAlgo::PFElectronAlgo(const double mvaEleCut,
00033 string mvaWeightFileEleID,
00034 const boost::shared_ptr<PFSCEnergyCalibration>& thePFSCEnergyCalibration,
00035 const boost::shared_ptr<PFEnergyCalibration>& thePFEnergyCalibration,
00036 bool applyCrackCorrections,
00037 bool usePFSCEleCalib,
00038 bool useEGElectrons,
00039 bool useEGammaSupercluster,
00040 double sumEtEcalIsoForEgammaSC_barrel,
00041 double sumEtEcalIsoForEgammaSC_endcap,
00042 double coneEcalIsoForEgammaSC,
00043 double sumPtTrackIsoForEgammaSC_barrel,
00044 double sumPtTrackIsoForEgammaSC_endcap,
00045 unsigned int nTrackIsoForEgammaSC,
00046 double coneTrackIsoForEgammaSC):
00047 mvaEleCut_(mvaEleCut),
00048 thePFSCEnergyCalibration_(thePFSCEnergyCalibration),
00049 thePFEnergyCalibration_(thePFEnergyCalibration),
00050 applyCrackCorrections_(applyCrackCorrections),
00051 usePFSCEleCalib_(usePFSCEleCalib),
00052 useEGElectrons_(useEGElectrons),
00053 useEGammaSupercluster_(useEGammaSupercluster),
00054 sumEtEcalIsoForEgammaSC_barrel_(sumEtEcalIsoForEgammaSC_barrel),
00055 sumEtEcalIsoForEgammaSC_endcap_(sumEtEcalIsoForEgammaSC_endcap),
00056 coneEcalIsoForEgammaSC_(coneEcalIsoForEgammaSC),
00057 sumPtTrackIsoForEgammaSC_barrel_(sumPtTrackIsoForEgammaSC_barrel),
00058 sumPtTrackIsoForEgammaSC_endcap_(sumPtTrackIsoForEgammaSC_endcap),
00059 nTrackIsoForEgammaSC_(nTrackIsoForEgammaSC),
00060 coneTrackIsoForEgammaSC_(coneTrackIsoForEgammaSC)
00061 {
00062
00063 tmvaReader_ = new TMVA::Reader("!Color:Silent");
00064 tmvaReader_->AddVariable("lnPt_gsf",&lnPt_gsf);
00065 tmvaReader_->AddVariable("Eta_gsf",&Eta_gsf);
00066 tmvaReader_->AddVariable("dPtOverPt_gsf",&dPtOverPt_gsf);
00067 tmvaReader_->AddVariable("DPtOverPt_gsf",&DPtOverPt_gsf);
00068
00069 tmvaReader_->AddVariable("chi2_gsf",&chi2_gsf);
00070
00071 tmvaReader_->AddVariable("nhit_kf",&nhit_kf);
00072 tmvaReader_->AddVariable("chi2_kf",&chi2_kf);
00073 tmvaReader_->AddVariable("EtotPinMode",&EtotPinMode);
00074 tmvaReader_->AddVariable("EGsfPoutMode",&EGsfPoutMode);
00075 tmvaReader_->AddVariable("EtotBremPinPoutMode",&EtotBremPinPoutMode);
00076 tmvaReader_->AddVariable("DEtaGsfEcalClust",&DEtaGsfEcalClust);
00077 tmvaReader_->AddVariable("SigmaEtaEta",&SigmaEtaEta);
00078 tmvaReader_->AddVariable("HOverHE",&HOverHE);
00079
00080 tmvaReader_->AddVariable("lateBrem",&lateBrem);
00081 tmvaReader_->AddVariable("firstBrem",&firstBrem);
00082 tmvaReader_->BookMVA("BDT",mvaWeightFileEleID.c_str());
00083 }
00084 void PFElectronAlgo::RunPFElectron(const reco::PFBlockRef& blockRef,
00085 std::vector<bool>& active){
00086
00087
00088 AssMap associatedToGsf;
00089 AssMap associatedToBrems;
00090 AssMap associatedToEcal;
00091
00092
00093 elCandidate_.clear();
00094 electronExtra_.clear();
00095 allElCandidate_.clear();
00096 electronConstituents_.clear();
00097 fifthStepKfTrack_.clear();
00098 convGsfTrack_.clear();
00099
00100
00101 bool blockHasGSF = SetLinks(blockRef,associatedToGsf,
00102 associatedToBrems,associatedToEcal,
00103 active);
00104
00105
00106 if (blockHasGSF) {
00107
00108 BDToutput_.clear();
00109
00110 lockExtraKf_.clear();
00111
00112 BDToutput_.assign(associatedToGsf.size(),-1.);
00113 lockExtraKf_.assign(associatedToGsf.size(),true);
00114
00115
00116 SetIDOutputs(blockRef,associatedToGsf,associatedToBrems,associatedToEcal);
00117
00118
00119
00120
00121 SetCandidates(blockRef,associatedToGsf,associatedToBrems,associatedToEcal);
00122 if (elCandidate_.size() > 0 ){
00123 isvalid_ = true;
00124
00125
00126 SetActive(blockRef,associatedToGsf,associatedToBrems,associatedToEcal,active);
00127 }
00128 }
00129 }
00130 bool PFElectronAlgo::SetLinks(const reco::PFBlockRef& blockRef,
00131 AssMap& associatedToGsf_,
00132 AssMap& associatedToBrems_,
00133 AssMap& associatedToEcal_,
00134 std::vector<bool>& active){
00135 unsigned int CutIndex = 100000;
00136 double CutGSFECAL = 10000. ;
00137
00138
00139 bool DebugSetLinksSummary = false;
00140 bool DebugSetLinksDetailed = false;
00141
00142 const reco::PFBlock& block = *blockRef;
00143 const edm::OwnVector< reco::PFBlockElement >& elements = block.elements();
00144 PFBlock::LinkData linkData = block.linkData();
00145
00146 bool IsThereAGSFTrack = false;
00147 bool IsThereAGoodGSFTrack = false;
00148
00149 vector<unsigned int> trackIs(0);
00150 vector<unsigned int> gsfIs(0);
00151 vector<unsigned int> ecalIs(0);
00152
00153 std::vector<bool> localactive(elements.size(),true);
00154
00155
00156
00157 std::multimap<double, unsigned int> kfElems;
00158 for(unsigned int iEle=0; iEle<elements.size(); iEle++) {
00159 localactive[iEle] = active[iEle];
00160 bool thisIsAMuon = false;
00161 PFBlockElement::Type type = elements[iEle].type();
00162 switch( type ) {
00163 case PFBlockElement::TRACK:
00164
00165 thisIsAMuon = PFMuonAlgo::isMuon(elements[iEle]);
00166
00167 if ( !thisIsAMuon && active[iEle] ) {
00168 trackIs.push_back( iEle );
00169 if (DebugSetLinksDetailed)
00170 cout<<"TRACK, stored index, continue "<< iEle << endl;
00171 }
00172 continue;
00173 case PFBlockElement::GSF:
00174
00175 block.associatedElements( iEle,linkData,
00176 kfElems,
00177 reco::PFBlockElement::TRACK,
00178 reco::PFBlock::LINKTEST_ALL );
00179 thisIsAMuon = kfElems.size() ?
00180 PFMuonAlgo::isMuon(elements[kfElems.begin()->second]) : false;
00181
00182 if ( !thisIsAMuon && active[iEle] ) {
00183 IsThereAGSFTrack = true;
00184 gsfIs.push_back( iEle );
00185 if (DebugSetLinksDetailed)
00186 cout<<"GSF, stored index, continue "<< iEle << endl;
00187 }
00188 continue;
00189 case PFBlockElement::ECAL:
00190 if ( active[iEle] ) {
00191 ecalIs.push_back( iEle );
00192 if (DebugSetLinksDetailed)
00193 cout<<"ECAL, stored index, continue "<< iEle << endl;
00194 }
00195 continue;
00196 default:
00197 continue;
00198 }
00199 }
00200
00201
00202 if(IsThereAGSFTrack) {
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 if (DebugSetLinksDetailed) {
00214 cout<<"#########################################################"<<endl;
00215 cout<<"##### Process Block: #####"<<endl;
00216 cout<<"#########################################################"<<endl;
00217 cout<<block<<endl;
00218 }
00219
00220
00221 for(unsigned int iEle=0; iEle<trackIs.size(); iEle++) {
00222 std::multimap<double, unsigned int> gsfElems;
00223 block.associatedElements( trackIs[iEle], linkData,
00224 gsfElems ,
00225 reco::PFBlockElement::GSF,
00226 reco::PFBlock::LINKTEST_ALL );
00227 if(gsfElems.size() == 0){
00228
00229
00230 std::multimap<double, unsigned int> ecalKfElems;
00231 block.associatedElements( trackIs[iEle],linkData,
00232 ecalKfElems,
00233 reco::PFBlockElement::ECAL,
00234 reco::PFBlock::LINKTEST_ALL );
00235 if(ecalKfElems.size() > 0) {
00236 unsigned int ecalKf_index = ecalKfElems.begin()->second;
00237 if(localactive[ecalKf_index]==true) {
00238
00239
00240
00241 bool isGsfLinked = false;
00242 for(unsigned int iGsf=0; iGsf<gsfIs.size(); iGsf++) {
00243
00244
00245
00246 const reco::PFBlockElementGsfTrack * GsfEl =
00247 dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[gsfIs[iGsf]]));
00248 if(GsfEl->trackType(reco::PFBlockElement::T_FROM_GAMMACONV)) continue;
00249
00250 std::multimap<double, unsigned int> ecalGsfElems;
00251 block.associatedElements( gsfIs[iGsf],linkData,
00252 ecalGsfElems,
00253 reco::PFBlockElement::ECAL,
00254 reco::PFBlock::LINKTEST_ALL );
00255 if(ecalGsfElems.size() > 0) {
00256 if (ecalGsfElems.begin()->second == ecalKf_index) {
00257 isGsfLinked = true;
00258 }
00259 }
00260 }
00261 if(isGsfLinked == false) {
00262
00263
00264 const reco::PFBlockElementTrack * kfEle =
00265 dynamic_cast<const reco::PFBlockElementTrack*>((&elements[(trackIs[iEle])]));
00266 reco::TrackRef refKf = kfEle->trackRef();
00267
00268 int nexhits = refKf->trackerExpectedHitsInner().numberOfLostHits();
00269
00270 unsigned int Algo = 0;
00271 if (refKf.isNonnull())
00272 Algo = refKf->algo();
00273
00274 if(Algo < 9 && nexhits == 0) {
00275 localactive[ecalKf_index] = false;
00276 }
00277 else {
00278 fifthStepKfTrack_.push_back(make_pair(ecalKf_index,trackIs[iEle]));
00279 }
00280 }
00281 }
00282 }
00283 }
00284 }
00285
00286
00287
00288 for(unsigned int iEle=0; iEle<gsfIs.size(); iEle++) {
00289
00290 if (!localactive[(gsfIs[iEle])]) continue;
00291
00292 localactive[gsfIs[iEle]] = false;
00293 bool ClosestEcalWithKf = false;
00294
00295 if (DebugSetLinksDetailed) cout << " Gsf Index " << gsfIs[iEle] << endl;
00296
00297 const reco::PFBlockElementGsfTrack * GsfEl =
00298 dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[(gsfIs[iEle])]));
00299
00300
00301 if(GsfEl->trackType(reco::PFBlockElement::T_FROM_GAMMACONV)) continue;
00302 IsThereAGoodGSFTrack = true;
00303 float eta_gsf = GsfEl->positionAtECALEntrance().eta();
00304 float etaOut_gsf = GsfEl->Pout().eta();
00305 float diffOutEcalEta = fabs(eta_gsf-etaOut_gsf);
00306 reco::GsfTrackRef RefGSF = GsfEl->GsftrackRef();
00307 float Pin_gsf = 0.01;
00308 if (RefGSF.isNonnull() )
00309 Pin_gsf = RefGSF->pMode();
00310
00311
00312
00313 unsigned int KfGsf_index = CutIndex;
00314 unsigned int KfGsf_secondIndex = CutIndex;
00315 std::multimap<double, unsigned int> kfElems;
00316 block.associatedElements( gsfIs[iEle],linkData,
00317 kfElems,
00318 reco::PFBlockElement::TRACK,
00319 reco::PFBlock::LINKTEST_ALL );
00320 std::multimap<double, unsigned int> ecalKfElems;
00321 if (kfElems.size() > 0) {
00322
00323
00324
00325 for(std::multimap<double, unsigned int>::iterator itkf = kfElems.begin();
00326 itkf != kfElems.end(); ++itkf) {
00327 const reco::PFBlockElementTrack * TrkEl =
00328 dynamic_cast<const reco::PFBlockElementTrack*>((&elements[itkf->second]));
00329
00330 bool isPrim = isPrimaryTrack(*TrkEl,*GsfEl);
00331 if(!isPrim)
00332 continue;
00333
00334 if(localactive[itkf->second] == true) {
00335
00336 KfGsf_index = itkf->second;
00337 localactive[KfGsf_index] = false;
00338
00339 block.associatedElements( KfGsf_index, linkData,
00340 ecalKfElems ,
00341 reco::PFBlockElement::ECAL,
00342 reco::PFBlock::LINKTEST_ALL );
00343 }
00344 else {
00345 KfGsf_secondIndex = itkf->second;
00346 }
00347 }
00348 }
00349
00350
00351 std::multimap<double, unsigned int> ecalGsfElems;
00352 block.associatedElements( gsfIs[iEle],linkData,
00353 ecalGsfElems,
00354 reco::PFBlockElement::ECAL,
00355 reco::PFBlock::LINKTEST_ALL );
00356 double ecalGsf_dist = CutGSFECAL;
00357 unsigned int ClosestEcalGsf_index = CutIndex;
00358 if (ecalGsfElems.size() > 0) {
00359 if(localactive[(ecalGsfElems.begin()->second)] == true) {
00360
00361 bool compatibleEPout = true;
00362 if(diffOutEcalEta > 0.3) {
00363 reco::PFClusterRef clusterRef = elements[(ecalGsfElems.begin()->second)].clusterRef();
00364 float EoPout = (clusterRef->energy())/(GsfEl->Pout().t());
00365 if(EoPout > 5)
00366 compatibleEPout = false;
00367 }
00368 if(compatibleEPout) {
00369 ClosestEcalGsf_index = ecalGsfElems.begin()->second;
00370 ecalGsf_dist = block.dist(gsfIs[iEle],ClosestEcalGsf_index,
00371 linkData,reco::PFBlock::LINKTEST_ALL);
00372
00373
00374
00375 std::multimap<double, unsigned int> ecalOtherGsfElems;
00376 block.associatedElements( ClosestEcalGsf_index,linkData,
00377 ecalOtherGsfElems,
00378 reco::PFBlockElement::GSF,
00379 reco::PFBlock::LINKTEST_ALL);
00380
00381 if(ecalOtherGsfElems.size()>0) {
00382
00383 const reco::PFBlockElementGsfTrack * gsfCheck =
00384 dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[ecalOtherGsfElems.begin()->second]));
00385
00386 if(ecalOtherGsfElems.begin()->second != gsfIs[iEle]&&
00387 gsfCheck->trackType(reco::PFBlockElement::T_FROM_GAMMACONV) == false) {
00388 ecalGsf_dist = CutGSFECAL;
00389 ClosestEcalGsf_index = CutIndex;
00390 }
00391 }
00392 }
00393
00394 }
00395 }
00396
00397 else if(ecalKfElems.size() > 0) {
00398 if(localactive[(ecalKfElems.begin()->second)] == true) {
00399 ClosestEcalGsf_index = ecalKfElems.begin()->second;
00400 ecalGsf_dist = block.dist(gsfIs[iEle],ClosestEcalGsf_index,
00401 linkData,reco::PFBlock::LINKTEST_ALL);
00402 ClosestEcalWithKf = true;
00403
00404
00405 std::multimap<double, unsigned int> ecalOtherGsfElems;
00406 block.associatedElements( ClosestEcalGsf_index,linkData,
00407 ecalOtherGsfElems,
00408 reco::PFBlockElement::GSF,
00409 reco::PFBlock::LINKTEST_ALL);
00410 if(ecalOtherGsfElems.size() > 0) {
00411 const reco::PFBlockElementGsfTrack * gsfCheck =
00412 dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[ecalOtherGsfElems.begin()->second]));
00413
00414 if(ecalOtherGsfElems.begin()->second != gsfIs[iEle] &&
00415 gsfCheck->trackType(reco::PFBlockElement::T_FROM_GAMMACONV) == false) {
00416 ecalGsf_dist = CutGSFECAL;
00417 ClosestEcalGsf_index = CutIndex;
00418 ClosestEcalWithKf = false;
00419 }
00420 }
00421 }
00422 }
00423
00424 if (DebugSetLinksDetailed)
00425 cout << " Closest Ecal to the Gsf/Kf: index " << ClosestEcalGsf_index
00426 << " dist " << ecalGsf_dist << endl;
00427
00428
00429
00430
00431 std::multimap<double, unsigned int> bremElems;
00432 block.associatedElements( gsfIs[iEle],linkData,
00433 bremElems,
00434 reco::PFBlockElement::BREM,
00435 reco::PFBlock::LINKTEST_ALL );
00436
00437
00438 multimap<unsigned int,unsigned int> cleanedEcalBremElems;
00439 vector<unsigned int> keyBremIndex(0);
00440 unsigned int latestBrem_trajP = 0;
00441 unsigned int latestBrem_index = CutIndex;
00442 for(std::multimap<double, unsigned int>::iterator ieb = bremElems.begin();
00443 ieb != bremElems.end(); ++ieb ) {
00444 unsigned int brem_index = ieb->second;
00445 if(localactive[brem_index] == false) continue;
00446
00447
00448
00449 std::multimap<double, unsigned int> ecalBremsElems;
00450
00451 block.associatedElements( brem_index, linkData,
00452 ecalBremsElems,
00453 reco::PFBlockElement::ECAL,
00454 reco::PFBlock::LINKTEST_ALL );
00455
00456 for (std::multimap<double, unsigned int>::iterator ie = ecalBremsElems.begin();
00457 ie != ecalBremsElems.end();ie++) {
00458 unsigned int ecalBrem_index = ie->second;
00459 if(localactive[ecalBrem_index] == false) continue;
00460
00461
00462 float ecalBrem_dist = block.dist(brem_index,ecalBrem_index,
00463 linkData,reco::PFBlock::LINKTEST_ALL);
00464
00465
00466 if (ecalBrem_index == ClosestEcalGsf_index && (ecalBrem_dist + 0.0012) > ecalGsf_dist) continue;
00467
00468
00469 std::multimap<double, unsigned int> sortedBremElems;
00470 block.associatedElements( ecalBrem_index,linkData,
00471 sortedBremElems,
00472 reco::PFBlockElement::BREM,
00473 reco::PFBlock::LINKTEST_ALL);
00474
00475 bool isGoodBrem = false;
00476 unsigned int sortedBrem_index = CutIndex;
00477 for (std::multimap<double, unsigned int>::iterator ibs = sortedBremElems.begin();
00478 ibs != sortedBremElems.end();ibs++) {
00479 unsigned int temp_sortedBrem_index = ibs->second;
00480 std::multimap<double, unsigned int> sortedGsfElems;
00481 block.associatedElements( temp_sortedBrem_index,linkData,
00482 sortedGsfElems,
00483 reco::PFBlockElement::GSF,
00484 reco::PFBlock::LINKTEST_ALL);
00485 bool enteredInPrimaryGsf = false;
00486 for (std::multimap<double, unsigned int>::iterator igs = sortedGsfElems.begin();
00487 igs != sortedGsfElems.end();igs++) {
00488 const reco::PFBlockElementGsfTrack * gsfCheck =
00489 dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[igs->second]));
00490
00491 if(gsfCheck->trackType(reco::PFBlockElement::T_FROM_GAMMACONV) == false) {
00492 if(igs->second == gsfIs[iEle]) {
00493 isGoodBrem = true;
00494 sortedBrem_index = temp_sortedBrem_index;
00495 }
00496 enteredInPrimaryGsf = true;
00497 break;
00498 }
00499 }
00500 if(enteredInPrimaryGsf)
00501 break;
00502 }
00503
00504 if(isGoodBrem) {
00505
00506
00507
00508 std::multimap<double, unsigned int> ecalOtherGsfElems;
00509 block.associatedElements( ecalBrem_index,linkData,
00510 ecalOtherGsfElems,
00511 reco::PFBlockElement::GSF,
00512 reco::PFBlock::LINKTEST_ALL);
00513 if (ecalOtherGsfElems.size() > 0) {
00514 const reco::PFBlockElementGsfTrack * gsfCheck =
00515 dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[ecalOtherGsfElems.begin()->second]));
00516 if(ecalOtherGsfElems.begin()->second != gsfIs[iEle] &&
00517 gsfCheck->trackType(reco::PFBlockElement::T_FROM_GAMMACONV) == false) {
00518 continue;
00519 }
00520 }
00521
00522 const reco::PFBlockElementBrem * BremEl =
00523 dynamic_cast<const reco::PFBlockElementBrem*>((&elements[sortedBrem_index]));
00524
00525 reco::PFClusterRef clusterRef =
00526 elements[ecalBrem_index].clusterRef();
00527
00528
00529 float sortedBremEcal_deta = fabs(clusterRef->position().eta() - BremEl->positionAtECALEntrance().eta());
00530
00531
00532 if(sortedBremEcal_deta < 0.015) {
00533
00534 cleanedEcalBremElems.insert(pair<unsigned int,unsigned int>(sortedBrem_index,ecalBrem_index));
00535
00536 unsigned int BremTrajP = BremEl->indTrajPoint();
00537 if (BremTrajP > latestBrem_trajP) {
00538 latestBrem_trajP = BremTrajP;
00539 latestBrem_index = sortedBrem_index;
00540 }
00541 if (DebugSetLinksDetailed)
00542 cout << " brem Index " << sortedBrem_index
00543 << " associated cluster " << ecalBrem_index << " BremTrajP " << BremTrajP <<endl;
00544
00545
00546
00547
00548 localactive[ecalBrem_index] = false;
00549 bool alreadyfound = false;
00550 for(unsigned int ii=0;ii<keyBremIndex.size();ii++) {
00551 if (sortedBrem_index == keyBremIndex[ii]) alreadyfound = true;
00552 }
00553 if (alreadyfound == false) {
00554 keyBremIndex.push_back(sortedBrem_index);
00555 localactive[sortedBrem_index] = false;
00556 }
00557 }
00558 }
00559 }
00560 }
00561
00562
00563
00564 vector<unsigned int> GsfElemIndex(0);
00565 vector<unsigned int> EcalIndex(0);
00566
00567
00568 if (ClosestEcalGsf_index < CutIndex) {
00569 GsfElemIndex.push_back(ClosestEcalGsf_index);
00570 localactive[ClosestEcalGsf_index] = false;
00571 for (std::multimap<double, unsigned int>::iterator ii = ecalGsfElems.begin();
00572 ii != ecalGsfElems.end();ii++) {
00573 if(localactive[ii->second]) {
00574
00575 std::multimap<double, unsigned int> ecalOtherGsfElems;
00576 block.associatedElements( ii->second,linkData,
00577 ecalOtherGsfElems,
00578 reco::PFBlockElement::GSF,
00579 reco::PFBlock::LINKTEST_ALL);
00580 if(ecalOtherGsfElems.size()) {
00581 if(ecalOtherGsfElems.begin()->second != gsfIs[iEle]) continue;
00582 }
00583
00584
00585 reco::PFClusterRef clusterRef = elements[(ii->second)].clusterRef();
00586 float etacl = clusterRef->eta();
00587 if( fabs(eta_gsf-etacl) < 0.05) {
00588 GsfElemIndex.push_back(ii->second);
00589 localactive[ii->second] = false;
00590 if (DebugSetLinksDetailed)
00591 cout << " ExtraCluster From Gsf " << ii->second << endl;
00592 }
00593 }
00594 }
00595 }
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628 if(GsfElemIndex.size() == 0){
00629 if(latestBrem_index < CutIndex) {
00630 unsigned int ckey = cleanedEcalBremElems.count(latestBrem_index);
00631 if(ckey == 1) {
00632 unsigned int temp_cal =
00633 cleanedEcalBremElems.find(latestBrem_index)->second;
00634 GsfElemIndex.push_back(temp_cal);
00635 if (DebugSetLinksDetailed)
00636 cout << "******************** Gsf Cluster From Brem " << temp_cal
00637 << " Latest Brem index " << latestBrem_index
00638 << " ************************* " << endl;
00639 }
00640 else{
00641 pair<multimap<unsigned int,unsigned int>::iterator,multimap<unsigned int,unsigned int>::iterator> ret;
00642 ret = cleanedEcalBremElems.equal_range(latestBrem_index);
00643 multimap<unsigned int,unsigned int>::iterator it;
00644 for(it=ret.first; it!=ret.second; ++it) {
00645 GsfElemIndex.push_back((*it).second);
00646 if (DebugSetLinksDetailed)
00647 cout << "******************** Gsf Cluster From Brem " << (*it).second
00648 << " Latest Brem index " << latestBrem_index
00649 << " ************************* " << endl;
00650 }
00651 }
00652
00653 unsigned int elToErase = 0;
00654 for(unsigned int i = 0; i<keyBremIndex.size();i++) {
00655 if(latestBrem_index == keyBremIndex[i]) {
00656 elToErase = i;
00657 }
00658 }
00659 keyBremIndex.erase(keyBremIndex.begin()+elToErase);
00660 }
00661 }
00662
00663
00664
00665
00666
00667 for(unsigned int iConv=0; iConv<gsfIs.size(); iConv++) {
00668 if(iConv != iEle) {
00669
00670 const reco::PFBlockElementGsfTrack * gsfConv =
00671 dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[(gsfIs[iConv])]));
00672
00673
00674 if(gsfConv->trackType(reco::PFBlockElement::T_FROM_GAMMACONV)){
00675 if (DebugSetLinksDetailed)
00676 cout << " PFElectronAlgo:: I'm running on convGsfBrem " << endl;
00677
00678 float conv_dist = block.dist(gsfIs[iConv],gsfIs[iEle],
00679 linkData,reco::PFBlock::LINKTEST_ALL);
00680 if(conv_dist > 0.) {
00681
00682
00683 std::multimap<double, unsigned int> ecalConvElems;
00684 block.associatedElements( gsfIs[iConv],linkData,
00685 ecalConvElems,
00686 reco::PFBlockElement::ECAL,
00687 reco::PFBlock::LINKTEST_ALL );
00688 if(ecalConvElems.size() > 0) {
00689
00690 if(localactive[(ecalConvElems.begin()->second)] == true) {
00691 if (DebugSetLinksDetailed)
00692 cout << " PFElectronAlgo:: convGsfBrem has a ECAL cluster linked and free" << endl;
00693
00694 std::multimap<double, unsigned int> ecalOtherGsfPrimElems;
00695 block.associatedElements( ecalConvElems.begin()->second,linkData,
00696 ecalOtherGsfPrimElems,
00697 reco::PFBlockElement::GSF,
00698 reco::PFBlock::LINKTEST_ALL);
00699 if(ecalOtherGsfPrimElems.size()>0) {
00700 unsigned int gsfprimcheck_index = ecalOtherGsfPrimElems.begin()->second;
00701 const reco::PFBlockElementGsfTrack * gsfCheck =
00702 dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[gsfprimcheck_index]));
00703 if(gsfCheck->trackType(reco::PFBlockElement::T_FROM_GAMMACONV) == false) continue;
00704
00705 reco::PFClusterRef clusterRef = elements[ecalConvElems.begin()->second].clusterRef();
00706 if (DebugSetLinksDetailed)
00707 cout << " PFElectronAlgo: !!!!!!! convGsfBrem ECAL cluster has been stored !!!!!!! "
00708 << " Energy " << clusterRef->energy() << " eta,phi " << clusterRef->position().eta()
00709 <<", " << clusterRef->position().phi() << endl;
00710
00711 GsfElemIndex.push_back(ecalConvElems.begin()->second);
00712 convGsfTrack_.push_back(make_pair(ecalConvElems.begin()->second,gsfIs[iConv]));
00713 localactive[ecalConvElems.begin()->second] = false;
00714
00715 }
00716 }
00717 }
00718 }
00719 }
00720 }
00721 }
00722
00723
00724
00725 EcalIndex.insert(EcalIndex.end(),GsfElemIndex.begin(),GsfElemIndex.end());
00726
00727
00728
00729
00730 for(unsigned int i =0;i<keyBremIndex.size();i++) {
00731 unsigned int ikey = keyBremIndex[i];
00732 unsigned int ckey = cleanedEcalBremElems.count(ikey);
00733 vector<unsigned int> BremElemIndex(0);
00734 if(ckey == 1) {
00735 unsigned int temp_cal =
00736 cleanedEcalBremElems.find(ikey)->second;
00737 BremElemIndex.push_back(temp_cal);
00738 }
00739 else{
00740 pair<multimap<unsigned int,unsigned int>::iterator,multimap<unsigned int,unsigned int>::iterator> ret;
00741 ret = cleanedEcalBremElems.equal_range(ikey);
00742 multimap<unsigned int,unsigned int>::iterator it;
00743 for(it=ret.first; it!=ret.second; ++it) {
00744 BremElemIndex.push_back((*it).second);
00745 }
00746 }
00747 EcalIndex.insert(EcalIndex.end(),BremElemIndex.begin(),BremElemIndex.end());
00748 associatedToBrems_.insert(pair<unsigned int,vector<unsigned int> >(ikey,BremElemIndex));
00749 }
00750
00751
00752
00753 vector<unsigned int> convBremKFTrack;
00754 convBremKFTrack.clear();
00755 if (kfElems.size() > 0) {
00756 for(std::multimap<double, unsigned int>::iterator itkf = kfElems.begin();
00757 itkf != kfElems.end(); ++itkf) {
00758 const reco::PFBlockElementTrack * TrkEl =
00759 dynamic_cast<const reco::PFBlockElementTrack*>((&elements[itkf->second]));
00760 bool isPrim = isPrimaryTrack(*TrkEl,*GsfEl);
00761
00762 if(!isPrim) {
00763
00764
00765 std::multimap<double, unsigned int> ecalConvElems;
00766 block.associatedElements( itkf->second,linkData,
00767 ecalConvElems,
00768 reco::PFBlockElement::ECAL,
00769 reco::PFBlock::LINKTEST_ALL );
00770 if(ecalConvElems.size() > 0) {
00771
00772 TrackRef trkRef = TrkEl->trackRef();
00773
00774 unsigned int Algo = whichTrackAlgo(trkRef);
00775
00776 float secpin = trkRef->p();
00777
00778 const reco::PFBlockElementCluster * clust =
00779 dynamic_cast<const reco::PFBlockElementCluster*>((&elements[(ecalConvElems.begin()->second)]));
00780 float eneclust =clust->clusterRef()->energy();
00781
00782
00783
00784
00785
00786 std::multimap<double, unsigned int> hcalConvElems;
00787 block.associatedElements( itkf->second,linkData,
00788 hcalConvElems,
00789 reco::PFBlockElement::HCAL,
00790 reco::PFBlock::LINKTEST_ALL );
00791
00792 bool isHoHE = false;
00793 bool isHoE = false;
00794 bool isPoHE = false;
00795
00796 float enehcalclust = -1;
00797 if(hcalConvElems.size() > 0) {
00798 const reco::PFBlockElementCluster * clusthcal =
00799 dynamic_cast<const reco::PFBlockElementCluster*>((&elements[(hcalConvElems.begin()->second)]));
00800 enehcalclust =clusthcal->clusterRef()->energy();
00801
00802 if( (enehcalclust / (enehcalclust+eneclust) ) > 0.1 && Algo < 3) {
00803 isHoHE = true;
00804 if(enehcalclust > eneclust)
00805 isHoE = true;
00806 if(secpin > (enehcalclust+eneclust) )
00807 isPoHE = true;
00808 }
00809 }
00810
00811
00812 if(localactive[(ecalConvElems.begin()->second)] == false) {
00813
00814 if(isHoE || isPoHE) {
00815 if (DebugSetLinksDetailed)
00816 cout << "PFElectronAlgo:: LOCKED ECAL REJECTED TRACK FOR H/E or P/(H+E) "
00817 << " H/H+E " << enehcalclust/(enehcalclust+eneclust)
00818 << " H/E " << enehcalclust/eneclust
00819 << " P/(H+E) " << secpin/(enehcalclust+eneclust)
00820 << " HCAL ENE " << enehcalclust
00821 << " ECAL ENE " << eneclust
00822 << " secPIN " << secpin
00823 << " Algo Track " << Algo << endl;
00824 continue;
00825 }
00826
00827
00828 for(unsigned int iecal =0; iecal < EcalIndex.size(); iecal++) {
00829
00830
00831 if(EcalIndex[iecal] == ecalConvElems.begin()->second) {
00832 if (DebugSetLinksDetailed)
00833 cout << " PFElectronAlgo:: Conv Brem Recovery locked cluster and I will lock also the KF track " << endl;
00834 convBremKFTrack.push_back(itkf->second);
00835 }
00836 }
00837 }
00838 else{
00839
00840
00841
00842 if(isHoHE){
00843 if (DebugSetLinksDetailed)
00844 cout << "PFElectronAlgo:: FREE ECAL REJECTED TRACK FOR H/H+E "
00845 << " H/H+E " << (enehcalclust / (enehcalclust+eneclust) )
00846 << " H/E " << enehcalclust/eneclust
00847 << " P/(H+E) " << secpin/(enehcalclust+eneclust)
00848 << " HCAL ENE " << enehcalclust
00849 << " ECAL ENE " << eneclust
00850 << " secPIN " << secpin
00851 << " Algo Track " << Algo << endl;
00852 continue;
00853 }
00854
00855
00856 std::multimap<double, unsigned int> ecalOtherKFPrimElems;
00857 block.associatedElements( ecalConvElems.begin()->second,linkData,
00858 ecalOtherKFPrimElems,
00859 reco::PFBlockElement::TRACK,
00860 reco::PFBlock::LINKTEST_ALL);
00861 if(ecalOtherKFPrimElems.size() > 0) {
00862
00863
00864
00865 bool isFromGSF = false;
00866 for(std::multimap<double, unsigned int>::iterator itclos = kfElems.begin();
00867 itclos != kfElems.end(); ++itclos) {
00868 if(ecalOtherKFPrimElems.begin()->second == itclos->second) {
00869 isFromGSF = true;
00870 break;
00871 }
00872 }
00873 if(isFromGSF){
00874
00875
00876
00877
00878 float Epin = eneclust/secpin;
00879
00880
00881 float totenergy = 0.;
00882 for(unsigned int ikeyecal = 0;
00883 ikeyecal<EcalIndex.size(); ikeyecal++){
00884
00885 bool foundcluster = false;
00886 if(ikeyecal > 0) {
00887 for(unsigned int i2 = 0; i2<ikeyecal-1; i2++) {
00888 if(EcalIndex[ikeyecal] == EcalIndex[i2])
00889 foundcluster = true;
00890 }
00891 }
00892 if(foundcluster) continue;
00893 const reco::PFBlockElementCluster * clusasso =
00894 dynamic_cast<const reco::PFBlockElementCluster*>((&elements[(EcalIndex[ikeyecal])]));
00895 totenergy += clusasso->clusterRef()->energy();
00896 }
00897
00898
00899
00900 if(totenergy == 0.) {
00901 if (DebugSetLinksDetailed)
00902 cout << "PFElectronAlgo:: REJECTED_NULLTOT totenergy " << totenergy << endl;
00903 continue;
00904 }
00905
00906
00907 if(Epin > 3) {
00908 double res_before = fabs((totenergy-Pin_gsf)/Pin_gsf);
00909 double res_after = fabs(((totenergy+eneclust)-Pin_gsf)/Pin_gsf);
00910
00911 if(res_before < res_after) {
00912 if (DebugSetLinksDetailed)
00913 cout << "PFElectronAlgo::REJECTED_RES totenergy " << totenergy << " Pin_gsf " << Pin_gsf << " cluster to secondary " << eneclust
00914 << " Res before " << res_before << " res_after " << res_after << endl;
00915 continue;
00916 }
00917 }
00918
00919 if (DebugSetLinksDetailed)
00920 cout << "PFElectronAlgo:: conv brem found asso to ECAL linked to a secondary KF " << endl;
00921 convBremKFTrack.push_back(itkf->second);
00922 GsfElemIndex.push_back(ecalConvElems.begin()->second);
00923 EcalIndex.push_back(ecalConvElems.begin()->second);
00924 localactive[(ecalConvElems.begin()->second)] = false;
00925 localactive[(itkf->second)] = false;
00926 }
00927 }
00928 }
00929 }
00930 }
00931 }
00932 }
00933
00934
00935 if(EcalIndex.size() > 0 && useEGammaSupercluster_) {
00936 double sumEtEcalInTheCone = 0.;
00937
00938
00939 const reco::PFBlockElementCluster * clust =
00940 dynamic_cast<const reco::PFBlockElementCluster*>((&elements[EcalIndex[0]]));
00941 double PhiFC = clust->clusterRef()->position().Phi();
00942 double EtaFC = clust->clusterRef()->position().Eta();
00943
00944
00945 for(unsigned int iEcal=0; iEcal<ecalIs.size(); iEcal++) {
00946 bool foundcluster = false;
00947 for(unsigned int ikeyecal = 0;
00948 ikeyecal<EcalIndex.size(); ikeyecal++){
00949 if(ecalIs[iEcal] == EcalIndex[ikeyecal])
00950 foundcluster = true;
00951 }
00952
00953
00954 if(foundcluster == false) {
00955 const reco::PFBlockElementCluster * clustExt =
00956 dynamic_cast<const reco::PFBlockElementCluster*>((&elements[ecalIs[iEcal]]));
00957 double eta_clust = clustExt->clusterRef()->position().Eta();
00958 double phi_clust = clustExt->clusterRef()->position().Phi();
00959 double theta_clust = clustExt->clusterRef()->position().Theta();
00960 double deta_clust = eta_clust - EtaFC;
00961 double dphi_clust = phi_clust - PhiFC;
00962 if ( dphi_clust < -M_PI )
00963 dphi_clust = dphi_clust + 2.*M_PI;
00964 else if ( dphi_clust > M_PI )
00965 dphi_clust = dphi_clust - 2.*M_PI;
00966 double DR = sqrt(deta_clust*deta_clust+
00967 dphi_clust*dphi_clust);
00968
00969
00970 if(fabs(deta_clust) > 0.05 && DR < coneEcalIsoForEgammaSC_) {
00971 vector<double> ps1Ene(0);
00972 vector<double> ps2Ene(0);
00973 double ps1,ps2;
00974 ps1=ps2=0.;
00975 double EE_calib = thePFEnergyCalibration_->energyEm(*(clustExt->clusterRef()),ps1Ene,ps2Ene,ps1,ps2,applyCrackCorrections_);
00976 double ET_calib = EE_calib*sin(theta_clust);
00977 sumEtEcalInTheCone += ET_calib;
00978 }
00979 }
00980 }
00981
00982
00983 unsigned int sumNTracksInTheCone = 0;
00984 double sumPtTracksInTheCone = 0.;
00985 for(unsigned int iTrack=0; iTrack<trackIs.size(); iTrack++) {
00986
00987 if(localactive[(trackIs[iTrack])]==true) {
00988 const reco::PFBlockElementTrack * kfEle =
00989 dynamic_cast<const reco::PFBlockElementTrack*>((&elements[(trackIs[iTrack])]));
00990 reco::TrackRef trkref = kfEle->trackRef();
00991 if (trkref.isNonnull()) {
00992 double deta_trk = trkref->eta() - RefGSF->etaMode();
00993 double dphi_trk = trkref->phi() - RefGSF->phiMode();
00994 if ( dphi_trk < -M_PI )
00995 dphi_trk = dphi_trk + 2.*M_PI;
00996 else if ( dphi_trk > M_PI )
00997 dphi_trk = dphi_trk - 2.*M_PI;
00998 double DR = sqrt(deta_trk*deta_trk+
00999 dphi_trk*dphi_trk);
01000
01001 reco::HitPattern kfHitPattern = trkref->hitPattern();
01002 int NValPixelHit = kfHitPattern.numberOfValidPixelHits();
01003
01004 if(DR < coneTrackIsoForEgammaSC_ && NValPixelHit >=3) {
01005 sumNTracksInTheCone++;
01006 sumPtTracksInTheCone+=trkref->pt();
01007 }
01008 }
01009 }
01010 }
01011
01012
01013 bool isBarrelIsolated = false;
01014 if( fabs(EtaFC < 1.478) &&
01015 (sumEtEcalInTheCone < sumEtEcalIsoForEgammaSC_barrel_ &&
01016 (sumNTracksInTheCone < nTrackIsoForEgammaSC_ || sumPtTracksInTheCone < sumPtTrackIsoForEgammaSC_barrel_)))
01017 isBarrelIsolated = true;
01018
01019
01020 bool isEndcapIsolated = false;
01021 if( fabs(EtaFC >= 1.478) &&
01022 (sumEtEcalInTheCone < sumEtEcalIsoForEgammaSC_endcap_ &&
01023 (sumNTracksInTheCone < nTrackIsoForEgammaSC_ || sumPtTracksInTheCone < sumPtTrackIsoForEgammaSC_endcap_)))
01024 isEndcapIsolated = true;
01025
01026
01027
01028 if(DebugSetLinksDetailed) {
01029 if(fabs(EtaFC < 1.478) && isBarrelIsolated == false) {
01030 cout << "**** PFElectronAlgo:: SUPERCLUSTER FOUND BUT FAILS ISOLATION:BARREL *** "
01031 << " sumEtEcalInTheCone " <<sumEtEcalInTheCone
01032 << " sumNTracksInTheCone " << sumNTracksInTheCone
01033 << " sumPtTracksInTheCone " << sumPtTracksInTheCone << endl;
01034 }
01035 if(fabs(EtaFC >= 1.478) && isEndcapIsolated == false) {
01036 cout << "**** PFElectronAlgo:: SUPERCLUSTER FOUND BUT FAILS ISOLATION:ENDCAP *** "
01037 << " sumEtEcalInTheCone " <<sumEtEcalInTheCone
01038 << " sumNTracksInTheCone " << sumNTracksInTheCone
01039 << " sumPtTracksInTheCone " << sumPtTracksInTheCone << endl;
01040 }
01041 }
01042
01043
01044
01045
01046 if(isBarrelIsolated || isEndcapIsolated ) {
01047
01048
01049
01050 double totenergy = 0.;
01051 for(unsigned int ikeyecal = 0;
01052 ikeyecal<EcalIndex.size(); ikeyecal++){
01053
01054 bool foundcluster = false;
01055 if(ikeyecal > 0) {
01056 for(unsigned int i2 = 0; i2<ikeyecal-1; i2++) {
01057 if(EcalIndex[ikeyecal] == EcalIndex[i2])
01058 foundcluster = true;;
01059 }
01060 }
01061 if(foundcluster) continue;
01062 const reco::PFBlockElementCluster * clusasso =
01063 dynamic_cast<const reco::PFBlockElementCluster*>((&elements[(EcalIndex[ikeyecal])]));
01064 totenergy += clusasso->clusterRef()->energy();
01065 }
01066
01067
01068
01069
01070 for(unsigned int ikeyecal = 0;
01071 ikeyecal<EcalIndex.size(); ikeyecal++){
01072
01073 bool foundcluster = false;
01074 if(ikeyecal > 0) {
01075 for(unsigned int i2 = 0; i2<ikeyecal-1; i2++) {
01076 if(EcalIndex[ikeyecal] == EcalIndex[i2])
01077 foundcluster = true;
01078 }
01079 }
01080 if(foundcluster) continue;
01081
01082
01083 std::multimap<double, unsigned int> ecalFromSuperClusterElems;
01084 block.associatedElements( EcalIndex[ikeyecal],linkData,
01085 ecalFromSuperClusterElems,
01086 reco::PFBlockElement::ECAL,
01087 reco::PFBlock::LINKTEST_ALL);
01088 if(ecalFromSuperClusterElems.size() > 0) {
01089 for(std::multimap<double, unsigned int>::iterator itsc = ecalFromSuperClusterElems.begin();
01090 itsc != ecalFromSuperClusterElems.end(); ++itsc) {
01091 if(localactive[itsc->second] == false) {
01092 continue;
01093 }
01094
01095 std::multimap<double, unsigned int> ecalOtherKFPrimElems;
01096 block.associatedElements( itsc->second,linkData,
01097 ecalOtherKFPrimElems,
01098 reco::PFBlockElement::TRACK,
01099 reco::PFBlock::LINKTEST_ALL);
01100 if(ecalOtherKFPrimElems.size() > 0) {
01101 if(localactive[ecalOtherKFPrimElems.begin()->second] == true) {
01102 if (DebugSetLinksDetailed)
01103 cout << "**** PFElectronAlgo:: SUPERCLUSTER FOUND BUT FAILS KF VETO *** " << endl;
01104 continue;
01105 }
01106 }
01107 bool isInTheEtaRange = false;
01108 const reco::PFBlockElementCluster * clustToAdd =
01109 dynamic_cast<const reco::PFBlockElementCluster*>((&elements[itsc->second]));
01110 double deta_clustToAdd = clustToAdd->clusterRef()->position().Eta() - EtaFC;
01111 double ene_clustToAdd = clustToAdd->clusterRef()->energy();
01112
01113 if(fabs(deta_clustToAdd) < 0.05)
01114 isInTheEtaRange = true;
01115
01116
01117 bool isBetterEpin = false;
01118 if(isInTheEtaRange == false ) {
01119 if (DebugSetLinksDetailed)
01120 cout << "**** PFElectronAlgo:: SUPERCLUSTER FOUND BUT FAILS GAMMA DETA RANGE *** "
01121 << fabs(deta_clustToAdd) << endl;
01122
01123 if(KfGsf_index < CutIndex) {
01124
01125 double res_before_gsf = fabs((totenergy-Pin_gsf)/Pin_gsf);
01126 double res_after_gsf = fabs(((totenergy+ene_clustToAdd)-Pin_gsf)/Pin_gsf);
01127
01128
01129 const reco::PFBlockElementTrack * trackEl =
01130 dynamic_cast<const reco::PFBlockElementTrack*>((&elements[KfGsf_index]));
01131 double Pin_kf = trackEl->trackRef()->p();
01132 double res_before_kf = fabs((totenergy-Pin_kf)/Pin_kf);
01133 double res_after_kf = fabs(((totenergy+ene_clustToAdd)-Pin_kf)/Pin_kf);
01134
01135
01136 if(res_after_gsf < res_before_gsf && res_after_kf < res_before_kf ) {
01137 isBetterEpin = true;
01138 }
01139 else {
01140 if (DebugSetLinksDetailed)
01141 cout << "**** PFElectronAlgo:: SUPERCLUSTER FOUND AND FAILS ALSO RES_EPIN"
01142 << " tot energy " << totenergy
01143 << " Pin_gsf " << Pin_gsf
01144 << " Pin_kf " << Pin_kf
01145 << " cluster from SC to ADD " << ene_clustToAdd
01146 << " Res before GSF " << res_before_gsf << " res_after_gsf " << res_after_gsf
01147 << " Res before KF " << res_before_kf << " res_after_kf " << res_after_kf << endl;
01148 }
01149 }
01150 }
01151
01152 if(isInTheEtaRange || isBetterEpin) {
01153 if (DebugSetLinksDetailed)
01154 cout << "!!!! PFElectronAlgo:: ECAL from SUPERCLUSTER FOUND !!!!! " << endl;
01155 GsfElemIndex.push_back(itsc->second);
01156 EcalIndex.push_back(itsc->second);
01157 localactive[(itsc->second)] = false;
01158 }
01159 }
01160 }
01161 }
01162 }
01163 }
01164
01165
01166 if(KfGsf_index < CutIndex)
01167 GsfElemIndex.push_back(KfGsf_index);
01168 else if(KfGsf_secondIndex < CutIndex)
01169 GsfElemIndex.push_back(KfGsf_secondIndex);
01170
01171
01172 GsfElemIndex.insert(GsfElemIndex.end(),convBremKFTrack.begin(),convBremKFTrack.end());
01173 GsfElemIndex.insert(GsfElemIndex.end(),keyBremIndex.begin(),keyBremIndex.end());
01174 associatedToGsf_.insert(pair<unsigned int, vector<unsigned int> >(gsfIs[iEle],GsfElemIndex));
01175
01176
01177 for(unsigned int ikeyecal = 0;
01178 ikeyecal<EcalIndex.size(); ikeyecal++){
01179
01180
01181 vector<unsigned int> EcalElemsIndex(0);
01182
01183 std::multimap<double, unsigned int> PS1Elems;
01184 block.associatedElements( EcalIndex[ikeyecal],linkData,
01185 PS1Elems,
01186 reco::PFBlockElement::PS1,
01187 reco::PFBlock::LINKTEST_ALL );
01188 for( std::multimap<double, unsigned int>::iterator it = PS1Elems.begin();
01189 it != PS1Elems.end();it++) {
01190 unsigned int index = it->second;
01191 if(localactive[index] == true) {
01192
01193
01194 std::multimap<double, unsigned> sortedECAL;
01195 block.associatedElements( index, linkData,
01196 sortedECAL,
01197 reco::PFBlockElement::ECAL,
01198 reco::PFBlock::LINKTEST_ALL );
01199 unsigned jEcal = sortedECAL.begin()->second;
01200 if ( jEcal != EcalIndex[ikeyecal]) continue;
01201
01202
01203 EcalElemsIndex.push_back(index);
01204 localactive[index] = false;
01205 }
01206 }
01207
01208 std::multimap<double, unsigned int> PS2Elems;
01209 block.associatedElements( EcalIndex[ikeyecal],linkData,
01210 PS2Elems,
01211 reco::PFBlockElement::PS2,
01212 reco::PFBlock::LINKTEST_ALL );
01213 for( std::multimap<double, unsigned int>::iterator it = PS2Elems.begin();
01214 it != PS2Elems.end();it++) {
01215 unsigned int index = it->second;
01216 if(localactive[index] == true) {
01217
01218 std::multimap<double, unsigned> sortedECAL;
01219 block.associatedElements( index, linkData,
01220 sortedECAL,
01221 reco::PFBlockElement::ECAL,
01222 reco::PFBlock::LINKTEST_ALL );
01223 unsigned jEcal = sortedECAL.begin()->second;
01224 if ( jEcal != EcalIndex[ikeyecal]) continue;
01225
01226 EcalElemsIndex.push_back(index);
01227 localactive[index] = false;
01228 }
01229 }
01230 if(ikeyecal == 0) {
01231
01232
01233
01234 std::multimap<double, unsigned int> hcalGsfElems;
01235 block.associatedElements( gsfIs[iEle],linkData,
01236 hcalGsfElems,
01237 reco::PFBlockElement::HCAL,
01238 reco::PFBlock::LINKTEST_ALL );
01239 for( std::multimap<double, unsigned int>::iterator it = hcalGsfElems.begin();
01240 it != hcalGsfElems.end();it++) {
01241 unsigned int index = it->second;
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254 EcalElemsIndex.push_back(index);
01255 localactive[index] = false;
01256
01257
01258 }
01259
01260 if(hcalGsfElems.size() == 0 && ClosestEcalWithKf == true) {
01261 std::multimap<double, unsigned int> hcalKfElems;
01262 block.associatedElements( KfGsf_index,linkData,
01263 hcalKfElems,
01264 reco::PFBlockElement::HCAL,
01265 reco::PFBlock::LINKTEST_ALL );
01266 for( std::multimap<double, unsigned int>::iterator it = hcalKfElems.begin();
01267 it != hcalKfElems.end();it++) {
01268 unsigned int index = it->second;
01269 if(localactive[index] == true) {
01270
01271
01272 std::multimap<double, unsigned> sortedKf;
01273 block.associatedElements( index, linkData,
01274 sortedKf,
01275 reco::PFBlockElement::TRACK,
01276 reco::PFBlock::LINKTEST_ALL );
01277 unsigned jKf = sortedKf.begin()->second;
01278 if ( jKf != KfGsf_index) continue;
01279 EcalElemsIndex.push_back(index);
01280 localactive[index] = false;
01281 }
01282 }
01283 }
01284
01285 std::multimap<double, unsigned int> kfEtraElems;
01286 block.associatedElements( EcalIndex[ikeyecal],linkData,
01287 kfEtraElems,
01288 reco::PFBlockElement::TRACK,
01289 reco::PFBlock::LINKTEST_ALL );
01290 if(kfEtraElems.size() > 0) {
01291 for( std::multimap<double, unsigned int>::iterator it = kfEtraElems.begin();
01292 it != kfEtraElems.end();it++) {
01293 unsigned int index = it->second;
01294
01295
01296
01297
01298
01299
01300
01301 bool thisIsAMuon = false;
01302 thisIsAMuon = PFMuonAlgo::isMuon(elements[index]);
01303 if (DebugSetLinksDetailed && thisIsAMuon)
01304 cout << " This is a Muon: index " << index << endl;
01305 if(localactive[index] == true && !thisIsAMuon) {
01306 if(index != KfGsf_index) {
01307
01308
01309 std::multimap<double, unsigned> sortedECAL;
01310 block.associatedElements( index, linkData,
01311 sortedECAL,
01312 reco::PFBlockElement::ECAL,
01313 reco::PFBlock::LINKTEST_ALL );
01314 unsigned jEcal = sortedECAL.begin()->second;
01315 if ( jEcal != EcalIndex[ikeyecal]) continue;
01316 EcalElemsIndex.push_back(index);
01317 localactive[index] = false;
01318 }
01319 }
01320 }
01321 }
01322
01323 }
01324 associatedToEcal_.insert(pair<unsigned int,vector<unsigned int> >(EcalIndex[ikeyecal],EcalElemsIndex));
01325 }
01326 }
01327 }
01328
01329
01330
01331
01332
01333 if (DebugSetLinksSummary) {
01334 if(IsThereAGoodGSFTrack) {
01335 if (DebugSetLinksSummary) cout << " -- The Link Summary --" << endl;
01336 for(map<unsigned int,vector<unsigned int> >::iterator it = associatedToGsf_.begin();
01337 it != associatedToGsf_.end(); it++) {
01338
01339 if (DebugSetLinksSummary) cout << " AssoGsf " << it->first << endl;
01340 vector<unsigned int> eleasso = it->second;
01341 for(unsigned int i=0;i<eleasso.size();i++) {
01342 PFBlockElement::Type type = elements[eleasso[i]].type();
01343 if(type == reco::PFBlockElement::BREM) {
01344 if (DebugSetLinksSummary)
01345 cout << " AssoGsfElements BREM " << eleasso[i] << endl;
01346 }
01347 else if(type == reco::PFBlockElement::ECAL) {
01348 if (DebugSetLinksSummary)
01349 cout << " AssoGsfElements ECAL " << eleasso[i] << endl;
01350 }
01351 else if(type == reco::PFBlockElement::TRACK) {
01352 if (DebugSetLinksSummary)
01353 cout << " AssoGsfElements KF " << eleasso[i] << endl;
01354 }
01355 else {
01356 if (DebugSetLinksSummary)
01357 cout << " AssoGsfElements ????? " << eleasso[i] << endl;
01358 }
01359 }
01360 }
01361
01362 for(map<unsigned int,vector<unsigned int> >::iterator it = associatedToBrems_.begin();
01363 it != associatedToBrems_.end(); it++) {
01364 if (DebugSetLinksSummary) cout << " AssoBrem " << it->first << endl;
01365 vector<unsigned int> eleasso = it->second;
01366 for(unsigned int i=0;i<eleasso.size();i++) {
01367 PFBlockElement::Type type = elements[eleasso[i]].type();
01368 if(type == reco::PFBlockElement::ECAL) {
01369 if (DebugSetLinksSummary)
01370 cout << " AssoBremElements ECAL " << eleasso[i] << endl;
01371 }
01372 else {
01373 if (DebugSetLinksSummary)
01374 cout << " AssoBremElements ????? " << eleasso[i] << endl;
01375 }
01376 }
01377 }
01378
01379 for(map<unsigned int,vector<unsigned int> >::iterator it = associatedToEcal_.begin();
01380 it != associatedToEcal_.end(); it++) {
01381 if (DebugSetLinksSummary) cout << " AssoECAL " << it->first << endl;
01382 vector<unsigned int> eleasso = it->second;
01383 for(unsigned int i=0;i<eleasso.size();i++) {
01384 PFBlockElement::Type type = elements[eleasso[i]].type();
01385 if(type == reco::PFBlockElement::PS1) {
01386 if (DebugSetLinksSummary)
01387 cout << " AssoECALElements PS1 " << eleasso[i] << endl;
01388 }
01389 else if(type == reco::PFBlockElement::PS2) {
01390 if (DebugSetLinksSummary)
01391 cout << " AssoECALElements PS2 " << eleasso[i] << endl;
01392 }
01393 else if(type == reco::PFBlockElement::HCAL) {
01394 if (DebugSetLinksSummary)
01395 cout << " AssoECALElements HCAL " << eleasso[i] << endl;
01396 }
01397 else {
01398 if (DebugSetLinksSummary)
01399 cout << " AssoHCALElements ????? " << eleasso[i] << endl;
01400 }
01401 }
01402 }
01403 if (DebugSetLinksSummary)
01404 cout << "-- End Summary --" << endl;
01405 }
01406
01407 }
01408
01409 return IsThereAGoodGSFTrack;
01410 }
01411
01412 void PFElectronAlgo::SetIDOutputs(const reco::PFBlockRef& blockRef,
01413 AssMap& associatedToGsf_,
01414 AssMap& associatedToBrems_,
01415 AssMap& associatedToEcal_){
01416
01417 const reco::PFBlock& block = *blockRef;
01418 PFBlock::LinkData linkData = block.linkData();
01419 const edm::OwnVector< reco::PFBlockElement >& elements = block.elements();
01420 bool DebugIDOutputs = false;
01421 if(DebugIDOutputs) cout << " ######## Enter in SetIDOutputs #########" << endl;
01422
01423 unsigned int cgsf=0;
01424 for (map<unsigned int,vector<unsigned int> >::iterator igsf = associatedToGsf_.begin();
01425 igsf != associatedToGsf_.end(); igsf++,cgsf++) {
01426
01427 float Ene_ecalgsf = 0.;
01428 float Ene_hcalgsf = 0.;
01429 double sigmaEtaEta = 0.;
01430 float deta_gsfecal = 0.;
01431 float Ene_ecalbrem = 0.;
01432 float Ene_extraecalgsf = 0.;
01433 bool LateBrem = false;
01434
01435 int FirstBrem = 1000;
01436 unsigned int ecalGsf_index = 100000;
01437 unsigned int kf_index = 100000;
01438
01439 int NumBrem = 0;
01440 reco::TrackRef RefKF;
01441 double posX=0.;
01442 double posY=0.;
01443 double posZ=0.;
01444
01445 unsigned int gsf_index = igsf->first;
01446 const reco::PFBlockElementGsfTrack * GsfEl =
01447 dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[gsf_index]));
01448 reco::GsfTrackRef RefGSF = GsfEl->GsftrackRef();
01449 float Ein_gsf = 0.;
01450 if (RefGSF.isNonnull()) {
01451 float m_el=0.00051;
01452 Ein_gsf =sqrt(RefGSF->pMode()*
01453 RefGSF->pMode()+m_el*m_el);
01454
01455 }
01456 float Eout_gsf = GsfEl->Pout().t();
01457 float Etaout_gsf = GsfEl->positionAtECALEntrance().eta();
01458
01459
01460 if (DebugIDOutputs)
01461 cout << " setIdOutput! GSF Track: Ein " << Ein_gsf
01462 << " eta,phi " << Etaout_gsf
01463 <<", " << GsfEl->positionAtECALEntrance().phi() << endl;
01464
01465
01466 vector<unsigned int> assogsf_index = igsf->second;
01467 bool FirstEcalGsf = true;
01468 for (unsigned int ielegsf=0;ielegsf<assogsf_index.size();ielegsf++) {
01469 PFBlockElement::Type assoele_type = elements[(assogsf_index[ielegsf])].type();
01470
01471
01472
01473 if(assoele_type == reco::PFBlockElement::TRACK) {
01474 const reco::PFBlockElementTrack * KfTk =
01475 dynamic_cast<const reco::PFBlockElementTrack*>((&elements[(assogsf_index[ielegsf])]));
01476
01477
01478 bool isPrim = isPrimaryTrack(*KfTk,*GsfEl);
01479 if(!isPrim) continue;
01480 RefKF = KfTk->trackRef();
01481 kf_index = assogsf_index[ielegsf];
01482 }
01483
01484
01485 if (assoele_type == reco::PFBlockElement::ECAL) {
01486 unsigned int keyecalgsf = assogsf_index[ielegsf];
01487 vector<unsigned int> assoecalgsf_index = associatedToEcal_.find(keyecalgsf)->second;
01488
01489 vector<double> ps1Ene(0);
01490 vector<double> ps2Ene(0);
01491 for(unsigned int ips =0; ips<assoecalgsf_index.size();ips++) {
01492 PFBlockElement::Type typeassoecal = elements[(assoecalgsf_index[ips])].type();
01493 if (typeassoecal == reco::PFBlockElement::PS1) {
01494 PFClusterRef psref = elements[(assoecalgsf_index[ips])].clusterRef();
01495 ps1Ene.push_back(psref->energy());
01496 }
01497 if (typeassoecal == reco::PFBlockElement::PS2) {
01498 PFClusterRef psref = elements[(assoecalgsf_index[ips])].clusterRef();
01499 ps2Ene.push_back(psref->energy());
01500 }
01501 if (typeassoecal == reco::PFBlockElement::HCAL) {
01502 const reco::PFBlockElementCluster * clust =
01503 dynamic_cast<const reco::PFBlockElementCluster*>((&elements[(assoecalgsf_index[ips])]));
01504 Ene_hcalgsf+=clust->clusterRef()->energy();
01505 }
01506 }
01507 if (FirstEcalGsf) {
01508 FirstEcalGsf = false;
01509 ecalGsf_index = assogsf_index[ielegsf];
01510 reco::PFClusterRef clusterRef = elements[(assogsf_index[ielegsf])].clusterRef();
01511 double ps1,ps2;
01512 ps1=ps2=0.;
01513
01514 Ene_ecalgsf = thePFEnergyCalibration_->energyEm(*clusterRef,ps1Ene,ps2Ene,ps1,ps2,applyCrackCorrections_);
01515
01516 posX += Ene_ecalgsf * clusterRef->position().X();
01517 posY += Ene_ecalgsf * clusterRef->position().Y();
01518 posZ += Ene_ecalgsf * clusterRef->position().Z();
01519
01520 if (DebugIDOutputs)
01521 cout << " setIdOutput! GSF ECAL Cluster E " << Ene_ecalgsf
01522 << " eta,phi " << clusterRef->position().eta()
01523 <<", " << clusterRef->position().phi() << endl;
01524
01525 deta_gsfecal = clusterRef->position().eta() - Etaout_gsf;
01526
01527 vector< const reco::PFCluster * > pfClust_vec(0);
01528 pfClust_vec.clear();
01529 pfClust_vec.push_back(&(*clusterRef));
01530
01531 PFClusterWidthAlgo pfwidth(pfClust_vec);
01532 sigmaEtaEta = pfwidth.pflowSigmaEtaEta();
01533
01534
01535 }
01536 else {
01537 reco::PFClusterRef clusterRef = elements[(assogsf_index[ielegsf])].clusterRef();
01538 float TempClus_energy = thePFEnergyCalibration_->energyEm(*clusterRef,ps1Ene,ps2Ene,applyCrackCorrections_);
01539 Ene_extraecalgsf += TempClus_energy;
01540 posX += TempClus_energy * clusterRef->position().X();
01541 posY += TempClus_energy * clusterRef->position().Y();
01542 posZ += TempClus_energy * clusterRef->position().Z();
01543
01544 if (DebugIDOutputs)
01545 cout << " setIdOutput! Extra ECAL Cluster E "
01546 << TempClus_energy << " Tot " << Ene_extraecalgsf << endl;
01547 }
01548 }
01549
01550
01551 if (assoele_type == reco::PFBlockElement::BREM) {
01552 unsigned int brem_index = assogsf_index[ielegsf];
01553 const reco::PFBlockElementBrem * BremEl =
01554 dynamic_cast<const reco::PFBlockElementBrem*>((&elements[brem_index]));
01555 int TrajPos = (BremEl->indTrajPoint())-2;
01556
01557 if (TrajPos < FirstBrem) FirstBrem = TrajPos;
01558
01559 vector<unsigned int> assobrem_index = associatedToBrems_.find(brem_index)->second;
01560 for (unsigned int ibrem = 0; ibrem < assobrem_index.size(); ibrem++){
01561 if (elements[(assobrem_index[ibrem])].type() == reco::PFBlockElement::ECAL) {
01562 unsigned int keyecalbrem = assobrem_index[ibrem];
01563 vector<unsigned int> assoelebrem_index = associatedToEcal_.find(keyecalbrem)->second;
01564 vector<double> ps1EneFromBrem(0);
01565 vector<double> ps2EneFromBrem(0);
01566 for (unsigned int ielebrem=0; ielebrem<assoelebrem_index.size();ielebrem++) {
01567 if (elements[(assoelebrem_index[ielebrem])].type() == reco::PFBlockElement::PS1) {
01568 PFClusterRef psref = elements[(assoelebrem_index[ielebrem])].clusterRef();
01569 ps1EneFromBrem.push_back(psref->energy());
01570 }
01571 if (elements[(assoelebrem_index[ielebrem])].type() == reco::PFBlockElement::PS2) {
01572 PFClusterRef psref = elements[(assoelebrem_index[ielebrem])].clusterRef();
01573 ps2EneFromBrem.push_back(psref->energy());
01574 }
01575 }
01576
01577 if( assobrem_index[ibrem] != ecalGsf_index) {
01578 reco::PFClusterRef clusterRef =
01579 elements[(assobrem_index[ibrem])].clusterRef();
01580 float BremClus_energy = thePFEnergyCalibration_->energyEm(*clusterRef,ps1EneFromBrem,ps2EneFromBrem,applyCrackCorrections_);
01581 Ene_ecalbrem += BremClus_energy;
01582 posX += BremClus_energy * clusterRef->position().X();
01583 posY += BremClus_energy * clusterRef->position().Y();
01584 posZ += BremClus_energy * clusterRef->position().Z();
01585
01586 NumBrem++;
01587 if (DebugIDOutputs) cout << " setIdOutput::BREM Cluster "
01588 << BremClus_energy << " eta,phi "
01589 << clusterRef->position().eta() <<", "
01590 << clusterRef->position().phi() << endl;
01591 }
01592 else {
01593 LateBrem = true;
01594 }
01595 }
01596 }
01597 }
01598 }
01599 if (Ene_ecalgsf > 0.) {
01600
01601
01602
01603 if(RefGSF.isNonnull()) {
01604 PFCandidateElectronExtra myExtra(RefGSF) ;
01605 myExtra.setGsfTrackPout(GsfEl->Pout());
01606 myExtra.setKfTrackRef(RefKF);
01607 float Pt_gsf = RefGSF->ptMode();
01608 lnPt_gsf = log(Pt_gsf);
01609 Eta_gsf = RefGSF->etaMode();
01610
01611
01612 if(RefGSF->ptModeError() > 0.)
01613 dPtOverPt_gsf = RefGSF->ptModeError()/Pt_gsf;
01614
01615 nhit_gsf= RefGSF->hitPattern().trackerLayersWithMeasurement();
01616 chi2_gsf = RefGSF->normalizedChi2();
01617
01618 DPtOverPt_gsf = (RefGSF->ptMode() - GsfEl->Pout().pt())/RefGSF->ptMode();
01619
01620
01621 nhit_kf = 0;
01622 chi2_kf = -0.01;
01623 DPtOverPt_kf = -0.01;
01624 if (RefKF.isNonnull()) {
01625 nhit_kf= RefKF->hitPattern().trackerLayersWithMeasurement();
01626 chi2_kf = RefKF->normalizedChi2();
01627
01628
01629
01630
01631
01632 }
01633
01634
01635 EtotPinMode = (Ene_ecalgsf + Ene_ecalbrem + Ene_extraecalgsf) / Ein_gsf;
01636 EGsfPoutMode = Ene_ecalgsf/Eout_gsf;
01637 EtotBremPinPoutMode = Ene_ecalbrem /(Ein_gsf - Eout_gsf);
01638 DEtaGsfEcalClust = fabs(deta_gsfecal);
01639 myExtra.setSigmaEtaEta(sigmaEtaEta);
01640 myExtra.setDeltaEta(DEtaGsfEcalClust);
01641 SigmaEtaEta = log(sigmaEtaEta);
01642
01643 lateBrem = -1;
01644 firstBrem = -1;
01645 earlyBrem = -1;
01646 if(NumBrem > 0) {
01647 if (LateBrem) lateBrem = 1;
01648 else lateBrem = 0;
01649 firstBrem = FirstBrem;
01650 if(FirstBrem < 4) earlyBrem = 1;
01651 else earlyBrem = 0;
01652 }
01653
01654 HOverHE = Ene_hcalgsf/(Ene_hcalgsf + Ene_ecalgsf);
01655 HOverPin = Ene_hcalgsf / Ein_gsf;
01656 myExtra.setHadEnergy(Ene_hcalgsf);
01657 myExtra.setEarlyBrem(earlyBrem);
01658 myExtra.setLateBrem(lateBrem);
01659
01660
01661
01662 if(DPtOverPt_gsf < -0.2) DPtOverPt_gsf = -0.2;
01663 if(DPtOverPt_gsf > 1.) DPtOverPt_gsf = 1.;
01664
01665 if(dPtOverPt_gsf > 0.3) dPtOverPt_gsf = 0.3;
01666
01667 if(chi2_gsf > 10.) chi2_gsf = 10.;
01668
01669 if(DPtOverPt_kf < -0.2) DPtOverPt_kf = -0.2;
01670 if(DPtOverPt_kf > 1.) DPtOverPt_kf = 1.;
01671
01672 if(chi2_kf > 10.) chi2_kf = 10.;
01673
01674 if(EtotPinMode < 0.) EtotPinMode = 0.;
01675 if(EtotPinMode > 5.) EtotPinMode = 5.;
01676
01677 if(EGsfPoutMode < 0.) EGsfPoutMode = 0.;
01678 if(EGsfPoutMode > 5.) EGsfPoutMode = 5.;
01679
01680 if(EtotBremPinPoutMode < 0.) EtotBremPinPoutMode = 0.01;
01681 if(EtotBremPinPoutMode > 5.) EtotBremPinPoutMode = 5.;
01682
01683 if(DEtaGsfEcalClust > 0.1) DEtaGsfEcalClust = 0.1;
01684
01685 if(SigmaEtaEta < -14) SigmaEtaEta = -14;
01686
01687 if(HOverPin < 0.) HOverPin = 0.;
01688 if(HOverPin > 5.) HOverPin = 5.;
01689 double mvaValue = tmvaReader_->EvaluateMVA("BDT");
01690
01691
01692 BDToutput_[cgsf] = mvaValue;
01693 myExtra.setMVA(mvaValue);
01694 electronExtra_.push_back(myExtra);
01695
01696
01697
01698 if(mvaValue > mvaEleCut_) {
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712 unsigned int iextratrack = 0;
01713 unsigned int itrackHcalLinked = 0;
01714 float SumExtraKfP = 0.;
01715
01716
01717 double Etotal = Ene_ecalgsf + Ene_ecalbrem + Ene_extraecalgsf;
01718 posX /=Etotal;
01719 posY /=Etotal;
01720 posZ /=Etotal;
01721 math::XYZPoint sc_pflow(posX,posY,posZ);
01722 double ETtotal = Etotal*sin(sc_pflow.Theta());
01723 double phiTrack = RefGSF->phiMode();
01724 double dphi_normalsc = sc_pflow.Phi() - phiTrack;
01725 if ( dphi_normalsc < -M_PI )
01726 dphi_normalsc = dphi_normalsc + 2.*M_PI;
01727 else if ( dphi_normalsc > M_PI )
01728 dphi_normalsc = dphi_normalsc - 2.*M_PI;
01729 dphi_normalsc = fabs(dphi_normalsc);
01730
01731
01732 if(ecalGsf_index < 100000) {
01733 vector<unsigned int> assoecalgsf_index = associatedToEcal_.find(ecalGsf_index)->second;
01734 for(unsigned int itrk =0; itrk<assoecalgsf_index.size();itrk++) {
01735 PFBlockElement::Type typeassoecal = elements[(assoecalgsf_index[itrk])].type();
01736 if(typeassoecal == reco::PFBlockElement::TRACK) {
01737 const reco::PFBlockElementTrack * kfTk =
01738 dynamic_cast<const reco::PFBlockElementTrack*>((&elements[(assoecalgsf_index[itrk])]));
01739
01740
01741
01742
01743
01744
01745 reco::TrackRef trackref = kfTk->trackRef();
01746 unsigned int Algo = whichTrackAlgo(trackref);
01747
01748
01749 int nexhits = trackref->trackerExpectedHitsInner().numberOfLostHits();
01750
01751 if(Algo < 3 && nexhits == 0) {
01752
01753 if(DebugIDOutputs)
01754 cout << " The ecalGsf cluster is not isolated: >0 KF extra with algo < 3" << endl;
01755
01756 float p_trk = trackref->p();
01757
01758
01759
01760 if(DebugIDOutputs)
01761 cout << " p_trk " << p_trk
01762 << " nexhits " << nexhits << endl;
01763
01764 SumExtraKfP += p_trk;
01765 iextratrack++;
01766
01767 std::multimap<double, unsigned int> hcalKfElems;
01768 block.associatedElements( assoecalgsf_index[itrk],linkData,
01769 hcalKfElems,
01770 reco::PFBlockElement::HCAL,
01771 reco::PFBlock::LINKTEST_ALL );
01772 if(hcalKfElems.size() > 0) {
01773 itrackHcalLinked++;
01774 }
01775 }
01776 }
01777 }
01778 }
01779 if( iextratrack > 0) {
01780 if(iextratrack > 3 || HOverHE > 0.05 || (SumExtraKfP/Ene_ecalgsf) > 1.
01781 || (ETtotal > 50. && iextratrack > 1 && (Ene_hcalgsf/Ene_ecalgsf) > 0.1) ) {
01782 if(DebugIDOutputs)
01783 cout << " *****This electron candidate is discarded: Non isolated # tracks "
01784 << iextratrack << " HOverHE " << HOverHE
01785 << " SumExtraKfP/Ene_ecalgsf " << SumExtraKfP/Ene_ecalgsf
01786 << " SumExtraKfP " << SumExtraKfP
01787 << " Ene_ecalgsf " << Ene_ecalgsf
01788 << " ETtotal " << ETtotal
01789 << " Ene_hcalgsf/Ene_ecalgsf " << Ene_hcalgsf/Ene_ecalgsf
01790 << endl;
01791
01792 BDToutput_[cgsf] = mvaValue-2.;
01793 lockExtraKf_[cgsf] = false;
01794 }
01795
01796
01797 if( (fabs(1.-EtotPinMode) < 0.2 && (fabs(Eta_gsf) < 1.0 || fabs(Eta_gsf) > 2.0)) ||
01798 ((EtotPinMode < 1.1 && EtotPinMode > 0.6) && (fabs(Eta_gsf) >= 1.0 && fabs(Eta_gsf) <= 2.0))) {
01799 if( fabs(1.-EGsfPoutMode) < 0.5 &&
01800 (itrackHcalLinked == iextratrack) &&
01801 kf_index < 100000 ) {
01802
01803 BDToutput_[cgsf] = mvaValue;
01804 lockExtraKf_[cgsf] = false;
01805 if(DebugIDOutputs)
01806 cout << " *****This electron is reactivated # tracks "
01807 << iextratrack << " #tracks hcal linked " << itrackHcalLinked
01808 << " SumExtraKfP/Ene_ecalgsf " << SumExtraKfP/Ene_ecalgsf
01809 << " EtotPinMode " << EtotPinMode << " EGsfPoutMode " << EGsfPoutMode
01810 << " eta gsf " << fabs(Eta_gsf) << " kf index " << kf_index <<endl;
01811 }
01812 }
01813 }
01814
01815 if (HOverPin > 1. && HOverHE > 0.1 && EtotPinMode < 0.5) {
01816 if(DebugIDOutputs)
01817 cout << " *****This electron candidate is discarded HCAL ENERGY "
01818 << " HOverPin " << HOverPin << " HOverHE " << HOverHE << " EtotPinMode" << EtotPinMode << endl;
01819 BDToutput_[cgsf] = mvaValue-4.;
01820 lockExtraKf_[cgsf] = false;
01821 }
01822
01823
01824
01825
01826 if( EtotPinMode < 0.2 && EGsfPoutMode < 0.2 ) {
01827 if(DebugIDOutputs)
01828 cout << " *****This electron candidate is discarded Low ETOTPIN "
01829 << " EtotPinMode " << EtotPinMode << " EGsfPoutMode " << EGsfPoutMode << endl;
01830 BDToutput_[cgsf] = mvaValue-6.;
01831 }
01832
01833
01834 if(ETtotal > 50. && dphi_normalsc > 0.1 ) {
01835 if(DebugIDOutputs)
01836 cout << " *****This electron candidate is discarded Large ANGLE "
01837 << " ETtotal " << ETtotal << " EGsfPoutMode " << dphi_normalsc << endl;
01838 BDToutput_[cgsf] = mvaValue-6.;
01839 }
01840 }
01841
01842
01843 if (DebugIDOutputs) {
01844 cout << " **** BDT observables ****" << endl;
01845 cout << " < Normalization > " << endl;
01846 cout << " Pt_gsf " << Pt_gsf << " Pin " << Ein_gsf << " Pout " << Eout_gsf
01847 << " Eta_gsf " << Eta_gsf << endl;
01848 cout << " < PureTracking > " << endl;
01849 cout << " dPtOverPt_gsf " << dPtOverPt_gsf
01850 << " DPtOverPt_gsf " << DPtOverPt_gsf
01851 << " chi2_gsf " << chi2_gsf
01852 << " nhit_gsf " << nhit_gsf
01853 << " DPtOverPt_kf " << DPtOverPt_kf
01854 << " chi2_kf " << chi2_kf
01855 << " nhit_kf " << nhit_kf << endl;
01856 cout << " < track-ecal-hcal-ps " << endl;
01857 cout << " EtotPinMode " << EtotPinMode
01858 << " EGsfPoutMode " << EGsfPoutMode
01859 << " EtotBremPinPoutMode " << EtotBremPinPoutMode
01860 << " DEtaGsfEcalClust " << DEtaGsfEcalClust
01861 << " SigmaEtaEta " << SigmaEtaEta
01862 << " HOverHE " << HOverHE << " Hcal energy " << Ene_hcalgsf
01863 << " HOverPin " << HOverPin
01864 << " lateBrem " << lateBrem
01865 << " firstBrem " << firstBrem << endl;
01866 cout << " !!!!!!!!!!!!!!!! the BDT output !!!!!!!!!!!!!!!!!: direct " << mvaValue
01867 << " corrected " << BDToutput_[cgsf] << endl;
01868
01869 }
01870 }
01871 else {
01872 if (DebugIDOutputs)
01873 cout << " Gsf Ref isNULL " << endl;
01874 BDToutput_[cgsf] = -2.;
01875 }
01876 } else {
01877 if (DebugIDOutputs)
01878 cout << " No clusters associated to the gsf " << endl;
01879 BDToutput_[cgsf] = -2.;
01880 }
01881 DebugIDOutputs = false;
01882 }
01883 return;
01884 }
01885
01886
01887
01888 void PFElectronAlgo::SetCandidates(const reco::PFBlockRef& blockRef,
01889 AssMap& associatedToGsf_,
01890 AssMap& associatedToBrems_,
01891 AssMap& associatedToEcal_){
01892
01893 const reco::PFBlock& block = *blockRef;
01894 PFBlock::LinkData linkData = block.linkData();
01895 const edm::OwnVector< reco::PFBlockElement >& elements = block.elements();
01896 PFEnergyResolution pfresol_;
01897
01898
01899 bool DebugIDCandidates = false;
01900
01901
01902
01903 unsigned int cgsf=0;
01904 for (map<unsigned int,vector<unsigned int> >::iterator igsf = associatedToGsf_.begin();
01905 igsf != associatedToGsf_.end(); igsf++,cgsf++) {
01906 unsigned int gsf_index = igsf->first;
01907
01908
01909
01910
01911 int eecal=0;
01912 int hcal=0;
01913 int charge =0;
01914
01915 math::XYZTLorentzVector momentum_kf,momentum_gsf,momentum,momentum_mean;
01916 float dpt=0; float dpt_gsf=0;
01917 float Eene=0; float dene=0; float Hene=0.;
01918 float RawEene = 0.;
01919 double posX=0.;
01920 double posY=0.;
01921 double posZ=0.;
01922 std::vector<float> bremEnergyVec;
01923
01924 std::vector<const PFCluster*> pfSC_Clust_vec;
01925
01926 float de_gs = 0., de_me = 0., de_kf = 0.;
01927 float m_el=0.00051;
01928 int nhit_kf=0; int nhit_gsf=0;
01929 bool has_gsf=false;
01930 bool has_kf=false;
01931 math::XYZTLorentzVector newmomentum;
01932 float ps1TotEne = 0;
01933 float ps2TotEne = 0;
01934 vector<unsigned int> elementsToAdd(0);
01935 reco::TrackRef RefKF;
01936
01937
01938
01939 elementsToAdd.push_back(gsf_index);
01940 const reco::PFBlockElementGsfTrack * GsfEl =
01941 dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[gsf_index]));
01942 const math::XYZPointF& posGsfEcalEntrance = GsfEl->positionAtECALEntrance();
01943 reco::GsfTrackRef RefGSF = GsfEl->GsftrackRef();
01944 if (RefGSF.isNonnull()) {
01945
01946 has_gsf=true;
01947
01948 charge= RefGSF->chargeMode();
01949 nhit_gsf= RefGSF->hitPattern().trackerLayersWithMeasurement();
01950
01951 momentum_gsf.SetPx(RefGSF->pxMode());
01952 momentum_gsf.SetPy(RefGSF->pyMode());
01953 momentum_gsf.SetPz(RefGSF->pzMode());
01954 float ENE=sqrt(RefGSF->pMode()*
01955 RefGSF->pMode()+m_el*m_el);
01956
01957 if( DebugIDCandidates )
01958 cout << "SetCandidates:: GsfTrackRef: Ene " << ENE
01959 << " charge " << charge << " nhits " << nhit_gsf <<endl;
01960
01961 momentum_gsf.SetE(ENE);
01962 dpt_gsf=RefGSF->ptModeError()*
01963 (RefGSF->pMode()/RefGSF->ptMode());
01964
01965 momentum_mean.SetPx(RefGSF->px());
01966 momentum_mean.SetPy(RefGSF->py());
01967 momentum_mean.SetPz(RefGSF->pz());
01968 float ENEm=sqrt(RefGSF->p()*
01969 RefGSF->p()+m_el*m_el);
01970 momentum_mean.SetE(ENEm);
01971
01972
01973 }
01974 else {
01975 if( DebugIDCandidates )
01976 cout << "SetCandidates:: !!!! NULL GSF Track Ref " << endl;
01977 }
01978
01979
01980 vector<unsigned int> assogsf_index = igsf->second;
01981 unsigned int ecalGsf_index = 100000;
01982 bool FirstEcalGsf = true;
01983 for (unsigned int ielegsf=0;ielegsf<assogsf_index.size();ielegsf++) {
01984 PFBlockElement::Type assoele_type = elements[(assogsf_index[ielegsf])].type();
01985 if (assoele_type == reco::PFBlockElement::TRACK) {
01986 elementsToAdd.push_back((assogsf_index[ielegsf]));
01987 const reco::PFBlockElementTrack * KfTk =
01988 dynamic_cast<const reco::PFBlockElementTrack*>((&elements[(assogsf_index[ielegsf])]));
01989
01990 bool isPrim = isPrimaryTrack(*KfTk,*GsfEl);
01991 if(!isPrim) continue;
01992
01993 RefKF = KfTk->trackRef();
01994 if (RefKF.isNonnull()) {
01995 has_kf = true;
01996
01997 nhit_kf=RefKF->hitPattern().trackerLayersWithMeasurement();
01998 momentum_kf.SetPx(RefKF->px());
01999 momentum_kf.SetPy(RefKF->py());
02000 momentum_kf.SetPz(RefKF->pz());
02001 float ENE=sqrt(RefKF->p()*RefKF->p()+m_el*m_el);
02002 if( DebugIDCandidates )
02003 cout << "SetCandidates:: KFTrackRef: Ene " << ENE << " nhits " << nhit_kf << endl;
02004
02005 momentum_kf.SetE(ENE);
02006 }
02007 else {
02008 if( DebugIDCandidates )
02009 cout << "SetCandidates:: !!!! NULL KF Track Ref " << endl;
02010 }
02011 }
02012
02013 if (assoele_type == reco::PFBlockElement::ECAL) {
02014 unsigned int keyecalgsf = assogsf_index[ielegsf];
02015 vector<unsigned int> assoecalgsf_index = associatedToEcal_.find(keyecalgsf)->second;
02016 vector<double> ps1Ene(0);
02017 vector<double> ps2Ene(0);
02018
02019
02020
02021 for(unsigned int ips =0; ips<assoecalgsf_index.size();ips++) {
02022 PFBlockElement::Type typeassoecal = elements[(assoecalgsf_index[ips])].type();
02023 if (typeassoecal == reco::PFBlockElement::PS1) {
02024 PFClusterRef psref = elements[(assoecalgsf_index[ips])].clusterRef();
02025 ps1Ene.push_back(psref->energy());
02026 elementsToAdd.push_back((assoecalgsf_index[ips]));
02027 }
02028 if (typeassoecal == reco::PFBlockElement::PS2) {
02029 PFClusterRef psref = elements[(assoecalgsf_index[ips])].clusterRef();
02030 ps2Ene.push_back(psref->energy());
02031 elementsToAdd.push_back((assoecalgsf_index[ips]));
02032 }
02033 if (typeassoecal == reco::PFBlockElement::HCAL) {
02034 const reco::PFBlockElementCluster * clust =
02035 dynamic_cast<const reco::PFBlockElementCluster*>((&elements[(assoecalgsf_index[ips])]));
02036 elementsToAdd.push_back((assoecalgsf_index[ips]));
02037 Hene+=clust->clusterRef()->energy();
02038 hcal++;
02039 }
02040 }
02041 elementsToAdd.push_back((assogsf_index[ielegsf]));
02042
02043
02044 const reco::PFBlockElementCluster * clust =
02045 dynamic_cast<const reco::PFBlockElementCluster*>((&elements[(assogsf_index[ielegsf])]));
02046
02047 eecal++;
02048
02049 const reco::PFCluster& cl(*clust->clusterRef());
02050
02051
02052
02053 double ps1,ps2;
02054 ps1=ps2=0.;
02055
02056 float EE = thePFEnergyCalibration_->energyEm(cl,ps1Ene,ps2Ene,ps1,ps2,applyCrackCorrections_);
02057
02058
02059 float ceta=cl.position().eta();
02060 float cphi=cl.position().phi();
02061
02062
02063
02064
02065
02066
02067
02068
02069
02070
02071
02072 float dE=pfresol_.getEnergyResolutionEm(EE,cl.position().eta());
02073 if( DebugIDCandidates )
02074 cout << "SetCandidates:: EcalCluster: EneNoCalib " << clust->clusterRef()->energy()
02075 << " eta,phi " << ceta << "," << cphi << " Calib " << EE << " dE " << dE <<endl;
02076
02077 bool elecCluster=false;
02078 if (FirstEcalGsf) {
02079 FirstEcalGsf = false;
02080 elecCluster=true;
02081 ecalGsf_index = assogsf_index[ielegsf];
02082
02083 RawEene += EE;
02084 }
02085
02086
02087 math::XYZTLorentzVector clusterMomentum;
02088 math::XYZPoint direction=cl.position()/cl.position().R();
02089 clusterMomentum.SetPxPyPzE(EE*direction.x(),
02090 EE*direction.y(),
02091 EE*direction.z(),
02092 EE);
02093 reco::PFCandidate cluster_Candidate((elecCluster)?charge:0,
02094 clusterMomentum,
02095 (elecCluster)? reco::PFCandidate::e : reco::PFCandidate::gamma);
02096
02097 cluster_Candidate.setPs1Energy(ps1);
02098 cluster_Candidate.setPs2Energy(ps2);
02099
02100
02101 cluster_Candidate.setEcalEnergy(EE-ps1-ps2,EE);
02102
02103 cluster_Candidate.setPositionAtECALEntrance(math::XYZPointF(cl.position()));
02104 cluster_Candidate.addElementInBlock(blockRef,assogsf_index[ielegsf]);
02105
02106 std::map<unsigned int,std::vector<reco::PFCandidate> >::iterator itcheck=
02107 electronConstituents_.find(cgsf);
02108 if(itcheck==electronConstituents_.end())
02109 {
02110
02111 std::vector<reco::PFCandidate> tmpVec;
02112 tmpVec.push_back(cluster_Candidate);
02113 electronConstituents_.insert(std::pair<unsigned int, std::vector<reco::PFCandidate> >
02114 (cgsf,tmpVec));
02115 }
02116 else
02117 {
02118 itcheck->second.push_back(cluster_Candidate);
02119 }
02120
02121 Eene+=EE;
02122 posX += EE * cl.position().X();
02123 posY += EE * cl.position().Y();
02124 posZ += EE * cl.position().Z();
02125 ps1TotEne+=ps1;
02126 ps2TotEne+=ps2;
02127 dene+=dE*dE;
02128
02129
02130 pfSC_Clust_vec.push_back( &cl );
02131
02132 }
02133
02134
02135
02136
02137 if (assoele_type == reco::PFBlockElement::BREM) {
02138 unsigned int brem_index = assogsf_index[ielegsf];
02139 vector<unsigned int> assobrem_index = associatedToBrems_.find(brem_index)->second;
02140 elementsToAdd.push_back(brem_index);
02141 for (unsigned int ibrem = 0; ibrem < assobrem_index.size(); ibrem++){
02142 if (elements[(assobrem_index[ibrem])].type() == reco::PFBlockElement::ECAL) {
02143
02144 unsigned int keyecalbrem = assobrem_index[ibrem];
02145 const vector<unsigned int>& assoelebrem_index = associatedToEcal_.find(keyecalbrem)->second;
02146 vector<double> ps1EneFromBrem(0);
02147 vector<double> ps2EneFromBrem(0);
02148 float ps1EneFromBremTot=0.;
02149 float ps2EneFromBremTot=0.;
02150 for (unsigned int ielebrem=0; ielebrem<assoelebrem_index.size();ielebrem++) {
02151 if (elements[(assoelebrem_index[ielebrem])].type() == reco::PFBlockElement::PS1) {
02152 PFClusterRef psref = elements[(assoelebrem_index[ielebrem])].clusterRef();
02153 ps1EneFromBrem.push_back(psref->energy());
02154 ps1EneFromBremTot+=psref->energy();
02155 elementsToAdd.push_back(assoelebrem_index[ielebrem]);
02156 }
02157 if (elements[(assoelebrem_index[ielebrem])].type() == reco::PFBlockElement::PS2) {
02158 PFClusterRef psref = elements[(assoelebrem_index[ielebrem])].clusterRef();
02159 ps2EneFromBrem.push_back(psref->energy());
02160 ps2EneFromBremTot+=psref->energy();
02161 elementsToAdd.push_back(assoelebrem_index[ielebrem]);
02162 }
02163 }
02164
02165
02166 if( assobrem_index[ibrem] != ecalGsf_index) {
02167 elementsToAdd.push_back(assobrem_index[ibrem]);
02168 reco::PFClusterRef clusterRef = elements[(assobrem_index[ibrem])].clusterRef();
02169
02170
02171 double ps1=0;
02172 double ps2=0;
02173 float EE = thePFEnergyCalibration_->energyEm(*clusterRef,ps1EneFromBrem,ps2EneFromBrem,ps1,ps2,applyCrackCorrections_);
02174 bremEnergyVec.push_back(EE);
02175
02176 float ceta = clusterRef->position().eta();
02177
02178 float dE=pfresol_.getEnergyResolutionEm(EE,ceta);
02179 if( DebugIDCandidates )
02180 cout << "SetCandidates:: BremCluster: Ene " << EE << " dE " << dE <<endl;
02181
02182 Eene+=EE;
02183 posX += EE * clusterRef->position().X();
02184 posY += EE * clusterRef->position().Y();
02185 posZ += EE * clusterRef->position().Z();
02186 ps1TotEne+=ps1;
02187 ps2TotEne+=ps2;
02188
02189
02190 dene+=dE*dE;
02191
02192
02193 pfSC_Clust_vec.push_back( clusterRef.get() );
02194
02195
02196
02197 math::XYZTLorentzVector photonMomentum;
02198 math::XYZPoint direction=clusterRef->position()/clusterRef->position().R();
02199
02200 photonMomentum.SetPxPyPzE(EE*direction.x(),
02201 EE*direction.y(),
02202 EE*direction.z(),
02203 EE);
02204 reco::PFCandidate photon_Candidate(0,photonMomentum, reco::PFCandidate::gamma);
02205
02206 photon_Candidate.setPs1Energy(ps1);
02207 photon_Candidate.setPs2Energy(ps2);
02208
02209
02210 photon_Candidate.setEcalEnergy(EE-ps1-ps2,EE);
02211
02212 photon_Candidate.setPositionAtECALEntrance(math::XYZPointF(clusterRef->position()));
02213 photon_Candidate.addElementInBlock(blockRef,assobrem_index[ibrem]);
02214
02215
02216 std::map<unsigned int,std::vector<reco::PFCandidate> >::iterator itcheck=
02217 electronConstituents_.find(cgsf);
02218 if(itcheck==electronConstituents_.end())
02219 {
02220
02221 std::vector<reco::PFCandidate> tmpVec;
02222 tmpVec.push_back(photon_Candidate);
02223 electronConstituents_.insert(std::pair<unsigned int, std::vector<reco::PFCandidate> >
02224 (cgsf,tmpVec));
02225 }
02226 else
02227 {
02228 itcheck->second.push_back(photon_Candidate);
02229 }
02230 }
02231 }
02232 }
02233 }
02234 }
02235 if (has_gsf) {
02236
02237
02238 double unCorrEene = Eene;
02239 double absEta = fabs(momentum_gsf.Eta());
02240 double emTheta = momentum_gsf.Theta();
02241 PFClusterWidthAlgo pfSCwidth(pfSC_Clust_vec);
02242 double brLinear = pfSCwidth.pflowPhiWidth()/pfSCwidth.pflowEtaWidth();
02243 pfSC_Clust_vec.clear();
02244
02245 if( DebugIDCandidates )
02246 cout << "PFEelectronAlgo:: absEta " << absEta << " theta " << emTheta
02247 << " EneRaw " << Eene << " Err " << dene;
02248
02249
02250
02251 if(usePFSCEleCalib_ && unCorrEene > 0.) {
02252 if( absEta < 1.5) {
02253 double Etene = Eene*sin(emTheta);
02254 double emBR_e = thePFSCEnergyCalibration_->SCCorrFBremBarrel(Eene, Etene, brLinear);
02255 double emBR_et = emBR_e*sin(emTheta);
02256 double emCorrFull_et = thePFSCEnergyCalibration_->SCCorrEtEtaBarrel(emBR_et, absEta);
02257 Eene = emCorrFull_et/sin(emTheta);
02258 }
02259 else {
02260
02261 double emBR_e = thePFSCEnergyCalibration_->SCCorrFBremEndcap(Eene, absEta, brLinear);
02262 double emBR_et = emBR_e*sin(emTheta);
02263 double emCorrFull_et = thePFSCEnergyCalibration_->SCCorrEtEtaEndcap(emBR_et, absEta);
02264 Eene = emCorrFull_et/sin(emTheta);
02265 }
02266 dene = sqrt(dene)*(Eene/unCorrEene);
02267 dene = dene*dene;
02268 }
02269
02270 if( DebugIDCandidates )
02271 cout << " EneCorrected " << Eene << " Err " << dene << endl;
02272
02273
02274
02275
02276 if(has_kf && unCorrEene > 0.) {
02277 posX /=unCorrEene;
02278 posY /=unCorrEene;
02279 posZ /=unCorrEene;
02280 math::XYZPoint sc_pflow(posX,posY,posZ);
02281
02282 std::multimap<double, unsigned int> bremElems;
02283 block.associatedElements( gsf_index,linkData,
02284 bremElems,
02285 reco::PFBlockElement::BREM,
02286 reco::PFBlock::LINKTEST_ALL );
02287
02288 double phiTrack = RefGSF->phiMode();
02289 if(bremElems.size()>0) {
02290 unsigned int brem_index = bremElems.begin()->second;
02291 const reco::PFBlockElementBrem * BremEl =
02292 dynamic_cast<const reco::PFBlockElementBrem*>((&elements[brem_index]));
02293 phiTrack = BremEl->positionAtECALEntrance().phi();
02294 }
02295
02296 double dphi_normalsc = sc_pflow.Phi() - phiTrack;
02297 if ( dphi_normalsc < -M_PI )
02298 dphi_normalsc = dphi_normalsc + 2.*M_PI;
02299 else if ( dphi_normalsc > M_PI )
02300 dphi_normalsc = dphi_normalsc - 2.*M_PI;
02301
02302 int chargeGsf = RefGSF->chargeMode();
02303 int chargeKf = RefKF->charge();
02304
02305 int chargeSC = 0;
02306 if(dphi_normalsc < 0.)
02307 chargeSC = 1;
02308 else
02309 chargeSC = -1;
02310
02311 if(chargeKf == chargeGsf)
02312 charge = chargeGsf;
02313 else if(chargeGsf == chargeSC)
02314 charge = chargeGsf;
02315 else
02316 charge = chargeKf;
02317
02318 if( DebugIDCandidates )
02319 cout << "PFElectronAlgo:: charge determination "
02320 << " charge GSF " << chargeGsf
02321 << " charge KF " << chargeKf
02322 << " charge SC " << chargeSC
02323 << " Final Charge " << charge << endl;
02324
02325 }
02326
02327
02328 if ((nhit_gsf<8) && (has_kf)){
02329
02330
02331
02332 momentum=momentum_kf;
02333 float Fe=Eene;
02334 float scale= Fe/momentum.E();
02335
02336
02337 if (Eene < 0.0001) {
02338 Fe = momentum.E();
02339 scale = 1.;
02340 }
02341
02342
02343 newmomentum.SetPxPyPzE(scale*momentum.Px(),
02344 scale*momentum.Py(),
02345 scale*momentum.Pz(),Fe);
02346 if( DebugIDCandidates )
02347 cout << "SetCandidates:: (nhit_gsf<8) && (has_kf):: pt " << newmomentum.pt() << " Ene " << Fe <<endl;
02348
02349
02350 }
02351 if ((nhit_gsf>7) || (has_kf==false)){
02352 if(Eene > 0.0001) {
02353 de_gs=1-momentum_gsf.E()/Eene;
02354 de_me=1-momentum_mean.E()/Eene;
02355 de_kf=1-momentum_kf.E()/Eene;
02356 }
02357
02358 momentum=momentum_gsf;
02359 dpt=1/(dpt_gsf*dpt_gsf);
02360
02361 if(dene > 0.)
02362 dene= 1./dene;
02363
02364 float Fe = 0.;
02365 if(Eene > 0.0001) {
02366 Fe =((dene*Eene) +(dpt*momentum.E()))/(dene+dpt);
02367 }
02368 else {
02369 Fe=momentum.E();
02370 }
02371
02372 if ((de_gs>0.05)&&(de_kf>0.05)){
02373 Fe=Eene;
02374 }
02375 if ((de_gs<-0.1)&&(de_me<-0.1) &&(de_kf<0.) &&
02376 (momentum.E()/dpt_gsf) > 5. && momentum_gsf.pt() < 30.){
02377 Fe=momentum.E();
02378 }
02379 float scale= Fe/momentum.E();
02380
02381 newmomentum.SetPxPyPzE(scale*momentum.Px(),
02382 scale*momentum.Py(),
02383 scale*momentum.Pz(),Fe);
02384 if( DebugIDCandidates )
02385 cout << "SetCandidates::(nhit_gsf>7) || (has_kf==false) " << newmomentum.pt() << " Ene " << Fe <<endl;
02386
02387
02388 }
02389 if (newmomentum.pt()>0.5){
02390
02391
02392
02393
02394 if( DebugIDCandidates )
02395 cout << "SetCandidates:: I am before doing candidate " <<endl;
02396
02397
02398 std::vector<float> clusterEnergyVec;
02399 clusterEnergyVec.push_back(RawEene);
02400 clusterEnergyVec.insert(clusterEnergyVec.end(),bremEnergyVec.begin(),bremEnergyVec.end());
02401
02402
02403 std::vector<reco::PFCandidateElectronExtra>::iterator itextra;
02404 PFElectronExtraEqual myExtraEqual(RefGSF);
02405 itextra=find_if(electronExtra_.begin(),electronExtra_.end(),myExtraEqual);
02406 if(itextra!=electronExtra_.end()) {
02407 itextra->setClusterEnergies(clusterEnergyVec);
02408 }
02409 else {
02410 if(RawEene>0.)
02411 std::cout << " There is a big problem with the electron extra, PFElectronAlgo should crash soon " << RawEene << std::endl;
02412 }
02413
02414 reco::PFCandidate::ParticleType particleType
02415 = reco::PFCandidate::e;
02416 reco::PFCandidate temp_Candidate;
02417 temp_Candidate = PFCandidate(charge,newmomentum,particleType);
02418 temp_Candidate.set_mva_e_pi(BDToutput_[cgsf]);
02419 temp_Candidate.setEcalEnergy(RawEene,Eene);
02420
02421 temp_Candidate.setHcalEnergy(Hene,Hene);
02422 temp_Candidate.setPs1Energy(ps1TotEne);
02423 temp_Candidate.setPs2Energy(ps2TotEne);
02424 temp_Candidate.setTrackRef(RefKF);
02425
02426 temp_Candidate.setGsfTrackRef(RefGSF);
02427 temp_Candidate.setPositionAtECALEntrance(posGsfEcalEntrance);
02428
02429 temp_Candidate.setVertexSource(PFCandidate::kGSFVertex);
02430
02431
02432 if(RefGSF->extra().isAvailable() && RefGSF->extra()->seedRef().isAvailable()) {
02433 reco::ElectronSeedRef seedRef= RefGSF->extra()->seedRef().castTo<reco::ElectronSeedRef>();
02434 if(seedRef.isAvailable() && seedRef->isEcalDriven()) {
02435 reco::SuperClusterRef scRef = seedRef->caloCluster().castTo<reco::SuperClusterRef>();
02436 if(scRef.isNonnull())
02437 temp_Candidate.setSuperClusterRef(scRef);
02438 }
02439 }
02440
02441 if( DebugIDCandidates )
02442 cout << "SetCandidates:: I am after doing candidate " <<endl;
02443
02444 for (unsigned int elad=0; elad<elementsToAdd.size();elad++){
02445 temp_Candidate.addElementInBlock(blockRef,elementsToAdd[elad]);
02446 }
02447
02448
02449 std::map<unsigned int, std::vector<reco::PFCandidate> >::const_iterator itcluster=
02450 electronConstituents_.find(cgsf);
02451 if(itcluster!=electronConstituents_.end())
02452 {
02453 const std::vector<reco::PFCandidate> & theClusters=itcluster->second;
02454 unsigned nclus=theClusters.size();
02455
02456 for(unsigned iclus=0;iclus<nclus;++iclus)
02457 {
02458 temp_Candidate.addDaughter(theClusters[iclus]);
02459 }
02460 }
02461
02462
02463 bool bypassmva=false;
02464 if(useEGElectrons_) {
02465 GsfElectronEqual myEqual(RefGSF);
02466 std::vector<reco::GsfElectron>::const_iterator itcheck=find_if(theGsfElectrons_->begin(),theGsfElectrons_->end(),myEqual);
02467 if(itcheck!=theGsfElectrons_->end()) {
02468 if(BDToutput_[cgsf] >= -1.) {
02469
02470 bypassmva=true;
02471
02472 if( DebugIDCandidates ) {
02473 if(BDToutput_[cgsf] < -0.1) {
02474 float esceg = itcheck->caloEnergy();
02475 cout << " Attention By pass the mva " << BDToutput_[cgsf]
02476 << " SuperClusterEnergy " << esceg
02477 << " PF Energy " << Eene << endl;
02478
02479 cout << " hoe " << itcheck->hcalOverEcal()
02480 << " tkiso04 " << itcheck->dr04TkSumPt()
02481 << " ecaliso04 " << itcheck->dr04EcalRecHitSumEt()
02482 << " hcaliso04 " << itcheck->dr04HcalTowerSumEt()
02483 << " tkiso03 " << itcheck->dr03TkSumPt()
02484 << " ecaliso03 " << itcheck->dr03EcalRecHitSumEt()
02485 << " hcaliso03 " << itcheck->dr03HcalTowerSumEt() << endl;
02486 }
02487 }
02488 }
02489 }
02490 }
02491
02492 bool mvaSelected = (BDToutput_[cgsf] >= mvaEleCut_);
02493 if( mvaSelected || bypassmva ) {
02494 elCandidate_.push_back(temp_Candidate);
02495 if(itextra!=electronExtra_.end())
02496 itextra->setStatus(PFCandidateElectronExtra::Selected,true);
02497 }
02498 else {
02499 if(itextra!=electronExtra_.end())
02500 itextra->setStatus(PFCandidateElectronExtra::Rejected,true);
02501 }
02502 allElCandidate_.push_back(temp_Candidate);
02503
02504
02505 if(itextra!=electronExtra_.end()) {
02506 itextra->setStatus(PFCandidateElectronExtra::ECALDrivenPreselected,bypassmva);
02507 itextra->setStatus(PFCandidateElectronExtra::MVASelected,mvaSelected);
02508 }
02509
02510
02511 }
02512 else {
02513 BDToutput_[cgsf] = -1.;
02514
02515 if( DebugIDCandidates )
02516 cout << "SetCandidates:: No Candidate Produced because of Pt cut: 0.5 " <<endl;
02517 }
02518 }
02519 else {
02520 BDToutput_[cgsf] = -1.;
02521 if( DebugIDCandidates )
02522 cout << "SetCandidates:: No Candidate Produced because of No GSF Track Ref " <<endl;
02523 }
02524 }
02525 return;
02526 }
02527
02528
02529
02530 void PFElectronAlgo::SetActive(const reco::PFBlockRef& blockRef,
02531 AssMap& associatedToGsf_,
02532 AssMap& associatedToBrems_,
02533 AssMap& associatedToEcal_,
02534 std::vector<bool>& active){
02535 const reco::PFBlock& block = *blockRef;
02536 PFBlock::LinkData linkData = block.linkData();
02537
02538 const edm::OwnVector< reco::PFBlockElement >& elements = block.elements();
02539
02540 unsigned int cgsf=0;
02541 for (map<unsigned int,vector<unsigned int> >::iterator igsf = associatedToGsf_.begin();
02542 igsf != associatedToGsf_.end(); igsf++,cgsf++) {
02543
02544 unsigned int gsf_index = igsf->first;
02545 const reco::PFBlockElementGsfTrack * GsfEl =
02546 dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[gsf_index]));
02547 reco::GsfTrackRef RefGSF = GsfEl->GsftrackRef();
02548
02549
02550 bool bypassmva=false;
02551 if(useEGElectrons_) {
02552 GsfElectronEqual myEqual(RefGSF);
02553 std::vector<reco::GsfElectron>::const_iterator itcheck=find_if(theGsfElectrons_->begin(),theGsfElectrons_->end(),myEqual);
02554 if(itcheck!=theGsfElectrons_->end()) {
02555 if(BDToutput_[cgsf] >= -1.)
02556 bypassmva=true;
02557 }
02558 }
02559
02560 if(BDToutput_[cgsf] < mvaEleCut_ && bypassmva == false) continue;
02561
02562
02563 active[gsf_index] = false;
02564 vector<unsigned int> assogsf_index = igsf->second;
02565 for (unsigned int ielegsf=0;ielegsf<assogsf_index.size();ielegsf++) {
02566 PFBlockElement::Type assoele_type = elements[(assogsf_index[ielegsf])].type();
02567
02568 active[(assogsf_index[ielegsf])] = false;
02569 if (assoele_type == reco::PFBlockElement::ECAL) {
02570 unsigned int keyecalgsf = assogsf_index[ielegsf];
02571
02572
02573 if(fifthStepKfTrack_.size() > 0) {
02574 for(unsigned int itr = 0; itr < fifthStepKfTrack_.size(); itr++) {
02575 if(fifthStepKfTrack_[itr].first == keyecalgsf) {
02576 active[(fifthStepKfTrack_[itr].second)] = false;
02577 }
02578 }
02579 }
02580
02581
02582 if(convGsfTrack_.size() > 0) {
02583 for(unsigned int iconv = 0; iconv < convGsfTrack_.size(); iconv++) {
02584 if(convGsfTrack_[iconv].first == keyecalgsf) {
02585
02586 active[(convGsfTrack_[iconv].second)] = false;
02587
02588 std::multimap<double, unsigned> convKf;
02589 block.associatedElements( convGsfTrack_[iconv].second,
02590 linkData,
02591 convKf,
02592 reco::PFBlockElement::TRACK,
02593 reco::PFBlock::LINKTEST_ALL );
02594 if(convKf.size() > 0) {
02595 active[convKf.begin()->second] = false;
02596 }
02597 }
02598 }
02599 }
02600
02601
02602 vector<unsigned int> assoecalgsf_index = associatedToEcal_.find(keyecalgsf)->second;
02603 for(unsigned int ips =0; ips<assoecalgsf_index.size();ips++) {
02604
02605 if (elements[(assoecalgsf_index[ips])].type() == reco::PFBlockElement::PS1)
02606 active[(assoecalgsf_index[ips])] = false;
02607 if (elements[(assoecalgsf_index[ips])].type() == reco::PFBlockElement::PS2)
02608 active[(assoecalgsf_index[ips])] = false;
02609 if (elements[(assoecalgsf_index[ips])].type() == reco::PFBlockElement::TRACK) {
02610 if(lockExtraKf_[cgsf] == true) {
02611 active[(assoecalgsf_index[ips])] = false;
02612 }
02613 }
02614 }
02615 }
02616 if (assoele_type == reco::PFBlockElement::BREM) {
02617 unsigned int brem_index = assogsf_index[ielegsf];
02618 vector<unsigned int> assobrem_index = associatedToBrems_.find(brem_index)->second;
02619 for (unsigned int ibrem = 0; ibrem < assobrem_index.size(); ibrem++){
02620 if (elements[(assobrem_index[ibrem])].type() == reco::PFBlockElement::ECAL) {
02621 unsigned int keyecalbrem = assobrem_index[ibrem];
02622
02623 active[(assobrem_index[ibrem])] = false;
02624
02625
02626 if(fifthStepKfTrack_.size() > 0) {
02627 for(unsigned int itr = 0; itr < fifthStepKfTrack_.size(); itr++) {
02628 if(fifthStepKfTrack_[itr].first == keyecalbrem) {
02629 active[(fifthStepKfTrack_[itr].second)] = false;
02630 }
02631 }
02632 }
02633
02634 vector<unsigned int> assoelebrem_index = associatedToEcal_.find(keyecalbrem)->second;
02635
02636 for (unsigned int ielebrem=0; ielebrem<assoelebrem_index.size();ielebrem++) {
02637 if (elements[(assoelebrem_index[ielebrem])].type() == reco::PFBlockElement::PS1)
02638 active[(assoelebrem_index[ielebrem])] = false;
02639 if (elements[(assoelebrem_index[ielebrem])].type() == reco::PFBlockElement::PS2)
02640 active[(assoelebrem_index[ielebrem])] = false;
02641 }
02642 }
02643 }
02644 }
02645 }
02646 }
02647 return;
02648 }
02649 void PFElectronAlgo::setEGElectronCollection(const reco::GsfElectronCollection & egelectrons) {
02650 theGsfElectrons_ = & egelectrons;
02651 }
02652 unsigned int PFElectronAlgo::whichTrackAlgo(const reco::TrackRef& trackRef) {
02653 unsigned int Algo = 0;
02654 switch (trackRef->algo()) {
02655 case TrackBase::ctf:
02656 case TrackBase::iter0:
02657 case TrackBase::iter1:
02658 case TrackBase::iter2:
02659 Algo = 0;
02660 break;
02661 case TrackBase::iter3:
02662 Algo = 1;
02663 break;
02664 case TrackBase::iter4:
02665 Algo = 2;
02666 break;
02667 case TrackBase::iter5:
02668 Algo = 3;
02669 break;
02670 case TrackBase::iter6:
02671 Algo = 4;
02672 break;
02673 default:
02674 Algo = 5;
02675 break;
02676 }
02677 return Algo;
02678 }
02679 bool PFElectronAlgo::isPrimaryTrack(const reco::PFBlockElementTrack& KfEl,
02680 const reco::PFBlockElementGsfTrack& GsfEl) {
02681 bool isPrimary = false;
02682
02683 GsfPFRecTrackRef gsfPfRef = GsfEl.GsftrackRefPF();
02684
02685 if(gsfPfRef.isNonnull()) {
02686 PFRecTrackRef kfPfRef = KfEl.trackRefPF();
02687 PFRecTrackRef kfPfRef_fromGsf = (*gsfPfRef).kfPFRecTrackRef();
02688 if(kfPfRef.isNonnull() && kfPfRef_fromGsf.isNonnull()) {
02689 reco::TrackRef kfref= (*kfPfRef).trackRef();
02690 reco::TrackRef kfref_fromGsf = (*kfPfRef_fromGsf).trackRef();
02691 if(kfref.isNonnull() && kfref_fromGsf.isNonnull()) {
02692 if(kfref == kfref_fromGsf)
02693 isPrimary = true;
02694 }
02695 }
02696 }
02697
02698 return isPrimary;
02699 }