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