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