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 bool EarlyBrem = false;
01435 int FirstBrem = 1000;
01436 unsigned int ecalGsf_index = 100000;
01437 unsigned int kf_index = 100000;
01438 unsigned int nhits_gsf = 0;
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 nhits_gsf = RefGSF->hitPattern().trackerLayersWithMeasurement();
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 if (TrajPos <= 3) EarlyBrem = true;
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 bool goodphi=true;
01915 math::XYZTLorentzVector momentum_kf,momentum_gsf,momentum,momentum_mean;
01916 float dpt=0; float dpt_kf=0; float dpt_gsf=0; float dpt_mean=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 dpt_mean=RefGSF->ptError()*
01972 (RefGSF->p()/RefGSF->pt());
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 dpt_kf=(RefKF->ptError()*RefKF->ptError());
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 float mphi=-2.97025;
02063 if (ceta<0) mphi+=0.00638;
02064 for (int ip=1; ip<19; ip++){
02065 float df= cphi - (mphi+(ip*6.283185/18));
02066 if (fabs(df)<0.01) goodphi=false;
02067 }
02068 float dE=pfresol_.getEnergyResolutionEm(EE,cl.position().eta());
02069 if( DebugIDCandidates )
02070 cout << "SetCandidates:: EcalCluster: EneNoCalib " << clust->clusterRef()->energy()
02071 << " eta,phi " << ceta << "," << cphi << " Calib " << EE << " dE " << dE <<endl;
02072
02073 bool elecCluster=false;
02074 if (FirstEcalGsf) {
02075 FirstEcalGsf = false;
02076 elecCluster=true;
02077 ecalGsf_index = assogsf_index[ielegsf];
02078
02079 RawEene += EE;
02080 }
02081
02082
02083 math::XYZTLorentzVector clusterMomentum;
02084 math::XYZPoint direction=cl.position()/cl.position().R();
02085 clusterMomentum.SetPxPyPzE(EE*direction.x(),
02086 EE*direction.y(),
02087 EE*direction.z(),
02088 EE);
02089 reco::PFCandidate cluster_Candidate((elecCluster)?charge:0,
02090 clusterMomentum,
02091 (elecCluster)? reco::PFCandidate::e : reco::PFCandidate::gamma);
02092
02093 cluster_Candidate.setPs1Energy(ps1);
02094 cluster_Candidate.setPs2Energy(ps2);
02095
02096
02097 cluster_Candidate.setEcalEnergy(EE-ps1-ps2,EE);
02098
02099 cluster_Candidate.setPositionAtECALEntrance(math::XYZPointF(cl.position()));
02100 cluster_Candidate.addElementInBlock(blockRef,assogsf_index[ielegsf]);
02101
02102 std::map<unsigned int,std::vector<reco::PFCandidate> >::iterator itcheck=
02103 electronConstituents_.find(cgsf);
02104 if(itcheck==electronConstituents_.end())
02105 {
02106
02107 std::vector<reco::PFCandidate> tmpVec;
02108 tmpVec.push_back(cluster_Candidate);
02109 electronConstituents_.insert(std::pair<unsigned int, std::vector<reco::PFCandidate> >
02110 (cgsf,tmpVec));
02111 }
02112 else
02113 {
02114 itcheck->second.push_back(cluster_Candidate);
02115 }
02116
02117 Eene+=EE;
02118 posX += EE * cl.position().X();
02119 posY += EE * cl.position().Y();
02120 posZ += EE * cl.position().Z();
02121 ps1TotEne+=ps1;
02122 ps2TotEne+=ps2;
02123 dene+=dE*dE;
02124
02125
02126 pfSC_Clust_vec.push_back( &cl );
02127
02128 }
02129
02130
02131
02132
02133 if (assoele_type == reco::PFBlockElement::BREM) {
02134 unsigned int brem_index = assogsf_index[ielegsf];
02135 vector<unsigned int> assobrem_index = associatedToBrems_.find(brem_index)->second;
02136 elementsToAdd.push_back(brem_index);
02137 for (unsigned int ibrem = 0; ibrem < assobrem_index.size(); ibrem++){
02138 if (elements[(assobrem_index[ibrem])].type() == reco::PFBlockElement::ECAL) {
02139
02140 unsigned int keyecalbrem = assobrem_index[ibrem];
02141 const vector<unsigned int>& assoelebrem_index = associatedToEcal_.find(keyecalbrem)->second;
02142 vector<double> ps1EneFromBrem(0);
02143 vector<double> ps2EneFromBrem(0);
02144 float ps1EneFromBremTot=0.;
02145 float ps2EneFromBremTot=0.;
02146 for (unsigned int ielebrem=0; ielebrem<assoelebrem_index.size();ielebrem++) {
02147 if (elements[(assoelebrem_index[ielebrem])].type() == reco::PFBlockElement::PS1) {
02148 PFClusterRef psref = elements[(assoelebrem_index[ielebrem])].clusterRef();
02149 ps1EneFromBrem.push_back(psref->energy());
02150 ps1EneFromBremTot+=psref->energy();
02151 elementsToAdd.push_back(assoelebrem_index[ielebrem]);
02152 }
02153 if (elements[(assoelebrem_index[ielebrem])].type() == reco::PFBlockElement::PS2) {
02154 PFClusterRef psref = elements[(assoelebrem_index[ielebrem])].clusterRef();
02155 ps2EneFromBrem.push_back(psref->energy());
02156 ps2EneFromBremTot+=psref->energy();
02157 elementsToAdd.push_back(assoelebrem_index[ielebrem]);
02158 }
02159 }
02160
02161
02162 if( assobrem_index[ibrem] != ecalGsf_index) {
02163 elementsToAdd.push_back(assobrem_index[ibrem]);
02164 reco::PFClusterRef clusterRef = elements[(assobrem_index[ibrem])].clusterRef();
02165
02166
02167 double ps1=0;
02168 double ps2=0;
02169 float EE = thePFEnergyCalibration_->energyEm(*clusterRef,ps1EneFromBrem,ps2EneFromBrem,ps1,ps2,applyCrackCorrections_);
02170 bremEnergyVec.push_back(EE);
02171
02172 float ceta = clusterRef->position().eta();
02173
02174 float dE=pfresol_.getEnergyResolutionEm(EE,ceta);
02175 if( DebugIDCandidates )
02176 cout << "SetCandidates:: BremCluster: Ene " << EE << " dE " << dE <<endl;
02177
02178 Eene+=EE;
02179 posX += EE * clusterRef->position().X();
02180 posY += EE * clusterRef->position().Y();
02181 posZ += EE * clusterRef->position().Z();
02182 ps1TotEne+=ps1;
02183 ps2TotEne+=ps2;
02184
02185
02186 dene+=dE*dE;
02187
02188
02189 pfSC_Clust_vec.push_back( clusterRef.get() );
02190
02191
02192
02193 math::XYZTLorentzVector photonMomentum;
02194 math::XYZPoint direction=clusterRef->position()/clusterRef->position().R();
02195
02196 photonMomentum.SetPxPyPzE(EE*direction.x(),
02197 EE*direction.y(),
02198 EE*direction.z(),
02199 EE);
02200 reco::PFCandidate photon_Candidate(0,photonMomentum, reco::PFCandidate::gamma);
02201
02202 photon_Candidate.setPs1Energy(ps1);
02203 photon_Candidate.setPs2Energy(ps2);
02204
02205
02206 photon_Candidate.setEcalEnergy(EE-ps1-ps2,EE);
02207
02208 photon_Candidate.setPositionAtECALEntrance(math::XYZPointF(clusterRef->position()));
02209 photon_Candidate.addElementInBlock(blockRef,assobrem_index[ibrem]);
02210
02211
02212 std::map<unsigned int,std::vector<reco::PFCandidate> >::iterator itcheck=
02213 electronConstituents_.find(cgsf);
02214 if(itcheck==electronConstituents_.end())
02215 {
02216
02217 std::vector<reco::PFCandidate> tmpVec;
02218 tmpVec.push_back(photon_Candidate);
02219 electronConstituents_.insert(std::pair<unsigned int, std::vector<reco::PFCandidate> >
02220 (cgsf,tmpVec));
02221 }
02222 else
02223 {
02224 itcheck->second.push_back(photon_Candidate);
02225 }
02226 }
02227 }
02228 }
02229 }
02230 }
02231 if (has_gsf) {
02232
02233
02234 double unCorrEene = Eene;
02235 double absEta = fabs(momentum_gsf.Eta());
02236 double emTheta = momentum_gsf.Theta();
02237 PFClusterWidthAlgo pfSCwidth(pfSC_Clust_vec);
02238 double brLinear = pfSCwidth.pflowPhiWidth()/pfSCwidth.pflowEtaWidth();
02239 pfSC_Clust_vec.clear();
02240
02241 if( DebugIDCandidates )
02242 cout << "PFEelectronAlgo:: absEta " << absEta << " theta " << emTheta
02243 << " EneRaw " << Eene << " Err " << dene;
02244
02245
02246
02247 if(usePFSCEleCalib_ && unCorrEene > 0.) {
02248 if( absEta < 1.5) {
02249 double Etene = Eene*sin(emTheta);
02250 double emBR_e = thePFSCEnergyCalibration_->SCCorrFBremBarrel(Eene, Etene, brLinear);
02251 double emBR_et = emBR_e*sin(emTheta);
02252 double emCorrFull_et = thePFSCEnergyCalibration_->SCCorrEtEtaBarrel(emBR_et, absEta);
02253 Eene = emCorrFull_et/sin(emTheta);
02254 }
02255 else {
02256
02257 double emBR_e = thePFSCEnergyCalibration_->SCCorrFBremEndcap(Eene, absEta, brLinear);
02258 double emBR_et = emBR_e*sin(emTheta);
02259 double emCorrFull_et = thePFSCEnergyCalibration_->SCCorrEtEtaEndcap(emBR_et, absEta);
02260 Eene = emCorrFull_et/sin(emTheta);
02261 }
02262 dene = sqrt(dene)*(Eene/unCorrEene);
02263 dene = dene*dene;
02264 }
02265
02266 if( DebugIDCandidates )
02267 cout << " EneCorrected " << Eene << " Err " << dene << endl;
02268
02269
02270
02271
02272 if(has_kf && unCorrEene > 0.) {
02273 posX /=unCorrEene;
02274 posY /=unCorrEene;
02275 posZ /=unCorrEene;
02276 math::XYZPoint sc_pflow(posX,posY,posZ);
02277
02278 std::multimap<double, unsigned int> bremElems;
02279 block.associatedElements( gsf_index,linkData,
02280 bremElems,
02281 reco::PFBlockElement::BREM,
02282 reco::PFBlock::LINKTEST_ALL );
02283
02284 double phiTrack = RefGSF->phiMode();
02285 if(bremElems.size()>0) {
02286 unsigned int brem_index = bremElems.begin()->second;
02287 const reco::PFBlockElementBrem * BremEl =
02288 dynamic_cast<const reco::PFBlockElementBrem*>((&elements[brem_index]));
02289 phiTrack = BremEl->positionAtECALEntrance().phi();
02290 }
02291
02292 double dphi_normalsc = sc_pflow.Phi() - phiTrack;
02293 if ( dphi_normalsc < -M_PI )
02294 dphi_normalsc = dphi_normalsc + 2.*M_PI;
02295 else if ( dphi_normalsc > M_PI )
02296 dphi_normalsc = dphi_normalsc - 2.*M_PI;
02297
02298 int chargeGsf = RefGSF->chargeMode();
02299 int chargeKf = RefKF->charge();
02300
02301 int chargeSC = 0;
02302 if(dphi_normalsc < 0.)
02303 chargeSC = 1;
02304 else
02305 chargeSC = -1;
02306
02307 if(chargeKf == chargeGsf)
02308 charge = chargeGsf;
02309 else if(chargeGsf == chargeSC)
02310 charge = chargeGsf;
02311 else
02312 charge = chargeKf;
02313
02314 if( DebugIDCandidates )
02315 cout << "PFElectronAlgo:: charge determination "
02316 << " charge GSF " << chargeGsf
02317 << " charge KF " << chargeKf
02318 << " charge SC " << chargeSC
02319 << " Final Charge " << charge << endl;
02320
02321 }
02322
02323
02324 if ((nhit_gsf<8) && (has_kf)){
02325
02326
02327
02328 momentum=momentum_kf;
02329 float Fe=Eene;
02330 float scale= Fe/momentum.E();
02331
02332
02333 if (Eene < 0.0001) {
02334 Fe = momentum.E();
02335 scale = 1.;
02336 }
02337
02338
02339 newmomentum.SetPxPyPzE(scale*momentum.Px(),
02340 scale*momentum.Py(),
02341 scale*momentum.Pz(),Fe);
02342 if( DebugIDCandidates )
02343 cout << "SetCandidates:: (nhit_gsf<8) && (has_kf):: pt " << newmomentum.pt() << " Ene " << Fe <<endl;
02344
02345
02346 }
02347 if ((nhit_gsf>7) || (has_kf==false)){
02348 if(Eene > 0.0001) {
02349 de_gs=1-momentum_gsf.E()/Eene;
02350 de_me=1-momentum_mean.E()/Eene;
02351 de_kf=1-momentum_kf.E()/Eene;
02352 }
02353
02354 momentum=momentum_gsf;
02355 dpt=1/(dpt_gsf*dpt_gsf);
02356
02357 if(dene > 0.)
02358 dene= 1./dene;
02359
02360 float Fe = 0.;
02361 if(Eene > 0.0001) {
02362 Fe =((dene*Eene) +(dpt*momentum.E()))/(dene+dpt);
02363 }
02364 else {
02365 Fe=momentum.E();
02366 }
02367
02368 if ((de_gs>0.05)&&(de_kf>0.05)){
02369 Fe=Eene;
02370 }
02371 if ((de_gs<-0.1)&&(de_me<-0.1) &&(de_kf<0.) &&
02372 (momentum.E()/dpt_gsf) > 5. && momentum_gsf.pt() < 30.){
02373 Fe=momentum.E();
02374 }
02375 float scale= Fe/momentum.E();
02376
02377 newmomentum.SetPxPyPzE(scale*momentum.Px(),
02378 scale*momentum.Py(),
02379 scale*momentum.Pz(),Fe);
02380 if( DebugIDCandidates )
02381 cout << "SetCandidates::(nhit_gsf>7) || (has_kf==false) " << newmomentum.pt() << " Ene " << Fe <<endl;
02382
02383
02384 }
02385 if (newmomentum.pt()>0.5){
02386
02387
02388
02389
02390 if( DebugIDCandidates )
02391 cout << "SetCandidates:: I am before doing candidate " <<endl;
02392
02393
02394 std::vector<float> clusterEnergyVec;
02395 clusterEnergyVec.push_back(RawEene);
02396 clusterEnergyVec.insert(clusterEnergyVec.end(),bremEnergyVec.begin(),bremEnergyVec.end());
02397
02398
02399 std::vector<reco::PFCandidateElectronExtra>::iterator itextra;
02400 PFElectronExtraEqual myExtraEqual(RefGSF);
02401 itextra=find_if(electronExtra_.begin(),electronExtra_.end(),myExtraEqual);
02402 if(itextra!=electronExtra_.end()) {
02403 itextra->setClusterEnergies(clusterEnergyVec);
02404 }
02405 else {
02406 if(RawEene>0.)
02407 std::cout << " There is a big problem with the electron extra, PFElectronAlgo should crash soon " << RawEene << std::endl;
02408 }
02409
02410 reco::PFCandidate::ParticleType particleType
02411 = reco::PFCandidate::e;
02412 reco::PFCandidate temp_Candidate;
02413 temp_Candidate = PFCandidate(charge,newmomentum,particleType);
02414 temp_Candidate.set_mva_e_pi(BDToutput_[cgsf]);
02415 temp_Candidate.setEcalEnergy(RawEene,Eene);
02416
02417 temp_Candidate.setHcalEnergy(Hene,Hene);
02418 temp_Candidate.setPs1Energy(ps1TotEne);
02419 temp_Candidate.setPs2Energy(ps2TotEne);
02420 temp_Candidate.setTrackRef(RefKF);
02421
02422 temp_Candidate.setGsfTrackRef(RefGSF);
02423 temp_Candidate.setPositionAtECALEntrance(posGsfEcalEntrance);
02424
02425 temp_Candidate.setVertexSource(PFCandidate::kGSFVertex);
02426
02427
02428 if(RefGSF->extra().isAvailable() && RefGSF->extra()->seedRef().isAvailable()) {
02429 reco::ElectronSeedRef seedRef= RefGSF->extra()->seedRef().castTo<reco::ElectronSeedRef>();
02430 if(seedRef.isAvailable() && seedRef->isEcalDriven()) {
02431 reco::SuperClusterRef scRef = seedRef->caloCluster().castTo<reco::SuperClusterRef>();
02432 if(scRef.isNonnull())
02433 temp_Candidate.setSuperClusterRef(scRef);
02434 }
02435 }
02436
02437 if( DebugIDCandidates )
02438 cout << "SetCandidates:: I am after doing candidate " <<endl;
02439
02440 for (unsigned int elad=0; elad<elementsToAdd.size();elad++){
02441 temp_Candidate.addElementInBlock(blockRef,elementsToAdd[elad]);
02442 }
02443
02444
02445 std::map<unsigned int, std::vector<reco::PFCandidate> >::const_iterator itcluster=
02446 electronConstituents_.find(cgsf);
02447 if(itcluster!=electronConstituents_.end())
02448 {
02449 const std::vector<reco::PFCandidate> & theClusters=itcluster->second;
02450 unsigned nclus=theClusters.size();
02451
02452 for(unsigned iclus=0;iclus<nclus;++iclus)
02453 {
02454 temp_Candidate.addDaughter(theClusters[iclus]);
02455 }
02456 }
02457
02458
02459 bool bypassmva=false;
02460 if(useEGElectrons_) {
02461 GsfElectronEqual myEqual(RefGSF);
02462 std::vector<reco::GsfElectron>::const_iterator itcheck=find_if(theGsfElectrons_->begin(),theGsfElectrons_->end(),myEqual);
02463 if(itcheck!=theGsfElectrons_->end()) {
02464 if(BDToutput_[cgsf] >= -1.) {
02465
02466 bypassmva=true;
02467
02468 if( DebugIDCandidates ) {
02469 if(BDToutput_[cgsf] < -0.1) {
02470 float esceg = itcheck->caloEnergy();
02471 cout << " Attention By pass the mva " << BDToutput_[cgsf]
02472 << " SuperClusterEnergy " << esceg
02473 << " PF Energy " << Eene << endl;
02474
02475 cout << " hoe " << itcheck->hcalOverEcal()
02476 << " tkiso04 " << itcheck->dr04TkSumPt()
02477 << " ecaliso04 " << itcheck->dr04EcalRecHitSumEt()
02478 << " hcaliso04 " << itcheck->dr04HcalTowerSumEt()
02479 << " tkiso03 " << itcheck->dr03TkSumPt()
02480 << " ecaliso03 " << itcheck->dr03EcalRecHitSumEt()
02481 << " hcaliso03 " << itcheck->dr03HcalTowerSumEt() << endl;
02482 }
02483 }
02484 }
02485 }
02486 }
02487
02488 bool mvaSelected = (BDToutput_[cgsf] >= mvaEleCut_);
02489 if( mvaSelected || bypassmva ) {
02490 elCandidate_.push_back(temp_Candidate);
02491 if(itextra!=electronExtra_.end())
02492 itextra->setStatus(PFCandidateElectronExtra::Selected,true);
02493 }
02494 else {
02495 if(itextra!=electronExtra_.end())
02496 itextra->setStatus(PFCandidateElectronExtra::Rejected,true);
02497 }
02498 allElCandidate_.push_back(temp_Candidate);
02499
02500
02501 if(itextra!=electronExtra_.end()) {
02502 itextra->setStatus(PFCandidateElectronExtra::ECALDrivenPreselected,bypassmva);
02503 itextra->setStatus(PFCandidateElectronExtra::MVASelected,mvaSelected);
02504 }
02505
02506
02507 }
02508 else {
02509 BDToutput_[cgsf] = -1.;
02510
02511 if( DebugIDCandidates )
02512 cout << "SetCandidates:: No Candidate Produced because of Pt cut: 0.5 " <<endl;
02513 }
02514 }
02515 else {
02516 BDToutput_[cgsf] = -1.;
02517 if( DebugIDCandidates )
02518 cout << "SetCandidates:: No Candidate Produced because of No GSF Track Ref " <<endl;
02519 }
02520 }
02521 return;
02522 }
02523
02524
02525
02526 void PFElectronAlgo::SetActive(const reco::PFBlockRef& blockRef,
02527 AssMap& associatedToGsf_,
02528 AssMap& associatedToBrems_,
02529 AssMap& associatedToEcal_,
02530 std::vector<bool>& active){
02531 const reco::PFBlock& block = *blockRef;
02532 PFBlock::LinkData linkData = block.linkData();
02533
02534 const edm::OwnVector< reco::PFBlockElement >& elements = block.elements();
02535
02536 unsigned int cgsf=0;
02537 for (map<unsigned int,vector<unsigned int> >::iterator igsf = associatedToGsf_.begin();
02538 igsf != associatedToGsf_.end(); igsf++,cgsf++) {
02539
02540 unsigned int gsf_index = igsf->first;
02541 const reco::PFBlockElementGsfTrack * GsfEl =
02542 dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[gsf_index]));
02543 reco::GsfTrackRef RefGSF = GsfEl->GsftrackRef();
02544
02545
02546 bool bypassmva=false;
02547 if(useEGElectrons_) {
02548 GsfElectronEqual myEqual(RefGSF);
02549 std::vector<reco::GsfElectron>::const_iterator itcheck=find_if(theGsfElectrons_->begin(),theGsfElectrons_->end(),myEqual);
02550 if(itcheck!=theGsfElectrons_->end()) {
02551 if(BDToutput_[cgsf] >= -1.)
02552 bypassmva=true;
02553 }
02554 }
02555
02556 if(BDToutput_[cgsf] < mvaEleCut_ && bypassmva == false) continue;
02557
02558
02559 active[gsf_index] = false;
02560 vector<unsigned int> assogsf_index = igsf->second;
02561 for (unsigned int ielegsf=0;ielegsf<assogsf_index.size();ielegsf++) {
02562 PFBlockElement::Type assoele_type = elements[(assogsf_index[ielegsf])].type();
02563
02564 active[(assogsf_index[ielegsf])] = false;
02565 if (assoele_type == reco::PFBlockElement::ECAL) {
02566 unsigned int keyecalgsf = assogsf_index[ielegsf];
02567
02568
02569 if(fifthStepKfTrack_.size() > 0) {
02570 for(unsigned int itr = 0; itr < fifthStepKfTrack_.size(); itr++) {
02571 if(fifthStepKfTrack_[itr].first == keyecalgsf) {
02572 active[(fifthStepKfTrack_[itr].second)] = false;
02573 }
02574 }
02575 }
02576
02577
02578 if(convGsfTrack_.size() > 0) {
02579 for(unsigned int iconv = 0; iconv < convGsfTrack_.size(); iconv++) {
02580 if(convGsfTrack_[iconv].first == keyecalgsf) {
02581
02582 active[(convGsfTrack_[iconv].second)] = false;
02583
02584 std::multimap<double, unsigned> convKf;
02585 block.associatedElements( convGsfTrack_[iconv].second,
02586 linkData,
02587 convKf,
02588 reco::PFBlockElement::TRACK,
02589 reco::PFBlock::LINKTEST_ALL );
02590 if(convKf.size() > 0) {
02591 active[convKf.begin()->second] = false;
02592 }
02593 }
02594 }
02595 }
02596
02597
02598 vector<unsigned int> assoecalgsf_index = associatedToEcal_.find(keyecalgsf)->second;
02599 for(unsigned int ips =0; ips<assoecalgsf_index.size();ips++) {
02600
02601 if (elements[(assoecalgsf_index[ips])].type() == reco::PFBlockElement::PS1)
02602 active[(assoecalgsf_index[ips])] = false;
02603 if (elements[(assoecalgsf_index[ips])].type() == reco::PFBlockElement::PS2)
02604 active[(assoecalgsf_index[ips])] = false;
02605 if (elements[(assoecalgsf_index[ips])].type() == reco::PFBlockElement::TRACK) {
02606 if(lockExtraKf_[cgsf] == true) {
02607 active[(assoecalgsf_index[ips])] = false;
02608 }
02609 }
02610 }
02611 }
02612 if (assoele_type == reco::PFBlockElement::BREM) {
02613 unsigned int brem_index = assogsf_index[ielegsf];
02614 vector<unsigned int> assobrem_index = associatedToBrems_.find(brem_index)->second;
02615 for (unsigned int ibrem = 0; ibrem < assobrem_index.size(); ibrem++){
02616 if (elements[(assobrem_index[ibrem])].type() == reco::PFBlockElement::ECAL) {
02617 unsigned int keyecalbrem = assobrem_index[ibrem];
02618
02619 active[(assobrem_index[ibrem])] = false;
02620
02621
02622 if(fifthStepKfTrack_.size() > 0) {
02623 for(unsigned int itr = 0; itr < fifthStepKfTrack_.size(); itr++) {
02624 if(fifthStepKfTrack_[itr].first == keyecalbrem) {
02625 active[(fifthStepKfTrack_[itr].second)] = false;
02626 }
02627 }
02628 }
02629
02630 vector<unsigned int> assoelebrem_index = associatedToEcal_.find(keyecalbrem)->second;
02631
02632 for (unsigned int ielebrem=0; ielebrem<assoelebrem_index.size();ielebrem++) {
02633 if (elements[(assoelebrem_index[ielebrem])].type() == reco::PFBlockElement::PS1)
02634 active[(assoelebrem_index[ielebrem])] = false;
02635 if (elements[(assoelebrem_index[ielebrem])].type() == reco::PFBlockElement::PS2)
02636 active[(assoelebrem_index[ielebrem])] = false;
02637 }
02638 }
02639 }
02640 }
02641 }
02642 }
02643 return;
02644 }
02645 void PFElectronAlgo::setEGElectronCollection(const reco::GsfElectronCollection & egelectrons) {
02646 theGsfElectrons_ = & egelectrons;
02647 }
02648 unsigned int PFElectronAlgo::whichTrackAlgo(const reco::TrackRef& trackRef) {
02649 unsigned int Algo = 0;
02650 switch (trackRef->algo()) {
02651 case TrackBase::ctf:
02652 case TrackBase::iter0:
02653 case TrackBase::iter1:
02654 case TrackBase::iter2:
02655 Algo = 0;
02656 break;
02657 case TrackBase::iter3:
02658 Algo = 1;
02659 break;
02660 case TrackBase::iter4:
02661 Algo = 2;
02662 break;
02663 case TrackBase::iter5:
02664 Algo = 3;
02665 break;
02666 case TrackBase::iter6:
02667 Algo = 4;
02668 break;
02669 default:
02670 Algo = 5;
02671 break;
02672 }
02673 return Algo;
02674 }
02675 bool PFElectronAlgo::isPrimaryTrack(const reco::PFBlockElementTrack& KfEl,
02676 const reco::PFBlockElementGsfTrack& GsfEl) {
02677 bool isPrimary = false;
02678
02679 GsfPFRecTrackRef gsfPfRef = GsfEl.GsftrackRefPF();
02680
02681 if(gsfPfRef.isNonnull()) {
02682 PFRecTrackRef kfPfRef = KfEl.trackRefPF();
02683 PFRecTrackRef kfPfRef_fromGsf = (*gsfPfRef).kfPFRecTrackRef();
02684 if(kfPfRef.isNonnull() && kfPfRef_fromGsf.isNonnull()) {
02685 reco::TrackRef kfref= (*kfPfRef).trackRef();
02686 reco::TrackRef kfref_fromGsf = (*kfPfRef_fromGsf).trackRef();
02687 if(kfref.isNonnull() && kfref_fromGsf.isNonnull()) {
02688 if(kfref == kfref_fromGsf)
02689 isPrimary = true;
02690 }
02691 }
02692 }
02693
02694 return isPrimary;
02695 }