00001
00002
00003
00004
00005 #include "RecoParticleFlow/PFAlgo/interface/PFElectronAlgo.h"
00006 #include "DataFormats/ParticleFlowReco/interface/PFBlockElementGsfTrack.h"
00007 #include "DataFormats/ParticleFlowReco/interface/PFBlockElementCluster.h"
00008 #include "DataFormats/ParticleFlowReco/interface/PFBlockElementBrem.h"
00009 #include "DataFormats/ParticleFlowReco/interface/PFRecHitFraction.h"
00010 #include "DataFormats/ParticleFlowReco/interface/PFRecHitFwd.h"
00011 #include "DataFormats/ParticleFlowReco/interface/PFRecHit.h"
00012 #include "DataFormats/ParticleFlowReco/interface/PFCluster.h"
00013 #include "DataFormats/GsfTrackReco/interface/GsfTrack.h"
00014 #include "DataFormats/GsfTrackReco/interface/GsfTrackFwd.h"
00015 #include "RecoParticleFlow/PFClusterTools/interface/PFEnergyCalibration.h"
00016 #include "RecoParticleFlow/PFClusterTools/interface/PFEnergyResolution.h"
00017
00018 using namespace std;
00019 using namespace reco;
00020 PFElectronAlgo::PFElectronAlgo(const std::vector<double> chi2values,
00021 const double mvaEleCut,
00022 string mvaWeightFileEleID):
00023 chi2values_(chi2values),
00024 mvaEleCut_(mvaEleCut)
00025 {
00026
00027 tmvaReader_ = new TMVA::Reader();
00028 tmvaReader_->AddVariable("TEtotPinMode",&TEtotPinMode);
00029 tmvaReader_->AddVariable("TEGsfPoutMode",&TEGsfPoutMode);
00030 tmvaReader_->AddVariable("TDiffEtaGSFEcalEle",&TDiffEtaGSFEcalEle);
00031 tmvaReader_->AddVariable("log(TSigmaEtaEtaEle)",&TSigmaEtaEtaEle);
00032 tmvaReader_->AddVariable("TChiEcalEle",&TChiEcalEle);
00033 tmvaReader_->AddVariable("TNumBrem",&TNumBrem);
00034 tmvaReader_->AddVariable("TSumEBremPinPoutMode",&TSumEBremPinPoutMode);
00035 tmvaReader_->AddVariable("TLateBrem",&TLateBrem);
00036 tmvaReader_->AddVariable("TEarlyBrem",&TEarlyBrem);
00037 tmvaReader_->BookMVA("BDT",mvaWeightFileEleID.c_str());
00038 }
00039 void PFElectronAlgo::RunPFElectron(const reco::PFBlockRef& blockRef,
00040 std::vector<bool>& active){
00041
00042
00043
00044 AssMap associatedToGSF(0);
00045 AssMap associatedToBrems(0);
00046
00047
00048
00049
00050
00051
00052
00053
00054 GsfTrackSingleEcal_.clear();
00055 GsfTrackSingleEcal_ = active;
00056 MultipleGsfTrackAssociation(blockRef);
00057
00058 bool blockHasGSF = SetLinks(blockRef,associatedToGSF,associatedToBrems,active);
00059
00060 if (blockHasGSF) {
00061
00062
00063
00064
00065 BDToutput_.clear();
00066
00067 BDToutput_.assign(associatedToGSF.size(),-1.);
00068
00069
00070 SetIDOutputs(blockRef,associatedToGSF,associatedToBrems);
00071 elCandidate_.clear();
00072
00073
00074
00075 SetCandidates(blockRef,associatedToGSF,associatedToBrems);
00076 if (elCandidate_.size() > 0 ){
00077 isvalid_ = true;
00078
00079
00080 SetActive(blockRef,associatedToGSF,associatedToBrems,active);
00081 }
00082 }
00083 }
00084
00085
00086
00087 uint PFElectronAlgo::FindClosestElement(const uint iele,
00088 std::multimap<double, unsigned>& Elems,
00089 float& chi2cut,
00090 std::vector<bool>& active,
00091 const reco::PFBlockRef& blockRef) {
00092
00093 const reco::PFBlock& block = *blockRef;
00094 PFBlock::LinkData linkData = block.linkData();
00095 uint FoundIndex = 100000;
00096 if (Elems.size() > 0) {
00097 std::multimap<double, unsigned>::iterator ie = Elems.begin();
00098
00099 uint index = ie->second;
00100 float chi2 = block.chi2(iele,index,linkData);
00101 if (chi2 < chi2cut && active[index] == true) {
00102 chi2cut = chi2;
00103 FoundIndex = index;
00104 }
00105 }
00106 return FoundIndex;
00107 }
00108
00109
00110 uint PFElectronAlgo::FindClosestElementCond(const uint iele,
00111 std::multimap<double, unsigned>& Elems,
00112 float& chi2cut,float chi2Comp,
00113 uint indexComp,
00114 std::vector<bool>& active,
00115 const reco::PFBlockRef& blockRef) {
00116 const reco::PFBlock& block = *blockRef;
00117 PFBlock::LinkData linkData = block.linkData();
00118 uint FoundIndex = 100000;
00119 for(std::multimap<double, unsigned>::iterator ie = Elems.begin(); ie != Elems.end(); ++ie ) {
00120 if (ie->second == indexComp && (ie->first + 5.) > chi2Comp) continue;
00121
00122 unsigned index = ie->second;
00123 float chi2 = block.chi2(iele,index,linkData);
00124 if (chi2 < chi2cut && active[index] == true ) {
00125 chi2cut = chi2;
00126 FoundIndex = index;
00127 }
00128 break;
00129 }
00130 return FoundIndex;
00131 }
00132
00133
00134 bool PFElectronAlgo::findLinkPairs(const vector< pair<unsigned, double> >& MinRow ,
00135 const vector<unsigned>& brem_it,
00136 const vector<unsigned>& clust_it,
00137 map<unsigned, unsigned>& finallink,
00138 float chi2cut){
00139
00140
00141 if (MinRow.size() >0 ) {
00142
00143 for (unsigned i1=0; i1< clust_it.size(); i1++) {
00144 double final_chi2 = chi2cut;
00145 unsigned final_brem_index = 100000;
00146 unsigned final_ecal_index = 100000;
00147 for(unsigned i2=0;i2<MinRow.size();i2++) {
00148 if (MinRow[i2].first == clust_it[i1]) {
00149 if (MinRow[i2].second < final_chi2) {
00150 final_chi2 = MinRow[i2].second;
00151 final_brem_index = brem_it[i2];
00152 final_ecal_index = clust_it[i1];
00153 }
00154 }
00155 }
00156 if (final_chi2 < chi2cut) {
00157 finallink.insert(make_pair(final_brem_index,final_ecal_index));
00158 }
00159 }
00160 if (finallink.size() > 0) return true;
00161 else return false;
00162 }
00163 else {
00164 return false;
00165 }
00166 }
00167
00168 void PFElectronAlgo::MultipleGsfTrackAssociation(const reco::PFBlockRef& blockRef){
00169
00170
00171 const reco::PFBlock& block = *blockRef;
00172 const edm::OwnVector< reco::PFBlockElement >& elements = block.elements();
00173 PFBlock::LinkData linkData = block.linkData();
00174 for(unsigned iEle=0; iEle<elements.size(); iEle++) {
00175 PFBlockElement::Type type = elements[iEle].type();
00176 if (type == reco::PFBlockElement::ECAL ) {
00177 std::multimap<double, unsigned> gsfTrack;
00178 block.associatedElements( iEle, linkData,
00179 gsfTrack ,
00180 reco::PFBlockElement::GSF,
00181 reco::PFBlock::LINKTEST_ALL );
00182 if (gsfTrack.size() > 1.) {
00183 for(std::multimap<double, unsigned>::iterator ie = gsfTrack.begin();
00184 ie != gsfTrack.end(); ++ie ) {
00185 unsigned index_gsf = ie->second;
00186 GsfTrackSingleEcal_[index_gsf] = false;
00187 }
00188 }
00189 }
00190 }
00191 return;
00192 }
00193
00194 bool PFElectronAlgo::SetLinks(const reco::PFBlockRef& blockRef,
00195 AssMap& associatedToGSF_,
00196 AssMap& associatedToBrems_,
00197 std::vector<bool>& active){
00198 uint CutIndex = 100000;
00199 double CutGSFECAL = chi2values_[0] ;
00200 double CutBremECAL = chi2values_[1];
00201 double CutGSFHCAL = chi2values_[2];
00202 double CutBremHCAL = chi2values_[3];
00203 double CutGSFPS = chi2values_[4];
00204 double CutBremPS = chi2values_[5];
00205 bool DebugSetLinks = false;
00206
00207 const reco::PFBlock& block = *blockRef;
00208 const edm::OwnVector< reco::PFBlockElement >& elements = block.elements();
00209 PFBlock::LinkData linkData = block.linkData();
00210
00211 bool IsThereAGSFTrack = false;
00212 for(unsigned iEle=0; iEle<elements.size(); iEle++) {
00213
00214 std::map<unsigned, unsigned> FinalBremECALIndex;
00215 std::map<unsigned, unsigned> FinalBremHCALIndex;
00216 std::map<unsigned, unsigned> FinalBremPS1Index;
00217 std::map<unsigned, unsigned> FinalBremPS2Index;
00218 unsigned ECALGSF_index = CutIndex;
00219 unsigned GSF_index = CutIndex;
00220 unsigned KFGSF_index = CutIndex;
00221 unsigned HCALGSF_index = CutIndex;
00222 unsigned PS1GSF_index = CutIndex;
00223 unsigned PS2GSF_index = CutIndex;
00224
00225 PFBlockElement::Type type = elements[iEle].type();
00226 if (type == reco::PFBlockElement::GSF ) {
00227 IsThereAGSFTrack = true;
00228 GSF_index = iEle;
00229
00230 if (!active[iEle]) continue;
00231 if (DebugSetLinks) cout << "PFElectron:: The Block " << block << endl;
00232
00233
00234 if(!GsfTrackSingleEcal_[iEle]) continue;
00235
00236
00237
00238
00239 std::multimap<double, unsigned> kfTrack;
00240 block.associatedElements( iEle, linkData,
00241 kfTrack ,
00242 reco::PFBlockElement::TRACK,
00243 reco::PFBlock::LINKTEST_ALL );
00244 if (kfTrack.size() > 0) {
00245 multimap<double, unsigned>::iterator itkf = kfTrack.begin();
00246 KFGSF_index = itkf->second;
00247 }
00248
00249
00250
00251 std::multimap<double, unsigned> ecalElems;
00252 block.associatedElements( iEle, linkData,
00253 ecalElems ,
00254 reco::PFBlockElement::ECAL,
00255 reco::PFBlock::LINKTEST_ALL );
00256 float chi2ECALGSFFinal = CutGSFECAL;
00257 ECALGSF_index = FindClosestElement(iEle,ecalElems,
00258 chi2ECALGSFFinal,
00259 active,blockRef);
00260
00261 if (DebugSetLinks) {
00262 if (ecalElems.size() > 0) {
00263 cout << "PFElectron:: ECALGSF_index " << ECALGSF_index << " chi2 " << chi2ECALGSFFinal << endl;
00264 }
00265 else {
00266 cout << "PFElectron:: No Link! " << endl;
00267 }
00268 }
00269
00270
00271 std::multimap<double, unsigned> hcalElems;
00272 block.associatedElements( iEle, linkData,
00273 hcalElems ,
00274 reco::PFBlockElement::HCAL,
00275 reco::PFBlock::LINKTEST_ALL );
00276 float chi2HCALGSFFinal = CutGSFHCAL;
00277 HCALGSF_index = FindClosestElement(iEle,hcalElems,
00278 chi2HCALGSFFinal,
00279 active,blockRef);
00280
00281
00282
00283 std::multimap<double, unsigned> ps1Elems;
00284 block.associatedElements( iEle, linkData,
00285 ps1Elems ,
00286 reco::PFBlockElement::PS1,
00287 reco::PFBlock::LINKTEST_ALL );
00288 float chi2PS1GSFFinal = CutGSFPS;
00289 PS1GSF_index = FindClosestElement(iEle,ps1Elems,
00290 chi2PS1GSFFinal,
00291 active,blockRef);
00292
00293
00294
00295 std::multimap<double, unsigned> ps2Elems;
00296 block.associatedElements( iEle, linkData,
00297 ps2Elems ,
00298 reco::PFBlockElement::PS1,
00299 reco::PFBlock::LINKTEST_ALL );
00300 float chi2PS2GSFFinal = CutGSFPS;
00301 PS2GSF_index = FindClosestElement(iEle,ps2Elems,
00302 chi2PS2GSFFinal,
00303 active,blockRef);
00304
00305
00306
00307
00308 std::multimap<double, unsigned> Brems;
00309
00310 block.associatedElements( iEle, linkData,
00311 Brems ,
00312 reco::PFBlockElement::BREM,
00313 reco::PFBlock::LINKTEST_ALL );
00314
00315
00316
00317 vector<unsigned> brems_index(0);
00318 vector<unsigned> mainecal_index(0);
00319 vector< pair<unsigned, double> > BremEcal(0);
00320
00321 for(std::multimap<double, unsigned>::iterator ieb = Brems.begin();
00322 ieb != Brems.end(); ++ieb ) {
00323
00324
00325
00326 unsigned index_brem = ieb->second;
00327 if (DebugSetLinks) cout << "PFElectron:: index brem " << index_brem << endl;
00328
00329 std::multimap<double, unsigned> ecalBremsElems;
00330 block.associatedElements( index_brem, linkData,
00331 ecalBremsElems,
00332 reco::PFBlockElement::ECAL,
00333 reco::PFBlock::LINKTEST_ALL );
00334 float chi2EcalBremFinal = CutBremECAL;
00335 unsigned ECALBREM_index = FindClosestElementCond(index_brem,ecalBremsElems,chi2EcalBremFinal,
00336 chi2ECALGSFFinal,ECALGSF_index,
00337 active,blockRef);
00338
00339 if (ECALBREM_index < CutIndex){
00340 bool NonAlreadyAss = true;
00341 if (BremEcal.size() > 0) {
00342 for (uint ieb = 0; ieb < BremEcal.size(); ieb++){
00343 if (ECALBREM_index == BremEcal[ieb].first) {
00344 NonAlreadyAss = false;
00345 break;
00346 }
00347 }
00348 }
00349 BremEcal.push_back(make_pair(ECALBREM_index,chi2EcalBremFinal));
00350 brems_index.push_back(index_brem);
00351 if (NonAlreadyAss) mainecal_index.push_back(ECALBREM_index);
00352 }
00353 }
00354
00355
00356 bool foundEcalLink = findLinkPairs(BremEcal,brems_index,mainecal_index,
00357 FinalBremECALIndex,CutBremECAL);
00358
00359
00360 vector<unsigned> element_brems(0);
00361 if (foundEcalLink) {
00362 for (map<unsigned, unsigned>::iterator it = FinalBremECALIndex.begin();
00363 it != FinalBremECALIndex.end(); ++it ) {
00364 unsigned index_bremassoecal = it->first;
00365 element_brems.push_back(index_bremassoecal);
00366
00367 if (DebugSetLinks) cout << "PFElectron:: linked index brem " << it->first
00368 <<" index ecal " << it->second << endl;
00369
00370
00371 std::multimap<double, unsigned> hcalBrems;
00372 block.associatedElements( index_bremassoecal, linkData,
00373 hcalBrems ,
00374 reco::PFBlockElement::HCAL,
00375 reco::PFBlock::LINKTEST_ALL );
00376 float chi2HcalBremFinal = CutBremHCAL;
00377 unsigned HCALBREM_index = FindClosestElementCond(index_bremassoecal,hcalBrems,chi2HcalBremFinal,
00378 chi2HCALGSFFinal,HCALGSF_index,
00379 active,blockRef);
00380 if (chi2HcalBremFinal < CutBremHCAL)
00381 FinalBremHCALIndex.insert(make_pair(index_bremassoecal,HCALBREM_index));
00382
00383
00384
00385
00386 std::multimap<double, unsigned> PS1Brems;
00387 block.associatedElements( index_bremassoecal, linkData,
00388 PS1Brems ,
00389 reco::PFBlockElement::PS1,
00390 reco::PFBlock::LINKTEST_ALL );
00391 float chi2PS1BremFinal = CutBremPS;
00392 unsigned PS1BREM_index = FindClosestElementCond(index_bremassoecal,PS1Brems,chi2PS1BremFinal,
00393 chi2PS1GSFFinal,PS1GSF_index,
00394 active,blockRef);
00395 if (chi2PS1BremFinal < CutBremPS)
00396 FinalBremPS1Index.insert(make_pair(index_bremassoecal,PS1BREM_index));
00397
00398
00399
00400
00401 std::multimap<double, unsigned> PS2Brems;
00402 block.associatedElements( index_bremassoecal, linkData,
00403 PS2Brems ,
00404 reco::PFBlockElement::PS2,
00405 reco::PFBlock::LINKTEST_ALL );
00406 float chi2PS2BremFinal = CutBremPS;
00407 unsigned PS2BREM_index = FindClosestElementCond(index_bremassoecal,PS2Brems,chi2PS2BremFinal,
00408 chi2PS2GSFFinal,PS2GSF_index,
00409 active,blockRef);
00410 if (chi2PS2BremFinal < CutBremPS)
00411 FinalBremPS2Index.insert(make_pair(index_bremassoecal,PS2BREM_index));
00412 }
00413 }
00414
00415
00416
00417
00418 vector<unsigned> assoel(0);
00419 if (KFGSF_index < CutIndex) assoel.push_back(KFGSF_index);
00420 if (PS1GSF_index < CutIndex) assoel.push_back(PS1GSF_index);
00421 if (PS2GSF_index < CutIndex) assoel.push_back(PS2GSF_index);
00422 if (ECALGSF_index < CutIndex) assoel.push_back(ECALGSF_index);
00423 if (HCALGSF_index < CutIndex) assoel.push_back(HCALGSF_index);
00424
00425 for (map<unsigned, unsigned>::iterator it = FinalBremECALIndex.begin();
00426 it != FinalBremECALIndex.end(); ++it ) {
00427 unsigned index_brem = it->first;
00428 assoel.push_back(index_brem);
00429 }
00430 associatedToGSF_.push_back(make_pair(GSF_index,assoel));
00431
00432
00433
00434 bool DebugBrem = false;
00435 for(unsigned iBrem=0; iBrem<element_brems.size(); iBrem++) {
00436 vector<unsigned> assobrem(0);
00437 for (map<unsigned, unsigned>::iterator it = FinalBremPS1Index.begin();
00438 it != FinalBremPS1Index.end(); ++it ) {
00439 if (it->first == element_brems[iBrem]) {
00440 unsigned index_clus = it->second;
00441 assobrem.push_back(index_clus);
00442 if(DebugBrem) cout << " In associate BREM " << element_brems[iBrem]
00443 << " PS1 Cluster Associated to BREM "
00444 << index_clus << endl;
00445 }
00446 }
00447 for (map<unsigned, unsigned>::iterator it = FinalBremPS2Index.begin();
00448 it != FinalBremPS2Index.end(); ++it ) {
00449 if (it->first == element_brems[iBrem]) {
00450 unsigned index_clus = it->second;
00451 assobrem.push_back(index_clus);
00452 if(DebugBrem) cout << " In associate BREM " << element_brems[iBrem]
00453 << " PS2 Cluster Associated to BREM "
00454 << index_clus << endl;
00455 }
00456 }
00457
00458 for (map<unsigned, unsigned>::iterator it = FinalBremECALIndex.begin();
00459 it != FinalBremECALIndex.end(); ++it ) {
00460 if (it->first == element_brems[iBrem]) {
00461 unsigned index_clus = it->second;
00462 assobrem.push_back(index_clus);
00463
00464 if(DebugBrem) cout << " In associate BREM " << element_brems[iBrem]
00465 << " ECAL Cluster Associated to BREM "
00466 << index_clus << endl;
00467 }
00468 }
00469 for (map<unsigned, unsigned>::iterator it = FinalBremHCALIndex.begin();
00470 it != FinalBremHCALIndex.end(); ++it ) {
00471 if (it->first == element_brems[iBrem]) {
00472 unsigned index_clus = it->second;
00473 assobrem.push_back(index_clus);
00474 if(DebugBrem) cout << " In associate BREM " << element_brems[iBrem]
00475 << " HCAL Cluster Associated to BREM "
00476 << index_clus << endl;
00477 }
00478 }
00479 associatedToBrems_.push_back(make_pair(element_brems[iBrem],assobrem));
00480 }
00481 }
00482 }
00483
00484 return IsThereAGSFTrack;
00485 }
00486
00487 void PFElectronAlgo::SetIDOutputs(const reco::PFBlockRef& blockRef,
00488 const AssMap& associatedToGSF_,
00489 const AssMap& associatedToBrems_){
00490 PFEnergyCalibration pfcalib_;
00491 const reco::PFBlock& block = *blockRef;
00492 PFBlock::LinkData linkData = block.linkData();
00493 const edm::OwnVector< reco::PFBlockElement >& elements = block.elements();
00494
00495 for (uint igsf = 0; igsf<associatedToGSF_.size();igsf++) {
00496 uint index_gsf = associatedToGSF_[igsf].first;
00497 PFBlockElement::Type typegsf = elements[index_gsf].type();
00498
00499
00500
00501 double GSF_Ein = 0.;
00502 double GSF_Eout = 0.;
00503 double GSF_etaout = 0.;
00504
00505 bool DebugIDOutputs = false;
00506
00507 if (typegsf == reco::PFBlockElement::GSF) {
00508 const reco::PFBlockElementGsfTrack * GsfEl =
00509 dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[index_gsf]));
00510 math::XYZTLorentzVector p_out = GsfEl->Pout();
00511
00512 GSF_Eout = p_out.t();
00513
00514 reco::GsfTrackRef RefGSF = GsfEl->GsftrackRef();
00515 if (RefGSF.isNonnull()) {
00516 float m_el=0.00051;
00517 GSF_Ein = sqrt(RefGSF->pMode()*
00518 RefGSF->pMode()+m_el*m_el);
00519 }
00520
00521
00522 const math::XYZPointF& PosEcal = GsfEl->positionAtECALEntrance();
00523 GSF_etaout = PosEcal.eta();
00524
00525 if (DebugIDOutputs) cout << " setIdOutput! GSF Track " << GSF_Ein
00526 << " ECAL eta,phi " << GSF_etaout
00527 <<", " << PosEcal.phi() << endl;
00528 }
00529
00530
00531 vector<uint> index_assogsf = associatedToGSF_[igsf].second;
00532
00533 double GSFClus_energy = 0.;
00534 double Sigmaetaeta = 0.;
00535 double DiffEtaGSFClust = 0.;
00536 unsigned GSFClus_index = 100000;
00537 double chi2GSFECAL = 0.;
00538 double Tot_BremClustEne = 0.;
00539 bool LateBrem = false;
00540 bool EarlyBrem = false;
00541 int NumBrem = 0;
00542
00543
00544
00545 for (unsigned ielegsf=0;ielegsf<index_assogsf.size();ielegsf++) {
00546 PFBlockElement::Type typeassoele = elements[(index_assogsf[ielegsf])].type();
00547 vector<double> ps1Ene(0);
00548 vector<double> ps2Ene(0);
00549
00550
00551
00552 if (typeassoele == reco::PFBlockElement::PS1) {
00553 PFClusterRef psref = elements[(index_assogsf[ielegsf])].clusterRef();
00554 ps1Ene.push_back(psref->energy());
00555 }
00556 if (typeassoele == reco::PFBlockElement::PS2) {
00557 PFClusterRef psref = elements[(index_assogsf[ielegsf])].clusterRef();
00558 ps2Ene.push_back(psref->energy());
00559 }
00560 if (typeassoele == reco::PFBlockElement::ECAL) {
00561 GSFClus_index = index_assogsf[ielegsf];
00562 reco::PFClusterRef clusterRef = elements[(index_assogsf[ielegsf])].clusterRef();
00563
00564 GSFClus_energy = pfcalib_.energyEm(*clusterRef,ps1Ene,ps2Ene);
00565
00566 chi2GSFECAL = block.chi2(index_gsf,index_assogsf[ielegsf],linkData);
00567 double GSFClus_eta = clusterRef->position().eta();
00568 if (DebugIDOutputs) cout << " setIdOutput! GSF ECAL Cluster E " << GSFClus_energy
00569 << " eta,phi " << GSFClus_eta
00570 <<", " << clusterRef->position().phi() << endl;
00571
00572 DiffEtaGSFClust = GSFClus_eta - GSF_etaout;
00573
00574 const vector< reco::PFRecHitFraction >& PFRecHits = clusterRef->recHitFractions();
00575 double SeedClusEnergy = -1.;
00576 unsigned SeedDetID = 0;
00577 double SeedEta = -1.;
00578 double SeedPhi = -1.;
00579 for ( vector< reco::PFRecHitFraction >::const_iterator it = PFRecHits.begin();
00580 it != PFRecHits.end(); ++it) {
00581 const PFRecHitRef& RefPFRecHit = it->recHitRef();
00582 double energyRecHit = RefPFRecHit->energy();
00583 if (energyRecHit > SeedClusEnergy) {
00584 SeedClusEnergy = energyRecHit;
00585 SeedEta = RefPFRecHit->position().eta();
00586 SeedPhi = RefPFRecHit->position().phi();
00587 SeedDetID = RefPFRecHit->detId();
00588 }
00589 }
00590
00591 for ( vector< reco::PFRecHitFraction >::const_iterator it = PFRecHits.begin();
00592 it != PFRecHits.end(); ++it) {
00593
00594 const PFRecHitRef& RefPFRecHit = it->recHitRef();
00595 double energyRecHit = RefPFRecHit->energy();
00596 if (RefPFRecHit->detId() != SeedDetID) {
00597 float diffEta = RefPFRecHit->position().eta() - SeedEta;
00598 Sigmaetaeta += (diffEta*diffEta) * (energyRecHit/SeedClusEnergy);
00599 }
00600 }
00601 if (Sigmaetaeta == 0.) Sigmaetaeta = 0.00000001;
00602 }
00603
00604
00605 if (typeassoele == reco::PFBlockElement::BREM) {
00606 for (uint ibrem = 0; ibrem < associatedToBrems_.size(); ibrem++){
00607 vector<unsigned> index_assobrem = (associatedToBrems_[ibrem]).second;
00608 unsigned index_brem = (associatedToBrems_[ibrem]).first;
00609 if (index_brem == index_assogsf[ielegsf]) {
00610
00611 const reco::PFBlockElementBrem * BremEl =
00612 dynamic_cast<const reco::PFBlockElementBrem*>((&elements[index_brem]));
00613 unsigned BremTrajP = BremEl->indTrajPoint();
00614 unsigned TrajPos = BremTrajP-2;
00615
00616
00617 if (TrajPos <= 3) EarlyBrem = true;
00618 for (unsigned ielebrem=0;ielebrem<index_assobrem.size();ielebrem++) {
00619 vector<double> ps1EneFromBrem(0);
00620 vector<double> ps2EneFromBrem(0);
00621
00622
00623
00624 if (elements[(index_assobrem[ielebrem])].type() == reco::PFBlockElement::PS1) {
00625 PFClusterRef psref = elements[(index_assobrem[ielebrem])].clusterRef();
00626 ps1EneFromBrem.push_back(psref->energy());
00627 }
00628 if (elements[(index_assobrem[ielebrem])].type() == reco::PFBlockElement::PS2) {
00629 PFClusterRef psref = elements[(index_assobrem[ielebrem])].clusterRef();
00630 ps2EneFromBrem.push_back(psref->energy());
00631 }
00632 if (elements[(index_assobrem[ielebrem])].type() == reco::PFBlockElement::ECAL) {
00633
00634 if( index_assobrem[ielebrem] != GSFClus_index) {
00635 reco::PFClusterRef clusterRef =
00636 elements[(index_assobrem[ielebrem])].clusterRef();
00637
00638 double BremClus_energy =
00639 pfcalib_.energyEm(*clusterRef,ps1EneFromBrem,ps2EneFromBrem);
00640 double chi2BREMECAL =
00641 block.chi2(index_brem,(index_assobrem[ielebrem]),linkData);
00642 if (DebugIDOutputs) cout << " setIdOutput:: GSF BREM Cluster "
00643 << BremClus_energy << " eta,phi "
00644 << clusterRef->position().eta() <<", "
00645 << clusterRef->position().phi()
00646 << " chi " << sqrt(chi2BREMECAL) << endl;
00647 Tot_BremClustEne += BremClus_energy;
00648 NumBrem++;
00649 }
00650 else LateBrem = true;
00651 }
00652 }
00653 }
00654 }
00655 }
00656 }
00657 if (GSFClus_energy > 0.) {
00658 TEtotPinMode = (GSFClus_energy + Tot_BremClustEne) / GSF_Ein;
00659 if (TEtotPinMode > 5.) TEtotPinMode = 5.;
00660 TEGsfPoutMode = GSFClus_energy/GSF_Eout;
00661 if (TEGsfPoutMode > 5.) TEGsfPoutMode = 5.;
00662 TDiffEtaGSFEcalEle = fabs(DiffEtaGSFClust);
00663 if (TDiffEtaGSFEcalEle > 0.2) TDiffEtaGSFEcalEle = 0.2;
00664 TSigmaEtaEtaEle = Sigmaetaeta;
00665 if (TSigmaEtaEtaEle > 0.05) TSigmaEtaEtaEle = 0.05;
00666 TSigmaEtaEtaEle = log(TSigmaEtaEtaEle);
00667
00668 TChiEcalEle = sqrt(chi2GSFECAL);
00669
00670 TNumBrem = NumBrem;
00671 TSumEBremPinPoutMode = 0.;
00672 TLateBrem = -1;
00673 TEarlyBrem = -1;
00674 if (TNumBrem > 0) {
00675 TSumEBremPinPoutMode = Tot_BremClustEne /(GSF_Ein - GSF_Eout);
00676 if (TSumEBremPinPoutMode < 0.) TSumEBremPinPoutMode = 0.;
00677 if (TSumEBremPinPoutMode > 5.) TSumEBremPinPoutMode = 5.;
00678
00679 if (LateBrem == true) TLateBrem = 1;
00680 else TLateBrem = 0;
00681 if (EarlyBrem == true) TEarlyBrem = 1;
00682 else TEarlyBrem = 0;
00683 }
00684
00685 if (DebugIDOutputs) cout << " variables " <<
00686 " TEtotPinMode " << TEtotPinMode << " " <<
00687 " TEGsfPoutMode " << TEGsfPoutMode << " " <<
00688 " TDiffEtaGSFEcalEle " << TDiffEtaGSFEcalEle << " " <<
00689 " TSigmaEtaEtaEle " << TSigmaEtaEtaEle << " " <<
00690 " TChiEcalEle " << TChiEcalEle << " " <<
00691 " TNumBrem " << TNumBrem << " " <<
00692 " TSumEBremPinPoutMode " << TSumEBremPinPoutMode << " " <<
00693 " TLateBrem " << TLateBrem << " " <<
00694 " TEarlyBrem " << TEarlyBrem << " " << endl;
00695
00696
00697 double mvaValue = tmvaReader_->EvaluateMVA("BDT");
00698
00699
00700
00701
00702 if (TEtotPinMode > 1.5 && TEarlyBrem != 1) {BDToutput_[igsf] = -1.;}
00703 else {BDToutput_[igsf] = mvaValue;}
00704
00705
00706 if (DebugIDOutputs) cout << "setIdOutput:: BDT output "
00707 << igsf << " mvaValue "
00708 << BDToutput_[igsf] << endl;
00709 }
00710 }
00711
00712 return;
00713 }
00714
00715
00716
00717 void PFElectronAlgo::SetCandidates(const reco::PFBlockRef& blockRef,
00718 const AssMap& associatedToGSF_,
00719 const AssMap& associatedToBrems_) {
00720
00721 const reco::PFBlock& block = *blockRef;
00722 PFBlock::LinkData linkData = block.linkData();
00723 const edm::OwnVector< reco::PFBlockElement >& elements = block.elements();
00724 PFEnergyResolution pfresol_;
00725 PFEnergyCalibration pfcalib_;
00726 bool DebugIDCandidates = false;
00727
00728 for (uint igsf = 0; igsf<associatedToGSF_.size();igsf++) {
00729 uint index_gsf = associatedToGSF_[igsf].first;
00730 if(BDToutput_[igsf] < mvaEleCut_) continue;
00731
00732
00733
00734 int eecal=0;
00735 int hcal=0;
00736 int charge =0;
00737 bool goodphi=true;
00738 math::XYZTLorentzVector momentum_kf,momentum_gsf,momentum,momentum_mean;
00739 float dpt=0; float dpt_kf=0; float dpt_gsf=0; float dpt_mean=0;
00740 float Eene=0; float dene=0; float Hene=0.;
00741 float de_gs, de_me, de_kf;
00742 float m_el=0.00051;
00743 int nhit_kf=0; int nhit_gsf=0;
00744 bool has_gsf=false;
00745 bool has_kf=false;
00746 math::XYZTLorentzVector newmomentum;
00747 float ps1TotEne = 0;
00748 float ps2TotEne = 0;
00749 vector<uint> elementsToAdd(0);
00750 reco::GsfTrackRef RefGSF;
00751 reco::TrackRef RefKF;
00752
00753
00754 PFBlockElement::Type typegsf = elements[index_gsf].type();
00755 if (typegsf == reco::PFBlockElement::GSF) {
00756 elementsToAdd.push_back(index_gsf);
00757 const reco::PFBlockElementGsfTrack * GsfEl =
00758 dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[index_gsf]));
00759 RefGSF = GsfEl->GsftrackRef();
00760 if (RefGSF.isAvailable()) {
00761 if (RefGSF.isNonnull()) {
00762
00763 has_gsf=true;
00764
00765 charge= RefGSF->chargeMode();
00766 nhit_gsf= RefGSF->hitPattern().trackerLayersWithMeasurement();
00767
00768 momentum_gsf.SetPx(RefGSF->pxMode());
00769 momentum_gsf.SetPy(RefGSF->pyMode());
00770 momentum_gsf.SetPz(RefGSF->pzMode());
00771 float ENE=sqrt(RefGSF->pMode()*
00772 RefGSF->pMode()+m_el*m_el);
00773
00774 if( DebugIDCandidates )
00775 cout << "SetCandidates:: GsfTrackRef: Ene " << ENE
00776 << " charge " << charge << endl;
00777
00778 momentum_gsf.SetE(ENE);
00779 dpt_gsf=RefGSF->ptModeError()*
00780 (RefGSF->pMode()/RefGSF->ptMode());
00781
00782 momentum_mean.SetPx(RefGSF->px());
00783 momentum_mean.SetPy(RefGSF->py());
00784 momentum_mean.SetPz(RefGSF->pz());
00785 float ENEm=sqrt(RefGSF->p()*
00786 RefGSF->p()+m_el*m_el);
00787 momentum_mean.SetE(ENEm);
00788 dpt_mean=RefGSF->ptError()*
00789 (RefGSF->p()/RefGSF->pt());
00790 }
00791 else {
00792 if( DebugIDCandidates )
00793 cout << "SetCandidates:: !!!! NULL GSF Track Ref " << endl;
00794 }
00795 }
00796 else {
00797 if( DebugIDCandidates )
00798 cout << "SetCandidates:: !!!! NotAvailable GSF Track Ref " << endl;
00799 }
00800 }
00801
00802 vector<uint> index_assogsf = associatedToGSF_[igsf].second;
00803 unsigned GSFClus_index = 100000;
00804 for (unsigned ielegsf=0;ielegsf<index_assogsf.size();ielegsf++) {
00805 PFBlockElement::Type typeassoele = elements[(index_assogsf[ielegsf])].type();
00806 if (typeassoele == reco::PFBlockElement::TRACK) {
00807 elementsToAdd.push_back((index_assogsf[ielegsf]));
00808 const reco::PFBlockElementTrack * KfTk =
00809 dynamic_cast<const reco::PFBlockElementTrack*>((&elements[(index_assogsf[ielegsf])]));
00810 RefKF = KfTk->trackRef();
00811 if (RefKF.isAvailable()) {
00812 if (RefKF.isNonnull()) {
00813 has_kf = true;
00814 dpt_kf=(RefKF->ptError()*RefKF->ptError());
00815 nhit_kf=RefKF->hitPattern().trackerLayersWithMeasurement();
00816 momentum_kf.SetPx(RefKF->px());
00817 momentum_kf.SetPy(RefKF->py());
00818 momentum_kf.SetPz(RefKF->pz());
00819 float ENE=sqrt(RefKF->p()*RefKF->p()+m_el*m_el);
00820 if( DebugIDCandidates )
00821 cout << "SetCandidates:: KFTrackRef: Ene " << ENE << endl;
00822
00823 momentum_kf.SetE(ENE);
00824 }
00825 else {
00826 if( DebugIDCandidates )
00827 cout << "SetCandidates:: !!!! NULL KF Track Ref " << endl;
00828 }
00829 }
00830 else {
00831 if( DebugIDCandidates )
00832 cout << "SetCandidates:: !!!! NotAvailable KF Track Ref " << endl;
00833 }
00834 }
00835
00836 vector<double> ps1Ene(0);
00837 vector<double> ps2Ene(0);
00838
00839
00840
00841 if (typeassoele == reco::PFBlockElement::PS1) {
00842 PFClusterRef psref = elements[(index_assogsf[ielegsf])].clusterRef();
00843 ps1Ene.push_back(psref->energy());
00844 ps1TotEne += psref->energy();
00845 elementsToAdd.push_back((index_assogsf[ielegsf]));
00846 }
00847 if (typeassoele == reco::PFBlockElement::PS2) {
00848 PFClusterRef psref = elements[(index_assogsf[ielegsf])].clusterRef();
00849 ps2Ene.push_back(psref->energy());
00850 ps2TotEne += psref->energy();
00851 elementsToAdd.push_back((index_assogsf[ielegsf]));
00852 }
00853
00854 if (typeassoele == reco::PFBlockElement::ECAL) {
00855 elementsToAdd.push_back((index_assogsf[ielegsf]));
00856
00857 GSFClus_index = index_assogsf[ielegsf];
00858
00859 const reco::PFBlockElementCluster * clust =
00860 dynamic_cast<const reco::PFBlockElementCluster*>((&elements[(index_assogsf[ielegsf])]));
00861
00862 eecal++;
00863
00864 reco::PFCluster cl=*clust->clusterRef();
00865
00866 float EE=pfcalib_.energyEm(cl,ps1Ene,ps2Ene);
00867
00868 float ceta=clust->clusterRef()->position().eta();
00869 float cphi=clust->clusterRef()->position().phi();
00870
00871 float mphi=-2.97025;
00872 if (ceta<0) mphi+=0.00638;
00873 for (int ip=1; ip<19; ip++){
00874 float df= cphi - (mphi+(ip*6.283185/18));
00875 if (fabs(df)<0.01) goodphi=false;
00876 }
00877 float dE=pfresol_.getEnergyResolutionEm(EE,clust->clusterRef()->position().eta());
00878 if( DebugIDCandidates )
00879 cout << "SetCandidates:: EcalCluster: Ene " << EE << " dE " << dE <<endl;
00880
00881 Eene+=EE;
00882 dene+=dE*dE;
00883 }
00884
00885 if (typeassoele == reco::PFBlockElement::HCAL) {
00886
00887 const reco::PFBlockElementCluster * clust =
00888 dynamic_cast<const reco::PFBlockElementCluster*>((&elements[(index_assogsf[ielegsf])]));
00889 float df=fabs(momentum_gsf.phi()-clust->clusterRef()->position().phi());
00890 if (df<0.1) {
00891
00892
00893
00894 Hene+=clust->clusterRef()->energy();
00895 hcal++;
00896 }
00897 }
00898
00899
00900 if (typeassoele == reco::PFBlockElement::BREM) {
00901 for (uint ibrem = 0; ibrem < associatedToBrems_.size(); ibrem++){
00902 vector<unsigned> index_assobrem = (associatedToBrems_[ibrem]).second;
00903 unsigned index_brem = (associatedToBrems_[ibrem]).first;
00904 if (index_brem == index_assogsf[ielegsf]) {
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914 elementsToAdd.push_back(index_brem);
00915 for (unsigned ielebrem=0;ielebrem<index_assobrem.size();ielebrem++) {
00916 vector<double> ps1EneFromBrem(0);
00917 vector<double> ps2EneFromBrem(0);
00918
00919
00920
00921 if (elements[(index_assobrem[ielebrem])].type() == reco::PFBlockElement::PS1) {
00922 PFClusterRef psref = elements[(index_assobrem[ielebrem])].clusterRef();
00923 ps1EneFromBrem.push_back(psref->energy());
00924 ps1TotEne += psref->energy();
00925 elementsToAdd.push_back(index_assobrem[ielebrem]);
00926 }
00927 if (elements[(index_assobrem[ielebrem])].type() == reco::PFBlockElement::PS2) {
00928 PFClusterRef psref = elements[(index_assobrem[ielebrem])].clusterRef();
00929 ps2EneFromBrem.push_back(psref->energy());
00930 ps2TotEne += psref->energy();
00931 elementsToAdd.push_back(index_assobrem[ielebrem]);
00932 }
00933
00934 if (elements[(index_assobrem[ielebrem])].type() == reco::PFBlockElement::ECAL) {
00935 if( index_assobrem[ielebrem] != GSFClus_index) {
00936 elementsToAdd.push_back(index_assobrem[ielebrem]);
00937 reco::PFClusterRef clusterRef = elements[(index_assobrem[ielebrem])].clusterRef();
00938
00939 float EE = pfcalib_.energyEm(*clusterRef,ps1EneFromBrem,ps2EneFromBrem);
00940 float ceta = clusterRef->position().eta();
00941
00942 float dE=pfresol_.getEnergyResolutionEm(EE,ceta);
00943 if( DebugIDCandidates ) cout << "SetCandidates:: BremCluster: Ene " << EE << " dE " << dE <<endl;
00944 Eene+=EE;
00945 dene+=dE*dE;
00946 }
00947 }
00948 if (elements[(index_assobrem[ielebrem])].type() == reco::PFBlockElement::HCAL) {
00949 reco::PFClusterRef clusterRef = elements[(index_assobrem[ielebrem])].clusterRef();
00950 float df=fabs(momentum_gsf.phi()-clusterRef->position().phi());
00951 if (df<0.1) {
00952
00953
00954
00955 Hene+= clusterRef->energy();
00956 hcal++;
00957 }
00958 }
00959 }
00960 }
00961 }
00962 }
00963 }
00964 if (has_gsf) {
00965 if ((nhit_gsf<8) && (has_kf)){
00966
00967
00968
00969
00970 de_gs=1-momentum_gsf.E()/Eene;
00971 de_me=1-momentum_mean.E()/Eene;
00972 de_kf=1-momentum_kf.E()/Eene;
00973
00974
00975 momentum=momentum_kf;
00976 float Fe=Eene;
00977
00978 float scale= Fe/momentum.E();
00979
00980 newmomentum.SetPxPyPzE(scale*momentum.Px(),
00981 scale*momentum.Py(),
00982 scale*momentum.Pz(),Fe);
00983
00984
00985 }
00986 if ((nhit_gsf>7) || (has_kf==false)){
00987
00988 de_gs=1-momentum_gsf.E()/Eene;
00989 de_me=1-momentum_mean.E()/Eene;
00990 de_kf=1-momentum_kf.E()/Eene;
00991
00992 momentum=momentum_gsf;
00993 dpt=1/(dpt_gsf*dpt_gsf);
00994
00995 dene= 1/dene;
00996
00997 float Fe=((dene*Eene) +(dpt*momentum.E()))/(dene+dpt);
00998
00999 if ((de_gs>0.05)&&(de_kf>0.05)){
01000 Fe=Eene;
01001 }
01002 if ((de_gs<-0.1)&&(de_me<-0.1) &&(de_kf<0.)){
01003 Fe=momentum.E();
01004 }
01005 float scale= Fe/momentum.E();
01006
01007 newmomentum.SetPxPyPzE(scale*momentum.Px(),
01008 scale*momentum.Py(),
01009 scale*momentum.Pz(),Fe);
01010
01011 }
01012 if (newmomentum.pt()>0.5){
01013
01014
01015
01016
01017 if( DebugIDCandidates )
01018 cout << "SetCandidates:: I am before doing candidate " <<endl;
01019
01020 reco::PFCandidate::ParticleType particleType
01021 = reco::PFCandidate::e;
01022 reco::PFCandidate temp_Candidate;
01023 temp_Candidate = PFCandidate(charge,newmomentum,particleType);
01024 temp_Candidate.set_mva_e_pi(BDToutput_[igsf]);
01025 temp_Candidate.setEcalEnergy(Eene);
01026 temp_Candidate.setHcalEnergy(0.);
01027 temp_Candidate.setPs1Energy(ps1TotEne);
01028 temp_Candidate.setPs2Energy(ps2TotEne);
01029 temp_Candidate.setTrackRef(RefKF);
01030
01031 temp_Candidate.setGsfTrackRef(RefGSF);
01032
01033 if( DebugIDCandidates )
01034 cout << "SetCandidates:: I am after doing candidate " <<endl;
01035
01036 for (uint elad=0; elad<elementsToAdd.size();elad++){
01037 temp_Candidate.addElementInBlock(blockRef,elementsToAdd[elad]);
01038 }
01039
01040 elCandidate_.push_back(temp_Candidate);
01041
01042 }
01043 else {
01044 BDToutput_[igsf] = -1.;
01045
01046 if( DebugIDCandidates )
01047 cout << "SetCandidates:: No Candidate Produced because of Pt cut: 0.5 " <<endl;
01048 }
01049 }
01050 else {
01051 BDToutput_[igsf] = -1.;
01052 if( DebugIDCandidates )
01053 cout << "SetCandidates:: No Candidate Produced because of No GSF Track Ref " <<endl;
01054 }
01055 }
01056 return;
01057 }
01058
01059
01060
01061 void PFElectronAlgo::SetActive(const reco::PFBlockRef& blockRef,
01062 const AssMap& associatedToGSF_,
01063 const AssMap& associatedToBrems_,
01064 std::vector<bool>& active){
01065 const reco::PFBlock& block = *blockRef;
01066 PFBlock::LinkData linkData = block.linkData();
01067 const edm::OwnVector< reco::PFBlockElement >& elements = block.elements();
01068 for (uint igsf = 0; igsf<associatedToGSF_.size();igsf++) {
01069 if(BDToutput_[igsf] < mvaEleCut_) continue;
01070 uint index_gsf = associatedToGSF_[igsf].first;
01071 active[index_gsf] = false;
01072 vector<uint> index_assogsf = associatedToGSF_[igsf].second;
01073 for (unsigned ielegsf=0;ielegsf<index_assogsf.size();ielegsf++) {
01074 PFBlockElement::Type typeassoele = elements[(index_assogsf[ielegsf])].type();
01075 if (typeassoele == reco::PFBlockElement::HCAL) continue;
01076 active[(index_assogsf[ielegsf])] = false;
01077 if (typeassoele == reco::PFBlockElement::BREM) {
01078 for (uint ibrem = 0; ibrem < associatedToBrems_.size(); ibrem++){
01079 vector<unsigned> index_assobrem = (associatedToBrems_[ibrem]).second;
01080 unsigned index_brem = (associatedToBrems_[ibrem]).first;
01081 if (index_brem == index_assogsf[ielegsf]) {
01082
01083 for (unsigned ielebrem=0;ielebrem<index_assobrem.size();ielebrem++) {
01084 if (elements[(index_assobrem[ielebrem])].type() == reco::PFBlockElement::HCAL) continue;
01085 active[(index_assobrem[ielebrem])] = false;
01086 }
01087 }
01088 }
01089 }
01090 }
01091 }
01092 return;
01093 }
01094