00001
00002
00003
00004
00005
00006
00007 #include "RecoParticleFlow/PFProducer/interface/PFPhotonAlgo.h"
00008 #include "DataFormats/ParticleFlowReco/interface/PFBlockElementCluster.h"
00009 #include "DataFormats/ParticleFlowReco/interface/PFCluster.h"
00010 #include "DataFormats/ParticleFlowReco/interface/PFBlockElementSuperCluster.h"
00011 #include "DataFormats/EgammaReco/interface/ElectronSeed.h"
00012 #include "RecoParticleFlow/PFClusterTools/interface/PFEnergyCalibration.h"
00013 #include "DataFormats/Math/interface/deltaPhi.h"
00014 #include "DataFormats/Math/interface/deltaR.h"
00015
00016 #include <iomanip>
00017 #include <algorithm>
00018
00019 using namespace std;
00020 using namespace reco;
00021
00022
00023 PFPhotonAlgo::PFPhotonAlgo(std::string mvaweightfile,
00024 double mvaConvCut,
00025 const reco::Vertex& primary,
00026 const boost::shared_ptr<PFEnergyCalibration>& thePFEnergyCalibration,
00027 double sumPtTrackIsoForPhoton,
00028 double sumPtTrackIsoSlopeForPhoton
00029 ) :
00030 isvalid_(false),
00031 verbosityLevel_(Silent),
00032 MVACUT(mvaConvCut),
00033 thePFEnergyCalibration_(thePFEnergyCalibration),
00034 sumPtTrackIsoForPhoton_(sumPtTrackIsoForPhoton),
00035 sumPtTrackIsoSlopeForPhoton_(sumPtTrackIsoSlopeForPhoton)
00036 {
00037 primaryVertex_=primary;
00038
00039 tmvaReader_ = new TMVA::Reader("!Color:Silent");
00040 tmvaReader_->AddVariable("del_phi",&del_phi);
00041 tmvaReader_->AddVariable("nlayers", &nlayers);
00042 tmvaReader_->AddVariable("chi2",&chi2);
00043 tmvaReader_->AddVariable("EoverPt",&EoverPt);
00044 tmvaReader_->AddVariable("HoverPt",&HoverPt);
00045 tmvaReader_->AddVariable("track_pt", &track_pt);
00046 tmvaReader_->AddVariable("STIP",&STIP);
00047 tmvaReader_->AddVariable("nlost", &nlost);
00048 tmvaReader_->BookMVA("BDT",mvaweightfile.c_str());
00049 }
00050
00051 void PFPhotonAlgo::RunPFPhoton(const reco::PFBlockRef& blockRef,
00052 std::vector<bool>& active,
00053 std::auto_ptr<PFCandidateCollection> &pfCandidates,
00054 std::vector<reco::PFCandidatePhotonExtra>& pfPhotonExtraCandidates,
00055 std::vector<reco::PFCandidate>
00056 &tempElectronCandidates
00057 ){
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 verbosityLevel_ = Chatty;
00070
00071
00072
00073 const edm::OwnVector< reco::PFBlockElement >& elements = blockRef->elements();
00074 edm::OwnVector< reco::PFBlockElement >::const_iterator ele = elements.begin();
00075 std::vector<bool>::const_iterator actIter = active.begin();
00076 PFBlock::LinkData linkData = blockRef->linkData();
00077 bool isActive = true;
00078
00079
00080 if(elements.size() != active.size()) {
00081
00082
00083 return;
00084 }
00085
00086
00087
00088 std::vector<unsigned int> elemsToLock;
00089 elemsToLock.resize(0);
00090
00091 for( ; ele != elements.end(); ++ele, ++actIter ) {
00092
00093
00094 if( !( ele->type() == reco::PFBlockElement::SC ) ) continue;
00095
00096
00097 float photonEnergy_ = 0.;
00098 float photonX_ = 0.;
00099 float photonY_ = 0.;
00100 float photonZ_ = 0.;
00101 float RawEcalEne = 0.;
00102
00103
00104 float ps1TotEne = 0.;
00105 float ps2TotEne = 0.;
00106
00107 bool hasConvTrack=false;
00108 bool hasSingleleg=false;
00109 std::vector<unsigned int> AddClusters(0);
00110 std::vector<unsigned int> IsoTracks(0);
00111 std::multimap<unsigned int, unsigned int>ClusterAddPS1;
00112 std::multimap<unsigned int, unsigned int>ClusterAddPS2;
00113 std::vector<reco::TrackRef>singleLegRef;
00114 std::vector<float>MVA_values(0);
00115 reco::ConversionRefVector ConversionsRef_;
00116 isActive = *(actIter);
00117
00118 const reco::PFBlockElementSuperCluster *sc = dynamic_cast<const reco::PFBlockElementSuperCluster*>(&(*ele));
00119
00120
00121 if (!(sc->fromPhoton()))continue;
00122
00123
00124
00125 if( !isActive ) {
00126
00127 continue;
00128 }
00129 elemsToLock.push_back(ele-elements.begin());
00130
00131 std::multimap<double, unsigned int> ecalAssoPFClusters;
00132 blockRef->associatedElements( ele-elements.begin(),
00133 linkData,
00134 ecalAssoPFClusters,
00135 reco::PFBlockElement::ECAL,
00136 reco::PFBlock::LINKTEST_ALL );
00137
00138
00139 if( ! ecalAssoPFClusters.size() ) {
00140
00141
00142 continue;
00143 }
00144
00145
00146
00147 for(std::multimap<double, unsigned int>::iterator itecal = ecalAssoPFClusters.begin();
00148 itecal != ecalAssoPFClusters.end(); ++itecal) {
00149
00150
00151 reco::PFClusterRef clusterRef = elements[itecal->second].clusterRef();
00152
00153
00154
00155
00156
00157
00158
00159 vector<double> ps1Ene(0);
00160 vector<double> ps2Ene(0);
00161 double ps1=0;
00162 double ps2=0;
00163 hasSingleleg=false;
00164 hasConvTrack=false;
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175 if( !( active[itecal->second] ) ) {
00176
00177 continue;
00178 }
00179
00180
00181
00182
00183 if ( false ) {
00184
00185 bool useIt = true;
00186 int mva_reject=0;
00187 bool isClosest=false;
00188 std::multimap<double, unsigned int> Trackscheck;
00189 blockRef->associatedElements( itecal->second,
00190 linkData,
00191 Trackscheck,
00192 reco::PFBlockElement::TRACK,
00193 reco::PFBlock::LINKTEST_ALL);
00194 for(std::multimap<double, unsigned int>::iterator track = Trackscheck.begin();
00195 track != Trackscheck.end(); ++track) {
00196
00197
00198 if( ! (active[track->second]) ) continue;
00199 hasSingleleg=EvaluateSingleLegMVA(blockRef, primaryVertex_, track->second);
00200
00201 std::multimap<double, unsigned int> closecheck;
00202 blockRef->associatedElements(track->second,
00203 linkData,
00204 closecheck,
00205 reco::PFBlockElement::ECAL,
00206 reco::PFBlock::LINKTEST_ALL);
00207 if(closecheck.begin()->second ==itecal->second)isClosest=true;
00208 if(!hasSingleleg)mva_reject++;
00209 }
00210
00211 if(mva_reject>0 && isClosest)useIt=false;
00212
00213 if( !useIt ) continue;
00214 }
00215
00216
00217
00218 elemsToLock.push_back(itecal->second);
00219
00220
00221 std::multimap<double, unsigned int> PS1Elems;
00222 std::multimap<double, unsigned int> PS2Elems;
00223
00224 blockRef->associatedElements( itecal->second,
00225 linkData,
00226 PS1Elems,
00227 reco::PFBlockElement::PS1,
00228 reco::PFBlock::LINKTEST_ALL );
00229
00230 blockRef->associatedElements( itecal->second,
00231 linkData,
00232 PS2Elems,
00233 reco::PFBlockElement::PS2,
00234 reco::PFBlock::LINKTEST_ALL );
00235
00236
00237 for(std::multimap<double, unsigned int>::iterator iteps = PS1Elems.begin();
00238 iteps != PS1Elems.end(); ++iteps) {
00239
00240
00241 if( !(active[iteps->second]) ) continue;
00242
00243
00244 std::multimap<double, unsigned int> ECALPS1check;
00245 blockRef->associatedElements( iteps->second,
00246 linkData,
00247 ECALPS1check,
00248 reco::PFBlockElement::ECAL,
00249 reco::PFBlock::LINKTEST_ALL );
00250 if(itecal->second==ECALPS1check.begin()->second)
00251 {
00252 reco::PFClusterRef ps1ClusterRef = elements[iteps->second].clusterRef();
00253 ps1Ene.push_back( ps1ClusterRef->energy() );
00254 ps1=ps1+ps1ClusterRef->energy();
00255
00256 elemsToLock.push_back(iteps->second);
00257 }
00258 }
00259 for(std::multimap<double, unsigned int>::iterator iteps = PS2Elems.begin();
00260 iteps != PS2Elems.end(); ++iteps) {
00261
00262
00263 if( !(active[iteps->second]) ) continue;
00264
00265
00266 std::multimap<double, unsigned int> ECALPS2check;
00267 blockRef->associatedElements( iteps->second,
00268 linkData,
00269 ECALPS2check,
00270 reco::PFBlockElement::ECAL,
00271 reco::PFBlock::LINKTEST_ALL );
00272 if(itecal->second==ECALPS2check.begin()->second)
00273 {
00274 reco::PFClusterRef ps2ClusterRef = elements[iteps->second].clusterRef();
00275 ps2Ene.push_back( ps2ClusterRef->energy() );
00276 ps2=ps2ClusterRef->energy()+ps2;
00277
00278 elemsToLock.push_back(iteps->second);
00279 }
00280 }
00281
00282
00283 std::multimap<double, unsigned int> hcalElems;
00284 blockRef->associatedElements( itecal->second,linkData,
00285 hcalElems,
00286 reco::PFBlockElement::HCAL,
00287 reco::PFBlock::LINKTEST_ALL );
00288
00289 for(std::multimap<double, unsigned int>::iterator ithcal = hcalElems.begin();
00290 ithcal != hcalElems.end(); ++ithcal) {
00291
00292 if ( ! (active[ithcal->second] ) ) continue;
00293
00294
00295
00296
00297
00298 bool useHcal = false;
00299 if ( !useHcal ) continue;
00300
00301
00302 }
00303
00304
00305
00306
00307 std::multimap<double, unsigned int> convTracks;
00308 blockRef->associatedElements( itecal->second,
00309 linkData,
00310 convTracks,
00311 reco::PFBlockElement::TRACK,
00312 reco::PFBlock::LINKTEST_ALL);
00313 for(std::multimap<double, unsigned int>::iterator track = convTracks.begin();
00314 track != convTracks.end(); ++track) {
00315
00316
00317 if( ! (active[track->second]) ) continue;
00318
00319
00320 const reco::PFBlockElementTrack * trackRef = dynamic_cast<const reco::PFBlockElementTrack*>((&elements[track->second]));
00321
00322
00323 mvaValue=-999;
00324 hasSingleleg=EvaluateSingleLegMVA(blockRef, primaryVertex_, track->second);
00325
00326
00327
00328
00329
00330
00331
00332 if(!hasSingleleg)
00333 {
00334 bool included=false;
00335
00336 for(unsigned int i=0; i<IsoTracks.size(); i++)
00337 {if(IsoTracks[i]==track->second)included=true;}
00338 if(!included)IsoTracks.push_back(track->second);
00339 }
00340
00341 if(hasSingleleg &&!(trackRef->trackType(reco::PFBlockElement::T_FROM_GAMMACONV)))
00342 {
00343 elemsToLock.push_back(track->second);
00344
00345 reco::TrackRef t_ref=elements[track->second].trackRef();
00346 bool matched=false;
00347 for(unsigned int ic=0; ic<singleLegRef.size(); ic++)
00348 if(singleLegRef[ic]==t_ref)matched=true;
00349
00350 if(!matched){
00351 singleLegRef.push_back(t_ref);
00352 MVA_values.push_back(mvaValue);
00353 }
00354
00355 std::multimap<double, unsigned int> moreClusters;
00356 blockRef->associatedElements( track->second,
00357 linkData,
00358 moreClusters,
00359 reco::PFBlockElement::ECAL,
00360 reco::PFBlock::LINKTEST_ALL);
00361
00362 float p_in=sqrt(elements[track->second].trackRef()->innerMomentum().x() * elements[track->second].trackRef()->innerMomentum().x() +
00363 elements[track->second].trackRef()->innerMomentum().y()*elements[track->second].trackRef()->innerMomentum().y()+
00364 elements[track->second].trackRef()->innerMomentum().z()*elements[track->second].trackRef()->innerMomentum().z());
00365 float linked_E=0;
00366 for(std::multimap<double, unsigned int>::iterator clust = moreClusters.begin();
00367 clust != moreClusters.end(); ++clust)
00368 {
00369 if(!active[clust->second])continue;
00370
00371 linked_E=linked_E+elements[clust->second].clusterRef()->energy();
00372
00373 if(linked_E/p_in>1.5)break;
00374 bool included=false;
00375
00376 for(std::multimap<double, unsigned int>::iterator cluscheck = ecalAssoPFClusters.begin();
00377 cluscheck != ecalAssoPFClusters.end(); ++cluscheck)
00378 {
00379 if(cluscheck->second==clust->second)included=true;
00380 }
00381 if(!included)AddClusters.push_back(clust->second);
00382 }
00383 }
00384
00385
00386
00387 if( ! (trackRef->trackType(reco::PFBlockElement::T_FROM_GAMMACONV) ) ) continue;
00388 hasConvTrack=true;
00389 elemsToLock.push_back(track->second);
00390
00391
00392
00393
00394
00395 std::multimap<double, unsigned int> moreClusters;
00396 blockRef->associatedElements( track->second,
00397 linkData,
00398 moreClusters,
00399 reco::PFBlockElement::ECAL,
00400 reco::PFBlock::LINKTEST_ALL);
00401
00402 float p_in=sqrt(elements[track->second].trackRef()->innerMomentum().x() * elements[track->second].trackRef()->innerMomentum().x() +
00403 elements[track->second].trackRef()->innerMomentum().y()*elements[track->second].trackRef()->innerMomentum().y()+
00404 elements[track->second].trackRef()->innerMomentum().z()*elements[track->second].trackRef()->innerMomentum().z());
00405 float linked_E=0;
00406 for(std::multimap<double, unsigned int>::iterator clust = moreClusters.begin();
00407 clust != moreClusters.end(); ++clust)
00408 {
00409 if(!active[clust->second])continue;
00410 linked_E=linked_E+elements[clust->second].clusterRef()->energy();
00411 if(linked_E/p_in>1.5)break;
00412 bool included=false;
00413 for(std::multimap<double, unsigned int>::iterator cluscheck = ecalAssoPFClusters.begin();
00414 cluscheck != ecalAssoPFClusters.end(); ++cluscheck)
00415 {
00416 if(cluscheck->second==clust->second)included=true;
00417 }
00418 if(!included)AddClusters.push_back(clust->second);
00419 }
00420
00421
00422
00423
00424 std::multimap<double, unsigned int> moreTracks;
00425 blockRef->associatedElements( track->second,
00426 linkData,
00427 moreTracks,
00428 reco::PFBlockElement::TRACK,
00429 reco::PFBlock::LINKTEST_ALL);
00430
00431 for(std::multimap<double, unsigned int>::iterator track2 = moreTracks.begin();
00432 track2 != moreTracks.end(); ++track2) {
00433
00434
00435 if( ! (active[track2->second]) ) continue;
00436
00437 if(track->second==track2->second)continue;
00438
00439 const reco::PFBlockElementTrack * track2Ref = dynamic_cast<const reco::PFBlockElementTrack*>((&elements[track2->second]));
00440 if( ! (track2Ref->trackType(reco::PFBlockElement::T_FROM_GAMMACONV) ) ) continue;
00441 elemsToLock.push_back(track2->second);
00442
00443
00444 std::multimap<double, unsigned int> convEcal;
00445 blockRef->associatedElements( track2->second,
00446 linkData,
00447 convEcal,
00448 reco::PFBlockElement::ECAL,
00449 reco::PFBlock::LINKTEST_ALL);
00450 float p_in=sqrt(elements[track->second].trackRef()->innerMomentum().x()*elements[track->second].trackRef()->innerMomentum().x()+
00451 elements[track->second].trackRef()->innerMomentum().y()*elements[track->second].trackRef()->innerMomentum().y()+
00452 elements[track->second].trackRef()->innerMomentum().z()*elements[track->second].trackRef()->innerMomentum().z());
00453
00454
00455 float linked_E=0;
00456 for(std::multimap<double, unsigned int>::iterator itConvEcal = convEcal.begin();
00457 itConvEcal != convEcal.end(); ++itConvEcal) {
00458
00459 if( ! (active[itConvEcal->second]) ) continue;
00460 bool included=false;
00461 for(std::multimap<double, unsigned int>::iterator cluscheck = ecalAssoPFClusters.begin();
00462 cluscheck != ecalAssoPFClusters.end(); ++cluscheck)
00463 {
00464 if(cluscheck->second==itConvEcal->second)included=true;
00465 }
00466 linked_E=linked_E+elements[itConvEcal->second].clusterRef()->energy();
00467 if(linked_E/p_in>1.5)break;
00468 if(!included){AddClusters.push_back(itConvEcal->second);
00469 }
00470
00471
00472
00473
00474
00475 std::multimap<double, unsigned int> hcalElems_conv;
00476 blockRef->associatedElements( itecal->second,linkData,
00477 hcalElems_conv,
00478 reco::PFBlockElement::HCAL,
00479 reco::PFBlock::LINKTEST_ALL );
00480
00481 for(std::multimap<double, unsigned int>::iterator ithcal2 = hcalElems_conv.begin();
00482 ithcal2 != hcalElems_conv.end(); ++ithcal2) {
00483
00484 if ( ! (active[ithcal2->second] ) ) continue;
00485
00486
00487
00488
00489
00490 bool useHcal = true;
00491 if ( !useHcal ) continue;
00492
00493
00494
00495 }
00496
00497 }
00498
00499 }
00500
00501
00502
00503 }
00504
00505
00506
00507 float addedCalibEne=0;
00508 float addedRawEne=0;
00509 std::vector<double>AddedPS1(0);
00510 std::vector<double>AddedPS2(0);
00511 double addedps1=0;
00512 double addedps2=0;
00513 for(unsigned int i=0; i<AddClusters.size(); i++)
00514 {
00515 std::multimap<double, unsigned int> PS1Elems_conv;
00516 std::multimap<double, unsigned int> PS2Elems_conv;
00517 blockRef->associatedElements(AddClusters[i],
00518 linkData,
00519 PS1Elems_conv,
00520 reco::PFBlockElement::PS1,
00521 reco::PFBlock::LINKTEST_ALL );
00522 blockRef->associatedElements( AddClusters[i],
00523 linkData,
00524 PS2Elems_conv,
00525 reco::PFBlockElement::PS2,
00526 reco::PFBlock::LINKTEST_ALL );
00527
00528 for(std::multimap<double, unsigned int>::iterator iteps = PS1Elems_conv.begin();
00529 iteps != PS1Elems_conv.end(); ++iteps)
00530 {
00531 if(!active[iteps->second])continue;
00532 std::multimap<double, unsigned int> PS1Elems_check;
00533 blockRef->associatedElements(iteps->second,
00534 linkData,
00535 PS1Elems_check,
00536 reco::PFBlockElement::ECAL,
00537 reco::PFBlock::LINKTEST_ALL );
00538 if(PS1Elems_check.begin()->second==AddClusters[i])
00539 {
00540
00541 reco::PFClusterRef ps1ClusterRef = elements[iteps->second].clusterRef();
00542 AddedPS1.push_back(ps1ClusterRef->energy());
00543 addedps1=addedps1+ps1ClusterRef->energy();
00544 elemsToLock.push_back(iteps->second);
00545 }
00546 }
00547
00548 for(std::multimap<double, unsigned int>::iterator iteps = PS2Elems_conv.begin();
00549 iteps != PS2Elems_conv.end(); ++iteps) {
00550 if(!active[iteps->second])continue;
00551 std::multimap<double, unsigned int> PS2Elems_check;
00552 blockRef->associatedElements(iteps->second,
00553 linkData,
00554 PS2Elems_check,
00555 reco::PFBlockElement::ECAL,
00556 reco::PFBlock::LINKTEST_ALL );
00557
00558 if(PS2Elems_check.begin()->second==AddClusters[i])
00559 {
00560 reco::PFClusterRef ps2ClusterRef = elements[iteps->second].clusterRef();
00561 AddedPS2.push_back(ps2ClusterRef->energy());
00562 addedps2=addedps2+ps2ClusterRef->energy();
00563 elemsToLock.push_back(iteps->second);
00564 }
00565 }
00566 reco::PFClusterRef AddclusterRef = elements[AddClusters[i]].clusterRef();
00567 addedRawEne = AddclusterRef->energy()+addedRawEne;
00568 addedCalibEne = thePFEnergyCalibration_->energyEm(*AddclusterRef,AddedPS1,AddedPS2,false)+addedCalibEne;
00569 AddedPS2.clear();
00570 AddedPS1.clear();
00571 elemsToLock.push_back(AddClusters[i]);
00572 }
00573 AddClusters.clear();
00574 float EE = thePFEnergyCalibration_->energyEm(*clusterRef,ps1Ene,ps2Ene,false)+addedCalibEne;
00575
00576
00577 photonEnergy_ += EE;
00578 RawEcalEne += clusterRef->energy()+addedRawEne;
00579 photonX_ += EE * clusterRef->position().X();
00580 photonY_ += EE * clusterRef->position().Y();
00581 photonZ_ += EE * clusterRef->position().Z();
00582 ps1TotEne += ps1+addedps1;
00583 ps2TotEne += ps2+addedps2;
00584 }
00585 AddFromElectron_.clear();
00586 float Elec_energy=0;
00587 float Elec_rawEcal=0;
00588 float Elec_totPs1=0;
00589 float Elec_totPs2=0;
00590 float ElectronX=0;
00591 float ElectronY=0;
00592 float ElectronZ=0;
00593 std::vector<double>AddedPS1(0);
00594 std::vector<double>AddedPS2(0);
00595
00596 EarlyConversion(
00597 tempElectronCandidates,
00598 sc
00599 );
00600
00601 if(AddFromElectron_.size()>0)
00602 {
00603
00604
00605 for(std::vector<unsigned int>::const_iterator it =
00606 AddFromElectron_.begin();
00607 it != AddFromElectron_.end(); ++it)
00608 {
00609
00610 if(elements[*it].type()== reco::PFBlockElement::ECAL)
00611 {
00612
00613 AddedPS1.clear();
00614 AddedPS2.clear();
00615 unsigned int index=*it;
00616 reco::PFClusterRef clusterRef =
00617 elements[index].clusterRef();
00618
00619 Elec_rawEcal=Elec_rawEcal+
00620 elements[index].clusterRef()->energy();
00621 std::multimap<double, unsigned int> PS1Elems;
00622 std::multimap<double, unsigned int> PS2Elems;
00623
00624 blockRef->associatedElements(index,
00625 linkData,
00626 PS1Elems, reco::PFBlockElement::PS1,
00627 reco::PFBlock::LINKTEST_ALL );
00628 blockRef->associatedElements( index,
00629 linkData,
00630 PS2Elems,
00631 reco::PFBlockElement::PS2,
00632 reco::PFBlock::LINKTEST_ALL );
00633
00634
00635 for(std::multimap<double, unsigned int>::iterator iteps =
00636 PS1Elems.begin();
00637 iteps != PS1Elems.end(); ++iteps)
00638 {
00639 std::multimap<double, unsigned int> Clustcheck; blockRef->associatedElements( iteps->second, linkData,
00640 Clustcheck,
00641 reco::PFBlockElement::ECAL,
00642 reco::PFBlock::LINKTEST_ALL );
00643 if(Clustcheck.begin()->second==index)
00644 {
00645 AddedPS1.push_back(elements[iteps->second].clusterRef()->energy());
00646 Elec_totPs1=Elec_totPs1+elements[iteps->second].clusterRef()->energy();
00647 }
00648 }
00649
00650 for(std::multimap<double, unsigned int>::iterator iteps =
00651 PS2Elems.begin();
00652 iteps != PS2Elems.end(); ++iteps)
00653 {
00654 std::multimap<double, unsigned int> Clustcheck; blockRef->associatedElements( iteps->second, linkData,
00655 Clustcheck,
00656 reco::PFBlockElement::ECAL,
00657 reco::PFBlock::LINKTEST_ALL );
00658 if(Clustcheck.begin()->second==index)
00659 {
00660 AddedPS2.push_back(elements[iteps->second].clusterRef()->energy());
00661 Elec_totPs2=Elec_totPs2+elements[iteps->second].clusterRef()->energy();
00662 }
00663 }
00664
00665
00666 float EE=thePFEnergyCalibration_->
00667 energyEm(*clusterRef,AddedPS1,AddedPS2,false);
00668 Elec_energy += EE;
00669 ElectronX += EE * clusterRef->position().X();
00670 ElectronY += EE * clusterRef->position().Y();
00671 ElectronZ += EE * clusterRef->position().Z();
00672
00673 }
00674 }
00675
00676 }
00677
00678
00679 photonEnergy_ += Elec_energy;
00680 RawEcalEne += Elec_rawEcal;
00681 photonX_ += ElectronX;
00682 photonY_ += ElectronY;
00683 photonZ_ += ElectronZ;
00684 ps1TotEne += Elec_totPs1;
00685 ps2TotEne += Elec_totPs2;
00686
00687
00688 if( ! (photonEnergy_ > 0.) ) continue;
00689 float sum_track_pt=0;
00690
00691 for(unsigned int i=0; i<IsoTracks.size(); i++)sum_track_pt=sum_track_pt+elements[IsoTracks[i]].trackRef()->pt();
00692
00693
00694
00695 math::XYZVector photonPosition(photonX_,
00696 photonY_,
00697 photonZ_);
00698
00699 math::XYZVector photonDirection=photonPosition.Unit();
00700
00701 math::XYZTLorentzVector photonMomentum(photonEnergy_* photonDirection.X(),
00702 photonEnergy_* photonDirection.Y(),
00703 photonEnergy_* photonDirection.Z(),
00704 photonEnergy_ );
00705
00706 if(sum_track_pt>(sumPtTrackIsoForPhoton_ + sumPtTrackIsoSlopeForPhoton_ * photonMomentum.pt()))
00707 {
00708
00709 match_ind.clear();
00710 continue;
00711 }
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726 reco::PFCandidate photonCand(0,photonMomentum, reco::PFCandidate::gamma);
00727
00728 photonCand.setPs1Energy(ps1TotEne);
00729 photonCand.setPs2Energy(ps2TotEne);
00730 photonCand.setEcalEnergy(RawEcalEne,photonEnergy_);
00731 photonCand.setHcalEnergy(0.,0.);
00732 photonCand.set_mva_nothing_gamma(1.);
00733 photonCand.setSuperClusterRef(sc->superClusterRef());
00734 math::XYZPoint v(primaryVertex_.x(), primaryVertex_.y(), primaryVertex_.z());
00735 photonCand.setVertex( v );
00736 if(hasConvTrack || hasSingleleg)photonCand.setFlag( reco::PFCandidate::GAMMA_TO_GAMMACONV, true);
00737 int matches=match_ind.size();
00738 int count=0;
00739 for ( std::vector<reco::PFCandidate>::const_iterator ec=tempElectronCandidates.begin(); ec != tempElectronCandidates.end(); ++ec ){
00740 for(int i=0; i<matches; i++)
00741 {
00742 if(count==match_ind[i])photonCand.addDaughter(*ec);
00743 count++;
00744 }
00745 }
00746
00747
00748 isvalid_ = true;
00749
00750
00751 for(std::vector<unsigned int>::const_iterator it =
00752 AddFromElectron_.begin();
00753 it != AddFromElectron_.end(); ++it)photonCand.addElementInBlock(blockRef,*it);
00754
00755
00756
00757 for(std::vector<unsigned int>::const_iterator it = elemsToLock.begin();
00758 it != elemsToLock.end(); ++it)
00759 {
00760 if(active[*it])
00761 {
00762 photonCand.addElementInBlock(blockRef,*it);
00763 if( elements[*it].type() == reco::PFBlockElement::TRACK )
00764 {
00765 if(elements[*it].convRef().isNonnull())
00766 {
00767
00768 bool matched=false;
00769 for(unsigned int ic = 0; ic < ConversionsRef_.size(); ic++)
00770 {
00771 if(ConversionsRef_[ic]==elements[*it].convRef())matched=true;
00772 }
00773 if(!matched)ConversionsRef_.push_back(elements[*it].convRef());
00774 }
00775 }
00776 }
00777 active[*it] = false;
00778 }
00779
00780
00781 PFCandidatePhotonExtra myExtra(sc->superClusterRef());
00782
00783
00784
00785 for(unsigned int ic = 0; ic < MVA_values.size(); ic++)
00786 {
00787 myExtra.addSingleLegConvMva(MVA_values[ic]);
00788 myExtra.addSingleLegConvTrackRef(singleLegRef[ic]);
00789
00790 }
00791 for(unsigned int ic = 0; ic < ConversionsRef_.size(); ic++)
00792 {
00793 myExtra.addConversionRef(ConversionsRef_[ic]);
00794
00795 }
00796 pfPhotonExtraCandidates.push_back(myExtra);
00797 pfCandidates->push_back(photonCand);
00798
00799 elemsToLock.resize(0);
00800 hasConvTrack=false;
00801 hasSingleleg=false;
00802 }
00803
00804 return;
00805
00806 }
00807 bool PFPhotonAlgo::EvaluateSingleLegMVA(const reco::PFBlockRef& blockref, const reco::Vertex& primaryvtx, unsigned int track_index)
00808 {
00809 bool convtkfound=false;
00810 const reco::PFBlock& block = *blockref;
00811 const edm::OwnVector< reco::PFBlockElement >& elements = block.elements();
00812
00813 PFBlock::LinkData linkData = block.linkData();
00814
00815 chi2=elements[track_index].trackRef()->chi2()/elements[track_index].trackRef()->ndof();
00816 nlost=elements[track_index].trackRef()->trackerExpectedHitsInner().numberOfLostHits();
00817 nlayers=elements[track_index].trackRef()->hitPattern().trackerLayersWithMeasurement();
00818 track_pt=elements[track_index].trackRef()->pt();
00819 STIP=elements[track_index].trackRefPF()->STIP();
00820
00821 float linked_e=0;
00822 float linked_h=0;
00823 std::multimap<double, unsigned int> ecalAssoTrack;
00824 block.associatedElements( track_index,linkData,
00825 ecalAssoTrack,
00826 reco::PFBlockElement::ECAL,
00827 reco::PFBlock::LINKTEST_ALL );
00828 std::multimap<double, unsigned int> hcalAssoTrack;
00829 block.associatedElements( track_index,linkData,
00830 hcalAssoTrack,
00831 reco::PFBlockElement::HCAL,
00832 reco::PFBlock::LINKTEST_ALL );
00833 if(ecalAssoTrack.size() > 0) {
00834 for(std::multimap<double, unsigned int>::iterator itecal = ecalAssoTrack.begin();
00835 itecal != ecalAssoTrack.end(); ++itecal) {
00836 linked_e=linked_e+elements[itecal->second].clusterRef()->energy();
00837 }
00838 }
00839 if(hcalAssoTrack.size() > 0) {
00840 for(std::multimap<double, unsigned int>::iterator ithcal = hcalAssoTrack.begin();
00841 ithcal != hcalAssoTrack.end(); ++ithcal) {
00842 linked_h=linked_h+elements[ithcal->second].clusterRef()->energy();
00843 }
00844 }
00845 EoverPt=linked_e/elements[track_index].trackRef()->pt();
00846 HoverPt=linked_h/elements[track_index].trackRef()->pt();
00847 GlobalVector rvtx(elements[track_index].trackRef()->innerPosition().X()-primaryvtx.x(),
00848 elements[track_index].trackRef()->innerPosition().Y()-primaryvtx.y(),
00849 elements[track_index].trackRef()->innerPosition().Z()-primaryvtx.z());
00850 double vtx_phi=rvtx.phi();
00851
00852 del_phi=fabs(deltaPhi(vtx_phi, elements[track_index].trackRef()->innerMomentum().Phi()));
00853 mvaValue = tmvaReader_->EvaluateMVA("BDT");
00854 if(mvaValue > MVACUT)convtkfound=true;
00855 return convtkfound;
00856 }
00857
00858
00859 void PFPhotonAlgo::EarlyConversion(
00860
00861
00862 std::vector<reco::PFCandidate>&
00863 tempElectronCandidates,
00864 const reco::PFBlockElementSuperCluster* sc
00865 ){
00866
00867
00868 int count=0;
00869 for ( std::vector<reco::PFCandidate>::const_iterator ec=tempElectronCandidates.begin(); ec != tempElectronCandidates.end(); ++ec )
00870 {
00871 bool matched=false;
00872 int mh=ec->gsfTrackRef()->trackerExpectedHitsInner().numberOfLostHits();
00873 if(mh==0)continue;
00874
00875 reco::GsfTrackRef gsf=ec->gsfTrackRef();
00876
00877
00878 if(gsf->extra().isAvailable() && gsf->extra()->seedRef().isAvailable())
00879 {
00880 reco::ElectronSeedRef seedRef= gsf->extra()->seedRef().castTo<reco::ElectronSeedRef>();
00881 if(seedRef.isAvailable() && seedRef->isEcalDriven())
00882 {
00883 reco::SuperClusterRef ElecscRef = seedRef->caloCluster().castTo<reco::SuperClusterRef>();
00884
00885 if(ElecscRef.isNonnull()){
00886
00887 reco::SuperClusterRef PhotscRef=sc->superClusterRef();
00888
00889 if(PhotscRef==ElecscRef)
00890 {
00891 match_ind.push_back(count);
00892 matched=true;
00893
00894
00895 reco::PFCandidate::ElementsInBlocks eleInBlocks = ec->elementsInBlocks();
00896 for(unsigned i=0; i<eleInBlocks.size(); i++)
00897 {
00898 reco::PFBlockRef blockRef = eleInBlocks[i].first;
00899 unsigned indexInBlock = eleInBlocks[i].second;
00900
00901
00902
00903 AddFromElectron_.push_back(indexInBlock);
00904 }
00905 }
00906 }
00907 }
00908 }
00909 count++;
00910 }
00911 }