39 #include "Math/PxPyPzM4D.h"
40 #include "Math/LorentzVector.h"
41 #include "Math/DisplacementVector3D.h"
42 #include "Math/SMatrix.h"
43 #include "TDecompChol.h"
45 #include "boost/graph/adjacency_matrix.hpp"
46 #include "boost/graph/graph_utility.hpp"
51 using namespace boost;
53 typedef std::list< reco::PFBlockRef >::iterator
IBR;
77 const boost::shared_ptr<PFEnergyCalibration>& calibration,
78 const boost::shared_ptr<PFEnergyCalibrationHF>& thepfEnergyCalibrationHF) {
91 string mvaWeightFileEleID,
93 const boost::shared_ptr<PFSCEnergyCalibration>& thePFSCEnergyCalibration,
94 const boost::shared_ptr<PFEnergyCalibration>& thePFEnergyCalibration,
95 double sumEtEcalIsoForEgammaSC_barrel,
96 double sumEtEcalIsoForEgammaSC_endcap,
97 double coneEcalIsoForEgammaSC,
98 double sumPtTrackIsoForEgammaSC_barrel,
99 double sumPtTrackIsoForEgammaSC_endcap,
100 unsigned int nTrackIsoForEgammaSC,
101 double coneTrackIsoForEgammaSC,
102 bool applyCrackCorrections,
103 bool usePFSCEleCalib,
105 bool useEGammaSupercluster) {
130 string err =
"PFAlgo: cannot open weight file '";
131 err += mvaWeightFileEleID;
133 throw invalid_argument( err );
137 thePFEnergyCalibration,
153 std::string mvaWeightFileConvID,
157 const boost::shared_ptr<PFEnergyCalibration>& thePFEnergyCalibration,
158 double sumPtTrackIsoForPhoton,
159 double sumPtTrackIsoSlopeForPhoton)
173 e(0, 0) = 0.0015 * 0.0015;
174 e(1, 1) = 0.0015 * 0.0015;
181 FILE * filePhotonConvID = fopen(mvaWeightFileConvID.c_str(),
"r");
182 if (filePhotonConvID) {
183 fclose(filePhotonConvID);
186 string err =
"PFAlgo: cannot open weight file '";
187 err += mvaWeightFileConvID;
189 throw invalid_argument( err );
198 thePFEnergyCalibration,
199 sumPtTrackIsoForPhoton,
200 sumPtTrackIsoSlopeForPhoton
223 GCorrForestBarrel, GCorrForestEndcapHr9,
224 GCorrForestEndcapLr9, PFEcalResolution);
228 std::vector<double> muonECAL,
229 std::vector<double> muonHO,
232 std::vector<double> factors45,
233 bool usePFMuonMomAssign,
234 bool useBestMuonTrack)
248 double minHFCleaningPt,
249 double minSignificance,
250 double maxSignificance,
251 double minSignificanceReduction,
252 double maxDeltaPhiPt,
253 double minDeltaMet) {
265 bool rejectTracks_Step45,
266 bool usePFNuclearInteractions,
267 bool usePFConversions,
269 double dptRel_DispVtx){
286 bool primaryVertexFound =
false;
287 int nVtx=primaryVertices.size();
290 for (
unsigned short i=0 ;
i<primaryVertices.size();++
i)
292 if(primaryVertices[
i].isValid()&&(!primaryVertices[
i].isFake()))
295 primaryVertexFound =
true;
372 cout<<
"*********************************************************"<<endl;
373 cout<<
"***** Particle flow algorithm *****"<<endl;
374 cout<<
"*********************************************************"<<endl;
378 std::list< reco::PFBlockRef > hcalBlockRefs;
379 std::list< reco::PFBlockRef > ecalBlockRefs;
380 std::list< reco::PFBlockRef > hoBlockRefs;
381 std::list< reco::PFBlockRef > otherBlockRefs;
383 for(
unsigned i=0;
i<blocks.size(); ++
i ) {
391 bool singleEcalOrHcal =
false;
392 if( elements.
size() == 1 ){
394 ecalBlockRefs.push_back( blockref );
395 singleEcalOrHcal =
true;
398 hcalBlockRefs.push_back( blockref );
399 singleEcalOrHcal =
true;
403 hoBlockRefs.push_back( blockref );
404 singleEcalOrHcal =
true;
408 if(!singleEcalOrHcal) {
409 otherBlockRefs.push_back( blockref );
414 cout<<
"# Ecal blocks: "<<ecalBlockRefs.size()
415 <<
", # Hcal blocks: "<<hcalBlockRefs.size()
416 <<
", # HO blocks: "<<hoBlockRefs.size()
417 <<
", # Other blocks: "<<otherBlockRefs.size()<<endl;
425 for(
IBR io = otherBlockRefs.begin(); io!=otherBlockRefs.end(); ++io) {
430 std::list< reco::PFBlockRef >
empty;
434 for(
IBR ih = hcalBlockRefs.begin(); ih!=hcalBlockRefs.end(); ++ih) {
435 if (
debug_ )
std::cout <<
"HCAL block number " << hblcks++ << std::endl;
441 for(
IBR ie = ecalBlockRefs.begin(); ie!=ecalBlockRefs.end(); ++ie) {
442 if (
debug_ )
std::cout <<
"ECAL block number " << eblcks++ << std::endl;
452 std::list<reco::PFBlockRef>& hcalBlockRefs,
453 std::list<reco::PFBlockRef>& ecalBlockRefs ) {
456 assert(!blockref.
isNull() );
459 typedef std::multimap<double, unsigned>::iterator IE;
460 typedef std::multimap<double, std::pair<unsigned,math::XYZVector> >::iterator IS;
461 typedef std::multimap<double, std::pair<unsigned,bool> >::iterator
IT;
462 typedef std::multimap< unsigned, std::pair<double, unsigned> >::iterator II;
465 cout<<
"#########################################################"<<endl;
466 cout<<
"##### Process Block: #####"<<endl;
467 cout<<
"#########################################################"<<endl;
477 vector<bool> active( elements.
size(),
true );
482 std::vector<reco::PFCandidate> tempElectronCandidates;
483 tempElectronCandidates.clear();
488 for ( std::vector<reco::PFCandidate>::const_iterator ec=PFElectCandidates_.begin(); ec != PFElectCandidates_.end(); ++ec )tempElectronCandidates.push_back(*ec);
508 cout<<endl<<
"--------------- entering PFPhotonAlgo ----------------"<<endl;
509 vector<PFCandidatePhotonExtra> pfPhotonExtraCand;
514 tempElectronCandidates
524 unsigned int extracand =0;
532 pfPhotonExtraCand.clear();
539 for(
unsigned iEle=0; iEle<elements.
size(); iEle++) {
541 if(type==PFBlockElement::TRACK)
543 if(elements[iEle].trackRef()->
algo() == 12)
548 if(elements[iEle].convRef().isNonnull())active[iEle]=
false;
552 for ( std::vector<reco::PFCandidate>::const_iterator ec=tempElectronCandidates.begin(); ec != tempElectronCandidates.end(); ++ec ){
555 tempElectronCandidates.clear();
559 cout<<endl<<
"--------------- loop 1 ------------------"<<endl;
586 vector<unsigned> hcalIs;
587 vector<unsigned> hoIs;
588 vector<unsigned> ecalIs;
589 vector<unsigned> trackIs;
590 vector<unsigned> ps1Is;
591 vector<unsigned> ps2Is;
593 vector<unsigned> hfEmIs;
594 vector<unsigned> hfHadIs;
597 for(
unsigned iEle=0; iEle<elements.
size(); iEle++) {
600 if(
debug_ && type != PFBlockElement::BREM )
cout<<endl<<elements[iEle];
603 case PFBlockElement::TRACK:
604 if ( active[iEle] ) {
606 if(
debug_)
cout<<
"TRACK, stored index, continue"<<endl;
610 if ( active[iEle] ) {
611 ecalIs.push_back( iEle );
612 if(
debug_)
cout<<
"ECAL, stored index, continue"<<endl;
616 if ( active[iEle] ) {
617 hcalIs.push_back( iEle );
618 if(
debug_)
cout<<
"HCAL, stored index, continue"<<endl;
621 case PFBlockElement::HO:
623 if ( active[iEle] ) {
624 hoIs.push_back( iEle );
625 if(
debug_)
cout<<
"HO, stored index, continue"<<endl;
629 case PFBlockElement::HFEM:
630 if ( active[iEle] ) {
631 hfEmIs.push_back( iEle );
632 if(
debug_)
cout<<
"HFEM, stored index, continue"<<endl;
635 case PFBlockElement::HFHAD:
636 if ( active[iEle] ) {
637 hfHadIs.push_back( iEle );
638 if(
debug_)
cout<<
"HFHAD, stored index, continue"<<endl;
661 unsigned iTrack = iEle;
665 if (active[iTrack] &&
isFromSecInt(elements[iEle],
"primary")){
666 bool isPrimaryTrack = elements[iEle].displacedVertexRef(PFBlockElement::T_TO_DISP)->displacedVertexRef()->isTherePrimaryTracks();
667 if (isPrimaryTrack) {
668 if (
debug_)
cout <<
"Primary Track reconstructed alone" << endl;
670 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEle );
671 active[iTrack] =
false;
677 if ( !active[iTrack] )
678 cout <<
"Already used by electrons, muons, conversions" << endl;
683 if ( ! active[iTrack] )
continue;
686 assert( !trackRef.
isNull() );
689 cout <<
"PFAlgo:processBlock "<<
" "<<trackIs.size()<<
" "<<ecalIs.size()<<
" "<<hcalIs.size()<<
" "<<hoIs.size()<<endl;
696 std::multimap<double, unsigned> ecalElems;
697 block.associatedElements( iTrack, linkData,
702 std::multimap<double, unsigned> hcalElems;
703 block.associatedElements( iTrack, linkData,
711 if ( hcalElems.empty() && !ecalElems.empty() ) {
714 unsigned index = ecalElems.begin()->second;
715 std::multimap<double, unsigned> sortedTracks;
716 block.associatedElements( index, linkData,
723 for(IE ie = sortedTracks.begin(); ie != sortedTracks.end(); ++ie ) {
724 unsigned jTrack = ie->second;
727 if ( !active[jTrack] )
continue;
731 if ( jTrack == iTrack )
continue;
736 std::multimap<double, unsigned> sortedECAL;
737 block.associatedElements( jTrack, linkData,
741 if ( sortedECAL.begin()->second !=
index )
continue;
746 std::multimap<double, unsigned> sortedHCAL;
747 block.associatedElements( jTrack, linkData,
751 if ( !sortedHCAL.size() )
continue;
756 block.setLink( iTrack,
757 sortedHCAL.begin()->second,
758 sortedECAL.begin()->first,
760 PFBlock::LINKTEST_RECHIT );
765 block.associatedElements( iTrack, linkData,
770 if (
debug_ && hcalElems.size() )
771 std::cout <<
"Track linked back to HCAL due to ECAL sharing with other tracks" << std::endl;
781 std::multimap<double,unsigned> gsfElems;
783 block.associatedElements( iTrack, linkData,
789 if(hcalElems.empty() &&
debug_) {
790 cout<<
"no hcal element connected to track "<<iTrack<<endl;
796 bool hcalFound =
false;
799 cout<<
"now looping on elements associated to the track"<<endl;
803 for(IE ie = ecalElems.begin(); ie != ecalElems.end(); ++ie ) {
805 unsigned index = ie->second;
809 double dist = ie->first;
810 cout<<
"\telement "<<elements[
index]<<
" linked with distance = "<< dist <<endl;
811 if ( ! active[index] )
cout <<
"This ECAL is already used - skip it" << endl;
816 if ( ! active[index] )
continue;
822 if( !hcalElems.empty() &&
debug_)
823 cout<<
"\t\tat least one hcal element connected to the track."
824 <<
" Sparing Ecal cluster for the hcal loop"<<endl;
832 if( hcalElems.empty() ) {
835 std::cout <<
"Now deals with tracks linked to no HCAL clusters" << std::endl;
842 std::cout << elements[iTrack] << std::endl;
846 if ( thisIsAMuon ) trackMomentum = 0.;
849 bool rejectFake =
false;
850 if ( !thisIsAMuon && elements[iTrack].trackRef()->ptError() >
ptError_ ) {
854 elements[iTrack].trackRef()->
eta());
857 if ( !ecalElems.empty() ) {
858 unsigned thisEcal = ecalElems.begin()->second;
860 deficit -= clusterRef->energy();
862 clusterRef->positionREP().Eta());
866 bool isPrimary =
isFromSecInt(elements[iTrack],
"primary");
870 active[iTrack] =
false;
872 std::cout << elements[iTrack] << std::endl
873 <<
"is probably a fake (1) --> lock the track"
878 if ( rejectFake )
continue;
883 std::vector<unsigned> tmpi;
884 std::vector<unsigned> kTrack;
887 double Dpt = trackRef->ptError();
890 trackMomentum > 30. && Dpt > 0.5 &&
891 ( trackRef->algo() == TrackBase::iter4 ||
892 trackRef->algo() == TrackBase::iter5 ||
893 trackRef->algo() == TrackBase::iter6 ) ) {
896 double dptRel = Dpt/trackRef->pt()*100;
897 bool isPrimaryOrSecondary =
isFromSecInt(elements[iTrack],
"all");
900 unsigned nHits = elements[iTrack].trackRef()->hitPattern().trackerLayersWithMeasurement();
901 unsigned int NLostHit = trackRef->hitPattern().trackerLayersWithoutMeasurement();
904 std::cout <<
"A track (algo = " << trackRef->algo() <<
") with momentum " << trackMomentum
905 <<
" / " << elements[iTrack].trackRef()->pt() <<
" +/- " << Dpt
906 <<
" / " << elements[iTrack].trackRef()->eta()
907 <<
" without any link to ECAL/HCAL and with " << nHits <<
" (" << NLostHit
908 <<
") hits (lost hits) has been cleaned" << std::endl;
909 active[iTrack] =
false;
915 kTrack.push_back(iTrack);
916 active[iTrack] =
false;
919 if ( ecalElems.empty() ) {
920 (*pfCandidates_)[tmpi[0]].setEcalEnergy( 0., 0. );
921 (*pfCandidates_)[tmpi[0]].setHcalEnergy( 0., 0. );
922 (*pfCandidates_)[tmpi[0]].setHoEnergy( 0., 0. );
923 (*pfCandidates_)[tmpi[0]].setPs1Energy( 0 );
924 (*pfCandidates_)[tmpi[0]].setPs2Energy( 0 );
925 (*pfCandidates_)[tmpi[0]].addElementInBlock( blockref, kTrack[0] );
930 unsigned thisEcal = ecalElems.begin()->second;
932 if (
debug_ )
std::cout <<
" is associated to " << elements[thisEcal] << std::endl;
936 (*pfCandidates_)[tmpi[0]].setEcalEnergy( clusterRef->energy(),
938 (*pfCandidates_)[tmpi[0]].setHcalEnergy( 0., 0. );
939 (*pfCandidates_)[tmpi[0]].setHoEnergy( 0., 0. );
940 (*pfCandidates_)[tmpi[0]].setPs1Energy( 0 );
941 (*pfCandidates_)[tmpi[0]].setPs2Energy( 0 );
942 (*pfCandidates_)[tmpi[0]].addElementInBlock( blockref, kTrack[0] );
945 double slopeEcal = 1.;
946 bool connectedToEcal =
false;
947 unsigned iEcal = 99999;
948 double calibEcal = 0.;
949 double calibHcal = 0.;
950 double totalEcal = thisIsAMuon ? -
muonECAL_[0] : 0.;
953 std::multimap<double, unsigned> sortedTracks;
954 block.associatedElements( thisEcal, linkData,
959 for(IE ie = sortedTracks.begin(); ie != sortedTracks.end(); ++ie ) {
960 unsigned jTrack = ie->second;
963 if ( !active[jTrack] )
continue;
966 if ( jTrack == iTrack )
continue;
971 std::multimap<double, unsigned> sortedECAL;
972 block.associatedElements( jTrack, linkData,
976 if ( sortedECAL.begin()->second != thisEcal )
continue;
982 bool rejectFake =
false;
984 if ( !thatIsAMuon && trackRef->ptError() >
ptError_) {
985 double deficit = trackMomentum + trackRef->p() - clusterRef->energy();
987 clusterRef->positionREP().Eta());
988 resol *= (trackMomentum+trackRef->p());
991 kTrack.push_back(jTrack);
992 active[jTrack] =
false;
994 std::cout << elements[jTrack] << std::endl
995 <<
"is probably a fake (2) --> lock the track"
999 if ( rejectFake )
continue;
1005 if ( !thatIsAMuon ) {
1007 std::cout <<
"Track momentum increased from " << trackMomentum <<
" GeV ";
1008 trackMomentum += trackRef->p();
1010 std::cout <<
"to " << trackMomentum <<
" GeV." << std::endl;
1011 std::cout <<
"with " << elements[jTrack] << std::endl;
1015 totalEcal =
std::max(totalEcal, 0.);
1020 kTrack.push_back(jTrack);
1021 active[jTrack] =
false;
1023 if ( thatIsAMuon ) {
1024 (*pfCandidates_)[tmpi.back()].setEcalEnergy(clusterRef->energy(),
1026 (*pfCandidates_)[tmpi.back()].setHcalEnergy( 0., 0. );
1027 (*pfCandidates_)[tmpi.back()].setHoEnergy( 0., 0. );
1028 (*pfCandidates_)[tmpi.back()].setPs1Energy( 0 );
1029 (*pfCandidates_)[tmpi.back()].setPs2Energy( 0 );
1030 (*pfCandidates_)[tmpi.back()].addElementInBlock( blockref, kTrack.back() );
1035 if (
debug_ )
std::cout <<
"Loop over all associated ECAL clusters" << std::endl;
1037 for(IE ie = ecalElems.begin(); ie != ecalElems.end(); ++ie ) {
1039 unsigned index = ie->second;
1045 if (
debug_ && ! active[index] )
std::cout <<
"is not active - ignore " << std::endl;
1046 if ( ! active[index] )
continue;
1050 block.associatedElements( index, linkData,
1055 for (
unsigned ic=0; ic<kTrack.size();++ic) {
1056 if ( sortedTracks.begin()->second == kTrack[ic] ) {
1061 if (
debug_ && skip )
std::cout <<
"is closer to another track - ignore " << std::endl;
1062 if ( skip )
continue;
1067 assert( !clusterRef.
isNull() );
1070 double dist = ie->first;
1071 std::cout <<
"Ecal cluster with raw energy = " << clusterRef->energy()
1072 <<
" linked with distance = " << dist << std::endl;
1085 vector<double> ps1Ene(1,static_cast<double>(0.));
1087 vector<double> ps2Ene(1,static_cast<double>(0.));
1091 bool crackCorrection =
false;
1092 double ecalEnergy =
calibration_->energyEm(*clusterRef,ps1Ene,ps2Ene,crackCorrection);
1094 std::cout <<
"Corrected ECAL(+PS) energy = " << ecalEnergy << std::endl;
1098 totalEcal += ecalEnergy;
1099 double previousCalibEcal = calibEcal;
1100 double previousSlopeEcal = slopeEcal;
1101 calibEcal =
std::max(totalEcal,0.);
1103 calibration_->energyEmHad(trackMomentum,calibEcal,calibHcal,
1104 clusterRef->positionREP().Eta(),
1105 clusterRef->positionREP().Phi());
1106 if ( totalEcal > 0.) slopeEcal = calibEcal/totalEcal;
1109 std::cout <<
"The total calibrated energy so far amounts to = " << calibEcal << std::endl;
1113 if ( connectedToEcal && calibEcal - trackMomentum >= 0. ) {
1116 calibEcal = previousCalibEcal;
1117 slopeEcal = previousSlopeEcal;
1118 totalEcal = calibEcal/slopeEcal;
1122 active[
index] =
false;
1125 std::multimap<double, unsigned> assTracks;
1126 block.associatedElements( index, linkData,
1133 (*pfCandidates_)[tmpe].setEcalEnergy( clusterRef->energy(), ecalEnergy );
1134 (*pfCandidates_)[tmpe].setHcalEnergy( 0., 0. );
1135 (*pfCandidates_)[tmpe].setHoEnergy( 0., 0. );
1136 (*pfCandidates_)[tmpe].setPs1Energy( ps1Ene[0] );
1137 (*pfCandidates_)[tmpe].setPs2Energy( ps2Ene[0] );
1138 (*pfCandidates_)[tmpe].addElementInBlock( blockref, index );
1140 if(assTracks.size()) {
1141 (*pfCandidates_)[tmpe].addElementInBlock( blockref, assTracks.begin()->second );
1152 connectedToEcal =
true;
1154 active[
index] =
false;
1155 for (
unsigned ic=0; ic<tmpi.size();++ic)
1156 (*
pfCandidates_)[tmpi[ic]].addElementInBlock( blockref, iEcal );
1161 bool bNeutralProduced =
false;
1164 if( connectedToEcal ) {
1206 neutralEnergy /= slopeEcal;
1208 (*pfCandidates_)[tmpj].setEcalEnergy( pivotalRef->energy(), neutralEnergy );
1209 (*pfCandidates_)[tmpj].setHcalEnergy( 0., 0. );
1210 (*pfCandidates_)[tmpj].setHoEnergy( 0., 0. );
1211 (*pfCandidates_)[tmpj].setPs1Energy( 0. );
1212 (*pfCandidates_)[tmpj].setPs2Energy( 0. );
1213 (*pfCandidates_)[tmpj].addElementInBlock(blockref, iEcal);
1214 bNeutralProduced =
true;
1215 for (
unsigned ic=0; ic<kTrack.size();++ic)
1216 (*
pfCandidates_)[tmpj].addElementInBlock( blockref, kTrack[ic] );
1220 for (
unsigned ic=0; ic<tmpi.size();++ic) {
1225 double fraction = (*pfCandidates_)[tmpi[ic]].trackRef()->p()/
trackMomentum;
1226 double ecalCal = bNeutralProduced ?
1227 (calibEcal-neutralEnergy*slopeEcal)*fraction : calibEcal*fraction;
1228 double ecalRaw = totalEcal*fraction;
1230 if (
debug_)
cout <<
"The fraction after photon supression is " << fraction <<
" calibrated ecal = " << ecalCal << endl;
1232 (*pfCandidates_)[tmpi[ic]].setEcalEnergy( ecalRaw, ecalCal );
1233 (*pfCandidates_)[tmpi[ic]].setHcalEnergy( 0., 0. );
1234 (*pfCandidates_)[tmpi[ic]].setHoEnergy( 0., 0. );
1235 (*pfCandidates_)[tmpi[ic]].setPs1Energy( 0 );
1236 (*pfCandidates_)[tmpi[ic]].setPs2Energy( 0 );
1237 (*pfCandidates_)[tmpi[ic]].addElementInBlock( blockref, kTrack[ic] );
1243 for (
unsigned ic=0; ic<tmpi.size();++ic) {
1244 const PFCandidate& pfc = (*pfCandidates_)[tmpi[ic]];
1246 if ( eleInBlocks.size() == 0 ) {
1247 if (
debug_ )
std::cout <<
"Single track / Fill element in block! " << std::endl;
1248 (*pfCandidates_)[tmpi[ic]].addElementInBlock( blockref, kTrack[ic] );
1257 for(IE ie = hcalElems.begin(); ie != hcalElems.end(); ++ie ) {
1259 unsigned index = ie->second;
1265 cout<<
"\telement "<<elements[
index]<<
" linked with distance "<< dist <<endl;
1274 cout<<
"\t\tclosest hcal cluster, doing nothing"<<endl;
1284 cout<<
"\t\tsecondary hcal cluster. unlinking"<<endl;
1285 block.setLink( iTrack, index, -1., linkData,
1286 PFBlock::LINKTEST_RECHIT );
1294 if( !(hfEmIs.empty() && hfHadIs.empty() ) ) {
1297 assert( hfEmIs.size() + hfHadIs.size() == elements.
size() );
1299 if( elements.
size() == 1 ) {
1302 double energyHF = 0.;
1303 double uncalibratedenergyHF = 0.;
1305 switch( clusterRef->layer() ) {
1308 energyHF = clusterRef->energy();
1309 uncalibratedenergyHF = energyHF;
1312 clusterRef->positionREP().Eta(),
1313 clusterRef->positionREP().Phi());
1316 (*pfCandidates_)[tmpi].setEcalEnergy( uncalibratedenergyHF, energyHF );
1317 (*pfCandidates_)[tmpi].setHcalEnergy( 0., 0.);
1318 (*pfCandidates_)[tmpi].setHoEnergy( 0., 0.);
1319 (*pfCandidates_)[tmpi].setPs1Energy( 0. );
1320 (*pfCandidates_)[tmpi].setPs2Energy( 0. );
1321 (*pfCandidates_)[tmpi].addElementInBlock( blockref, hfEmIs[0] );
1326 energyHF = clusterRef->energy();
1327 uncalibratedenergyHF = energyHF;
1330 clusterRef->positionREP().Eta(),
1331 clusterRef->positionREP().Phi());
1334 (*pfCandidates_)[tmpi].setHcalEnergy( uncalibratedenergyHF, energyHF );
1335 (*pfCandidates_)[tmpi].setEcalEnergy( 0., 0.);
1336 (*pfCandidates_)[tmpi].setHoEnergy( 0., 0.);
1337 (*pfCandidates_)[tmpi].setPs1Energy( 0. );
1338 (*pfCandidates_)[tmpi].setPs2Energy( 0. );
1339 (*pfCandidates_)[tmpi].addElementInBlock( blockref, hfHadIs[0] );
1346 else if( elements.
size() == 2 ) {
1356 cem = c0; chad =
c1;
1361 double energyHfEm = cem->energy();
1362 double energyHfHad = chad->energy();
1363 double uncalibratedenergyHFEm = energyHfEm;
1364 double uncalibratedenergyHFHad = energyHfHad;
1369 c0->positionREP().Eta(),
1370 c0->positionREP().Phi());
1372 uncalibratedenergyHFHad,
1373 c1->positionREP().Eta(),
1374 c1->positionREP().Phi());
1377 (*pfCandidates_)[tmpi].setEcalEnergy( uncalibratedenergyHFEm, energyHfEm );
1378 (*pfCandidates_)[tmpi].setHcalEnergy( uncalibratedenergyHFHad, energyHfHad);
1379 (*pfCandidates_)[tmpi].setHoEnergy( 0., 0.);
1380 (*pfCandidates_)[tmpi].setPs1Energy( 0. );
1381 (*pfCandidates_)[tmpi].setPs2Energy( 0. );
1382 (*pfCandidates_)[tmpi].addElementInBlock( blockref, hfEmIs[0] );
1383 (*pfCandidates_)[tmpi].addElementInBlock( blockref, hfHadIs[0] );
1388 cerr<<
"Warning: 2 elements, but not 1 HFEM and 1 HFHAD"<<endl;
1397 cerr<<
"Warning: HF, but n elem different from 1 or 2"<<endl;
1408 cout<<endl<<
"--------------- loop hcal ---------------------"<<endl;
1417 for(
unsigned i=0;
i<hcalIs.size();
i++) {
1419 unsigned iHcal= hcalIs[
i];
1424 if(
debug_)
cout<<endl<<elements[iHcal]<<endl;
1430 std::multimap<double, unsigned> sortedTracks;
1431 block.associatedElements( iHcal, linkData,
1436 std::multimap< unsigned, std::pair<double, unsigned> > associatedEcals;
1438 std::map< unsigned, std::pair<double, double> > associatedPSs;
1440 std::multimap<double, std::pair<unsigned,bool> > associatedTracks;
1443 std::multimap<double,std::pair<unsigned,math::XYZVector> > ecalSatellites;
1444 std::pair<unsigned,math::XYZVector> fakeSatellite = make_pair(iHcal,
math::XYZVector(0.,0.,0.));
1445 ecalSatellites.insert( make_pair(-1., fakeSatellite) );
1447 std::multimap< unsigned, std::pair<double, unsigned> > associatedHOs;
1449 PFClusterRef hclusterref = elements[iHcal].clusterRef();
1450 assert(!hclusterref.
isNull() );
1460 if( sortedTracks.empty() ) {
1462 cout<<
"\tno associated tracks, keep for later"<<endl;
1467 active[iHcal] =
false;
1475 if(
debug_)
cout<<
"\t"<<sortedTracks.size()<<
" associated tracks:"<<endl;
1477 double totalChargedMomentum = 0;
1478 double sumpError2 = 0.;
1479 double totalHO = 0.;
1480 double totalEcal = 0.;
1481 double totalHcal = hclusterref->energy();
1482 vector<double> hcalP;
1483 vector<double> hcalDP;
1484 vector<unsigned> tkIs;
1485 double maxDPovP = -9999.;
1488 vector< unsigned > chargedHadronsIndices;
1489 vector< unsigned > chargedHadronsInBlock;
1490 double mergedNeutralHadronEnergy = 0;
1491 double mergedPhotonEnergy = 0;
1492 double muonHCALEnergy = 0.;
1493 double muonECALEnergy = 0.;
1494 double muonHCALError = 0.;
1495 double muonECALError = 0.;
1496 unsigned nMuons = 0;
1501 hclusterref->position().Y(),
1502 hclusterref->position().Z());
1503 hadronDirection = hadronDirection.Unit();
1507 for(IE ie = sortedTracks.begin(); ie != sortedTracks.end(); ++ie ) {
1509 unsigned iTrack = ie->second;
1512 if ( !active[iTrack] )
continue;
1518 assert( !trackRef.
isNull() );
1523 math::XYZVector chargedDirection(chargedPosition.X(),chargedPosition.Y(),chargedPosition.Z());
1524 chargedDirection = chargedDirection.Unit();
1527 std::multimap<double, unsigned> sortedEcals;
1528 block.associatedElements( iTrack, linkData,
1533 if(
debug_)
cout<<
"\t\t\tnumber of Ecal elements linked to this track: "
1534 <<sortedEcals.size()<<endl;
1537 std::multimap<double, unsigned> sortedHOs;
1539 block.associatedElements( iTrack, linkData,
1546 cout<<
"PFAlgo : number of HO elements linked to this track: "
1547 <<sortedHOs.size()<<endl;
1553 bool thisIsALooseMuon =
false;
1558 if ( thisIsAMuon ) {
1560 std::cout <<
"\t\tThis track is identified as a muon - remove it from the stack" << std::endl;
1561 std::cout <<
"\t\t" << elements[iTrack] << std::endl;
1566 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iTrack );
1567 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHcal );
1573 bool letMuonEatCaloEnergy =
false;
1575 if(thisIsAnIsolatedMuon){
1577 double totalCaloEnergy = totalHcal / 1.30;
1579 if( !sortedEcals.empty() ) {
1580 iEcal = sortedEcals.begin()->second;
1581 PFClusterRef eclusterref = elements[iEcal].clusterRef();
1582 totalCaloEnergy += eclusterref->energy();
1588 if( !sortedHOs.empty() ) {
1589 iHO = sortedHOs.begin()->second;
1591 totalCaloEnergy += eclusterref->energy() / 1.30;
1597 if( (
pfCandidates_->back()).
p() > totalCaloEnergy ) letMuonEatCaloEnergy =
true;
1600 if(letMuonEatCaloEnergy) muonHcal = totalHcal;
1601 double muonEcal =0.;
1603 if( !sortedEcals.empty() ) {
1604 iEcal = sortedEcals.begin()->second;
1605 PFClusterRef eclusterref = elements[iEcal].clusterRef();
1606 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal);
1608 if(letMuonEatCaloEnergy) muonEcal = eclusterref->energy();
1610 if ( eclusterref->energy() - muonEcal < 0.2 ) active[iEcal] =
false;
1611 (*pfCandidates_)[tmpi].setEcalEnergy(eclusterref->energy(), muonEcal);
1616 if( !sortedHOs.empty() ) {
1617 iHO = sortedHOs.begin()->second;
1618 PFClusterRef hoclusterref = elements[iHO].clusterRef();
1619 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHO);
1621 if(letMuonEatCaloEnergy) muonHO = hoclusterref->energy();
1623 if ( hoclusterref->energy() - muonHO < 0.2 ) active[iHO] =
false;
1624 (*pfCandidates_)[tmpi].setHcalEnergy(totalHcal, muonHcal);
1625 (*pfCandidates_)[tmpi].setHoEnergy(hoclusterref->energy(), muonHO);
1628 (*pfCandidates_)[tmpi].setHcalEnergy(totalHcal, muonHcal);
1631 if(letMuonEatCaloEnergy){
1632 muonHCALEnergy += totalHcal;
1633 if (
useHO_) muonHCALEnergy +=muonHO;
1634 muonHCALError += 0.;
1635 muonECALEnergy += muonEcal;
1636 muonECALError += 0.;
1637 photonAtECAL -= muonEcal*chargedDirection;
1638 hadronAtECAL -= totalHcal*chargedDirection;
1639 if ( !sortedEcals.empty() ) active[iEcal] =
false;
1640 active[iHcal] =
false;
1641 if (
useHO_ && !sortedHOs.empty() ) active[iHO] =
false;
1647 if ( muonHO > 0. ) {
1654 photonAtECAL -= muonECAL_[0]*chargedDirection;
1655 hadronAtECAL -= muonHCAL_[0]*chargedDirection;
1659 active[iTrack] =
false;
1666 if(
debug_)
cout<<
"\t\t"<<elements[iTrack]<<endl;
1674 if ( thisIsALooseMuon && !thisIsAMuon ) nMuons += 1;
1679 double Dpt = trackRef->ptError();
1680 double blowError = 1.;
1681 switch (trackRef->algo()) {
1682 case TrackBase::ctf:
1683 case TrackBase::iter0:
1684 case TrackBase::iter1:
1685 case TrackBase::iter2:
1686 case TrackBase::iter3:
1687 case TrackBase::iter4:
1690 case TrackBase::iter5:
1693 case TrackBase::iter6:
1701 bool isPrimaryOrSecondary =
isFromSecInt(elements[iTrack],
"all");
1703 if ( isPrimaryOrSecondary ) blowError = 1.;
1705 std::pair<unsigned,bool> tkmuon = make_pair(iTrack,thisIsALooseMuon);
1706 associatedTracks.insert( make_pair(-Dpt*blowError, tkmuon) );
1709 double Dp = trackRef->qoverpError()*trackMomentum*
trackMomentum;
1710 sumpError2 += Dp*Dp;
1712 bool connectedToEcal =
false;
1713 if( !sortedEcals.empty() )
1717 for ( IE iec=sortedEcals.begin();
1718 iec!=sortedEcals.end(); ++iec ) {
1720 unsigned iEcal = iec->second;
1721 double dist = iec->first;
1724 if( !active[iEcal] ) {
1732 PFClusterRef eclusterref = elements[iEcal].clusterRef();
1733 assert(!eclusterref.
isNull() );
1736 std::multimap<double, unsigned> sortedTracksEcal;
1737 block.associatedElements( iEcal, linkData,
1741 unsigned jTrack = sortedTracksEcal.
begin()->second;
1742 if ( jTrack != iTrack )
continue;
1746 double distEcal = block.dist(jTrack,iEcal,linkData,
1754 vector<double> ps1Ene(1,static_cast<double>(0.));
1756 block, elements, linkData, active,
1758 vector<double> ps2Ene(1,static_cast<double>(0.));
1760 block, elements, linkData, active,
1762 std::pair<double,double> psEnes = make_pair(ps1Ene[0],
1764 associatedPSs.insert(make_pair(iEcal,psEnes));
1767 bool crackCorrection =
false;
1768 float ecalEnergyCalibrated =
calibration_->energyEm(*eclusterref,ps1Ene,ps2Ene,crackCorrection);
1770 eclusterref->position().Y(),
1771 eclusterref->position().Z());
1772 photonDirection = photonDirection.Unit();
1774 if ( !connectedToEcal ) {
1777 <<elements[iEcal]<<endl;
1779 connectedToEcal =
true;
1783 std::pair<unsigned,math::XYZVector> satellite =
1784 make_pair(iEcal,ecalEnergyCalibrated*photonDirection);
1785 ecalSatellites.insert( make_pair(-1., satellite) );
1789 std::pair<unsigned,math::XYZVector> satellite =
1790 make_pair(iEcal,ecalEnergyCalibrated*photonDirection);
1791 ecalSatellites.insert( make_pair(dist, satellite) );
1795 std::pair<double, unsigned> associatedEcal
1796 = make_pair( distEcal, iEcal );
1797 associatedEcals.insert( make_pair(iTrack, associatedEcal) );
1802 if(
useHO_ && !sortedHOs.empty() )
1806 for ( IE ieho=sortedHOs.begin(); ieho!=sortedHOs.end(); ++ieho ) {
1808 unsigned iHO = ieho->second;
1809 double distHO = ieho->first;
1812 if( !active[iHO] ) {
1819 assert( type == PFBlockElement::HO );
1820 PFClusterRef hoclusterref = elements[iHO].clusterRef();
1821 assert(!hoclusterref.
isNull() );
1824 std::multimap<double, unsigned> sortedTracksHO;
1825 block.associatedElements( iHO, linkData,
1829 unsigned jTrack = sortedTracksHO.
begin()->second;
1830 if ( jTrack != iTrack )
continue;
1838 totalHO += hoclusterref->energy();
1839 active[iHO] =
false;
1841 std::pair<double, unsigned> associatedHO
1842 = make_pair( distHO, iHO );
1843 associatedHOs.insert( make_pair(iTrack, associatedHO) );
1852 totalHcal += totalHO;
1856 double caloEnergy = 0.;
1857 double slopeEcal = 1.0;
1858 double calibEcal = 0.;
1859 double calibHcal = 0.;
1860 hadronDirection = hadronAtECAL.Unit();
1864 Caloresolution *= totalChargedMomentum;
1866 Caloresolution =
std::sqrt(Caloresolution*Caloresolution + muonHCALError + muonECALError);
1867 totalEcal -=
std::min(totalEcal,muonECALEnergy);
1868 totalHcal -=
std::min(totalHcal,muonHCALEnergy);
1876 for ( IS is = ecalSatellites.begin(); is != ecalSatellites.end(); ++is ) {
1879 double previousCalibEcal = calibEcal;
1880 double previousCalibHcal = calibHcal;
1881 double previousCaloEnergy = caloEnergy;
1882 double previousSlopeEcal = slopeEcal;
1885 totalEcal +=
sqrt(is->second.second.Mag2());
1886 photonAtECAL += is->second.second;
1887 calibEcal =
std::max(0.,totalEcal);
1888 calibHcal =
std::max(0.,totalHcal);
1889 hadronAtECAL = calibHcal * hadronDirection;
1891 calibration_->energyEmHad(totalChargedMomentum,calibEcal,calibHcal,
1892 hclusterref->positionREP().Eta(),
1893 hclusterref->positionREP().Phi());
1894 caloEnergy = calibEcal+calibHcal;
1895 if ( totalEcal > 0.) slopeEcal = calibEcal/totalEcal;
1897 hadronAtECAL = calibHcal * hadronDirection;
1901 if ( is->first < 0. || caloEnergy - totalChargedMomentum <= 0. ) {
1902 if(
debug_)
cout<<
"\t\t\tactive, adding "<<is->second.second
1903 <<
" to ECAL energy, and locking"<<endl;
1904 active[is->second.first] =
false;
1910 totalEcal -=
sqrt(is->second.second.Mag2());
1911 photonAtECAL -= is->second.second;
1912 calibEcal = previousCalibEcal;
1913 calibHcal = previousCalibHcal;
1914 hadronAtECAL = previousHadronAtECAL;
1915 slopeEcal = previousSlopeEcal;
1916 caloEnergy = previousCaloEnergy;
1923 assert(caloEnergy>=0);
1936 double TotalError =
sqrt(sumpError2 + Caloresolution*Caloresolution);
1940 if ( totalChargedMomentum - caloEnergy >
nSigmaTRACK_*Caloresolution ) {
1955 for ( IT it = associatedTracks.begin(); it != associatedTracks.end(); ++it ) {
1956 unsigned iTrack = it->second.first;
1958 if ( !active[iTrack] )
continue;
1960 if ( !it->second.second )
continue;
1962 bool isTrack = elements[it->second.first].muonRef()->isTrackerMuon();
1963 double trackMomentum = elements[it->second.first].trackRef()->p();
1966 std::multimap<double, unsigned> sortedEcals;
1967 block.associatedElements( iTrack, linkData,
1971 std::multimap<double, unsigned> sortedHOs;
1972 block.associatedElements( iTrack, linkData,
1978 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iTrack );
1979 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHcal );
1982 (*pfCandidates_)[tmpi].setHcalEnergy(totalHcal,muonHcal);
1983 if( !sortedEcals.empty() ) {
1984 unsigned iEcal = sortedEcals.begin()->second;
1985 PFClusterRef eclusterref = elements[iEcal].clusterRef();
1986 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal);
1988 (*pfCandidates_)[tmpi].setEcalEnergy(eclusterref->energy(),muonEcal);
1990 if(
useHO_ && !sortedHOs.empty() ) {
1991 unsigned iHO = sortedHOs.begin()->second;
1992 PFClusterRef hoclusterref = elements[iHO].clusterRef();
1993 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHO);
1995 (*pfCandidates_)[tmpi].setHcalEnergy(totalHcal-totalHO,muonHcal);
1996 (*pfCandidates_)[tmpi].setHoEnergy(hoclusterref->energy(),muonHO);
1999 (*pfCandidates_)[tmpi].setParticleType(particleType);
2003 reco::TrackRef bestMuTrack = elements[it->second.first].muonRef()->muonBestTrack();
2005 bestMuTrack = elements[it->second.first].muonRef()->combinedMuon();
2007 double muonMomentum = bestMuTrack->p();
2008 double muonPtError = bestMuTrack->ptError();
2010 double staMomentum = elements[it->second.first].muonRef()->standAloneMuon()->p();
2011 double staPtError = elements[it->second.first].muonRef()->standAloneMuon()->ptError();
2012 double trackPtError = elements[it->second.first].trackRef()->ptError();
2015 double globalCorr = 1;
2018 if(!isTrack || muonPtError < trackPtError || staPtError < trackPtError){
2019 if(muonPtError < staPtError) globalCorr = muonMomentum/
trackMomentum;
2022 (*pfCandidates_)[tmpi].rescaleMomentum(globalCorr);
2025 std::cout <<
"\tElement " << elements[iTrack] << std::endl
2026 <<
"PFAlgo: particle type set to muon (global, loose), pT = "<<elements[it->second.first].muonRef()->pt()<<std::endl;
2032 std::cout <<
"\tElement " << elements[iTrack] << std::endl
2033 <<
"PFAlgo: particle type set to muon (tracker, loose), pT = "<<elements[it->second.first].muonRef()->pt()<<std::endl;
2041 math::XYZVector chargedDirection(chargedPosition.X(), chargedPosition.Y(), chargedPosition.Z());
2042 chargedDirection = chargedDirection.Unit();
2045 if ( totalEcal > 0. )
2047 if ( totalHcal > 0. )
2052 if ( totalHcal >
muonHCAL_[0] ) hadronAtECAL -=
muonHCAL_[0]*calibHcal/totalHcal * chargedDirection;
2053 caloEnergy = calibEcal+calibHcal;
2056 if ( muonHO > 0. ) {
2059 if ( totalHcal > 0. ) {
2060 calibHcal -=
std::min(calibHcal,muonHO_[0]*calibHcal/totalHcal);
2061 totalHcal -=
std::min(totalHcal,muonHO_[0]);
2066 active[iTrack] =
false;
2073 Caloresolution *= totalChargedMomentum;
2074 Caloresolution =
std::sqrt(Caloresolution*Caloresolution + muonHCALError + muonECALError);
2092 unsigned corrTrack = 10000000;
2093 double corrFact = 1.;
2096 totalChargedMomentum - caloEnergy >
nSigmaTRACK_*Caloresolution) {
2098 for ( IT it = associatedTracks.begin(); it != associatedTracks.end(); ++it ) {
2099 unsigned iTrack = it->second.first;
2101 if ( !active[iTrack] )
continue;
2102 const reco::TrackRef& trackref = elements[it->second.first].trackRef();
2104 double dptRel = fabs(it->first)/trackref->pt()*100;
2105 bool isSecondary =
isFromSecInt(elements[iTrack],
"secondary");
2106 bool isPrimary =
isFromSecInt(elements[iTrack],
"primary");
2110 if ( fabs(it->first) <
ptError_ )
break;
2112 double wouldBeTotalChargedMomentum =
2113 totalChargedMomentum - trackref->p();
2117 if ( wouldBeTotalChargedMomentum > caloEnergy ) {
2119 if (
debug_ && isSecondary) {
2120 cout <<
"In bad track rejection step dptRel = " << dptRel <<
" dptRel_DispVtx_ = " <<
dptRel_DispVtx_ << endl;
2121 cout <<
"The calo energy would be still smaller even without this track but it is attached to a NI"<< endl;
2126 active[iTrack] =
false;
2127 totalChargedMomentum = wouldBeTotalChargedMomentum;
2129 std::cout <<
"\tElement " << elements[iTrack]
2130 <<
" rejected (Dpt = " << -it->first
2131 <<
" GeV/c, algo = " << trackref->algo() <<
")" << std::endl;
2134 if(isPrimary)
break;
2136 corrFact = (caloEnergy - wouldBeTotalChargedMomentum)/elements[it->second.first].trackRef()->p();
2137 if ( trackref->p()*corrFact < 0.05 ) {
2139 active[iTrack] =
false;
2141 totalChargedMomentum -= trackref->p()*(1.-corrFact);
2143 std::cout <<
"\tElement " << elements[iTrack]
2144 <<
" (Dpt = " << -it->first
2145 <<
" GeV/c, algo = " << trackref->algo()
2146 <<
") rescaled by " << corrFact
2147 <<
" Now the total charged momentum is " << totalChargedMomentum << endl;
2155 Caloresolution *= totalChargedMomentum;
2156 Caloresolution =
std::sqrt(Caloresolution*Caloresolution + muonHCALError + muonECALError);
2162 sortedTracks.size() > 1 &&
2163 totalChargedMomentum - caloEnergy >
nSigmaTRACK_*Caloresolution ) {
2164 for ( IT it = associatedTracks.begin(); it != associatedTracks.end(); ++it ) {
2165 unsigned iTrack = it->second.first;
2167 if ( !active[iTrack] )
continue;
2169 double dptRel = fabs(it->first)/trackref->pt()*100;
2170 bool isPrimaryOrSecondary =
isFromSecInt(elements[iTrack],
"all");
2177 switch (trackref->algo()) {
2178 case TrackBase::ctf:
2179 case TrackBase::iter0:
2180 case TrackBase::iter1:
2181 case TrackBase::iter2:
2182 case TrackBase::iter3:
2183 case TrackBase::iter4:
2185 case TrackBase::iter5:
2186 case TrackBase::iter6:
2187 active[iTrack] =
false;
2188 totalChargedMomentum -= trackref->p();
2191 std::cout <<
"\tElement " << elements[iTrack]
2192 <<
" rejected (Dpt = " << -it->first
2193 <<
" GeV/c, algo = " << trackref->algo() <<
")" << std::endl;
2203 Caloresolution *= totalChargedMomentum;
2204 Caloresolution =
std::sqrt(Caloresolution*Caloresolution + muonHCALError + muonECALError);
2208 for ( IT it = associatedTracks.begin(); it != associatedTracks.end(); ++it ) {
2209 unsigned iTrack = it->second.first;
2210 if ( !active[iTrack] )
continue;
2213 double Dp = trackRef->qoverpError()*trackMomentum*
trackMomentum;
2215 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iTrack );
2216 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHcal );
2217 std::pair<II,II> myEcals = associatedEcals.equal_range(iTrack);
2218 for (II ii=myEcals.first; ii!=myEcals.second; ++ii ) {
2219 unsigned iEcal = ii->second.second;
2220 if ( active[iEcal] )
continue;
2221 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal );
2225 std::pair<II,II> myHOs = associatedHOs.equal_range(iTrack);
2226 for (II ii=myHOs.first; ii!=myHOs.second; ++ii ) {
2227 unsigned iHO = ii->second.second;
2228 if ( active[iHO] )
continue;
2229 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHO );
2233 if ( iTrack == corrTrack ) {
2234 (*pfCandidates_)[tmpi].rescaleMomentum(corrFact);
2235 trackMomentum *= corrFact;
2237 chargedHadronsIndices.push_back( tmpi );
2238 chargedHadronsInBlock.push_back( iTrack );
2239 active[iTrack] =
false;
2240 hcalP.push_back(trackMomentum);
2241 hcalDP.push_back(Dp);
2242 if (Dp/trackMomentum > maxDPovP) maxDPovP = Dp/
trackMomentum;
2243 sumpError2 += Dp*Dp;
2247 TotalError =
sqrt(sumpError2 + Caloresolution*Caloresolution);
2250 cout<<
"\tCompare Calo Energy to total charged momentum "<<endl;
2251 cout<<
"\t\tsum p = "<<totalChargedMomentum<<
" +- "<<
sqrt(sumpError2)<<endl;
2252 cout<<
"\t\tsum ecal = "<<totalEcal<<endl;
2253 cout<<
"\t\tsum hcal = "<<totalHcal<<endl;
2254 cout<<
"\t\t => Calo Energy = "<<caloEnergy<<
" +- "<<Caloresolution<<endl;
2255 cout<<
"\t\t => Calo Energy- total charged momentum = "
2256 <<caloEnergy-totalChargedMomentum<<
" +- "<<TotalError<<endl;
2263 double nsigma =
nSigmaHCAL(totalChargedMomentum,hclusterref->positionREP().Eta());
2265 if (
abs(totalChargedMomentum-caloEnergy)<nsigma*TotalError ) {
2271 cout<<
"\t\tcase 1: COMPATIBLE "
2272 <<
"|Calo Energy- total charged momentum| = "
2273 <<
abs(caloEnergy-totalChargedMomentum)
2274 <<
" < "<<nsigma<<
" x "<<TotalError<<endl;
2275 if (maxDPovP < 0.1 )
2276 cout<<
"\t\t\tmax DP/P = "<< maxDPovP
2277 <<
" less than 0.1: do nothing "<<endl;
2279 cout<<
"\t\t\tmax DP/P = "<< maxDPovP
2280 <<
" > 0.1: take weighted averages "<<endl;
2284 if (maxDPovP > 0.1) {
2288 int nrows = chargedHadronsIndices.size();
2289 TMatrixTSym<double>
a (nrows);
2291 TVectorD
check(nrows);
2292 double sigma2E = Caloresolution*Caloresolution;
2293 for(
int i=0;
i<nrows;
i++) {
2294 double sigma2i = hcalDP[
i]*hcalDP[
i];
2296 cout<<
"\t\t\ttrack associated to hcal "<<
i
2297 <<
" P = "<<hcalP[
i]<<
" +- "
2300 a(
i,
i) = 1./sigma2i + 1./sigma2E;
2301 b(
i) = hcalP[
i]/sigma2i + caloEnergy/sigma2E;
2302 for(
int j=0;
j<nrows;
j++) {
2304 a(
i,
j) = 1./sigma2E;
2315 TDecompChol decomp(a);
2317 TVectorD
x = decomp.Solve(b, ok);
2321 for (
int i=0;
i<nrows;
i++){
2323 unsigned ich = chargedHadronsIndices[
i];
2324 double rescaleFactor =
x(
i)/hcalP[
i];
2325 (*pfCandidates_)[ich].rescaleMomentum( rescaleFactor );
2328 cout<<
"\t\t\told p "<<hcalP[
i]
2330 <<
" rescale "<<rescaleFactor<<endl;
2335 cerr<<
"not ok!"<<endl;
2342 else if( caloEnergy > totalChargedMomentum ) {
2361 double eNeutralHadron = caloEnergy - totalChargedMomentum;
2362 double ePhoton = (caloEnergy - totalChargedMomentum) / slopeEcal;
2365 if(!sortedTracks.empty() ){
2366 cout<<
"\t\tcase 2: NEUTRAL DETECTION "
2367 <<caloEnergy<<
" > "<<nsigma<<
"x"<<TotalError
2368 <<
" + "<<totalChargedMomentum<<endl;
2369 cout<<
"\t\tneutral activity detected: "<<endl
2370 <<
"\t\t\t photon = "<<ePhoton<<endl
2371 <<
"\t\t\tor neutral hadron = "<<eNeutralHadron<<endl;
2373 cout<<
"\t\tphoton or hadron ?"<<endl;}
2375 if(sortedTracks.empty() )
2376 cout<<
"\t\tno track -> hadron "<<endl;
2378 cout<<
"\t\t"<<sortedTracks.size()
2379 <<
"tracks -> check if the excess is photonic or hadronic"<<endl;
2383 double ratioMax = 0.;
2385 unsigned maxiEcal= 9999;
2389 for(IE ie = sortedTracks.begin(); ie != sortedTracks.end(); ++ie ) {
2391 unsigned iTrack = ie->second;
2397 assert( !trackRef.
isNull() );
2399 II iae = associatedEcals.find(iTrack);
2401 if( iae == associatedEcals.end() )
continue;
2404 unsigned iEcal = iae->second.second;
2410 assert( !clusterRef.
isNull() );
2412 double pTrack = trackRef->p();
2413 double eECAL = clusterRef->energy();
2414 double eECALOverpTrack = eECAL / pTrack;
2416 if ( eECALOverpTrack > ratioMax ) {
2417 ratioMax = eECALOverpTrack;
2418 maxEcalRef = clusterRef;
2424 std::vector<reco::PFClusterRef> pivotalClusterRef;
2425 std::vector<unsigned> iPivotal;
2426 std::vector<double> particleEnergy, ecalEnergy, hcalEnergy, rawecalEnergy, rawhcalEnergy;
2427 std::vector<math::XYZVector> particleDirection;
2431 if ( ePhoton < totalEcal || eNeutralHadron-calibEcal < 1E-10 ) {
2433 if ( !maxEcalRef.
isNull() ) {
2434 particleEnergy.push_back(ePhoton);
2435 particleDirection.push_back(photonAtECAL);
2436 ecalEnergy.push_back(ePhoton);
2437 hcalEnergy.push_back(0.);
2438 rawecalEnergy.push_back(totalEcal);
2439 rawhcalEnergy.push_back(totalHcal);
2440 pivotalClusterRef.push_back(maxEcalRef);
2441 iPivotal.push_back(maxiEcal);
2443 mergedPhotonEnergy = ePhoton;
2449 if ( !maxEcalRef.
isNull() ) {
2450 pivotalClusterRef.push_back(maxEcalRef);
2451 particleEnergy.push_back(totalEcal);
2452 particleDirection.push_back(photonAtECAL);
2453 ecalEnergy.push_back(totalEcal);
2454 hcalEnergy.push_back(0.);
2455 rawecalEnergy.push_back(totalEcal);
2456 rawhcalEnergy.push_back(totalHcal);
2457 iPivotal.push_back(maxiEcal);
2459 mergedPhotonEnergy = totalEcal;
2463 mergedNeutralHadronEnergy = eNeutralHadron-calibEcal;
2464 if ( mergedNeutralHadronEnergy > 1.0 ) {
2465 pivotalClusterRef.push_back(hclusterref);
2466 particleEnergy.push_back(mergedNeutralHadronEnergy);
2467 particleDirection.push_back(hadronAtECAL);
2468 ecalEnergy.push_back(0.);
2469 hcalEnergy.push_back(mergedNeutralHadronEnergy);
2470 rawecalEnergy.push_back(totalEcal);
2471 rawhcalEnergy.push_back(totalHcal);
2472 iPivotal.push_back(iHcal);
2482 for (
unsigned iPivot=0; iPivot<iPivotal.size(); ++iPivot ) {
2484 if ( particleEnergy[iPivot] < 0. )
2485 std::cout <<
"ALARM = Negative energy ! "
2486 << particleEnergy[iPivot] << std::endl;
2488 bool useDirection =
true;
2490 particleEnergy[iPivot],
2492 particleDirection[iPivot].
X(),
2493 particleDirection[iPivot].Y(),
2494 particleDirection[iPivot].
Z());
2497 (*pfCandidates_)[tmpi].setEcalEnergy( rawecalEnergy[iPivot],ecalEnergy[iPivot] );
2499 (*pfCandidates_)[tmpi].setHcalEnergy( rawhcalEnergy[iPivot],hcalEnergy[iPivot] );
2500 (*pfCandidates_)[tmpi].setHoEnergy(0., 0.);
2502 (*pfCandidates_)[tmpi].setHcalEnergy( rawhcalEnergy[iPivot]-totalHO,hcalEnergy[iPivot]*(1.-totalHO/rawhcalEnergy[iPivot]));
2503 (*pfCandidates_)[tmpi].setHoEnergy(totalHO, totalHO * hcalEnergy[iPivot]/rawhcalEnergy[iPivot]);
2505 (*pfCandidates_)[tmpi].setPs1Energy( 0. );
2506 (*pfCandidates_)[tmpi].setPs2Energy( 0. );
2507 (*pfCandidates_)[tmpi].set_mva_nothing_gamma( -1. );
2510 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHcal );
2511 for (
unsigned ich=0; ich<chargedHadronsInBlock.size(); ++ich) {
2512 unsigned iTrack = chargedHadronsInBlock[ich];
2513 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iTrack );
2519 std::pair<II,II> myEcals = associatedEcals.equal_range(iTrack);
2520 for (II ii=myEcals.first; ii!=myEcals.second; ++ii ) {
2521 unsigned iEcal = ii->second.second;
2522 if ( active[iEcal] )
continue;
2523 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal );
2535 double totalHcalEnergyCalibrated = calibHcal;
2536 double totalEcalEnergyCalibrated = calibEcal;
2551 totalHcalEnergyCalibrated -= mergedNeutralHadronEnergy;
2553 totalEcalEnergyCalibrated -= mergedPhotonEnergy;
2558 double chargedHadronsTotalEnergy = 0;
2559 for(
unsigned ich=0; ich<chargedHadronsIndices.size(); ++ich ) {
2560 unsigned index = chargedHadronsIndices[ich];
2562 chargedHadronsTotalEnergy += chargedHadron.
energy();
2565 for(
unsigned ich=0; ich<chargedHadronsIndices.size(); ++ich ) {
2566 unsigned index = chargedHadronsIndices[ich];
2568 float fraction = chargedHadron.
energy()/chargedHadronsTotalEnergy;
2571 chargedHadron.
setHcalEnergy( fraction * totalHcal, fraction * totalHcalEnergyCalibrated );
2574 chargedHadron.
setHcalEnergy( fraction * (totalHcal-totalHO), fraction * totalHcalEnergyCalibrated * (1.-totalHO/totalHcal) );
2575 chargedHadron.
setHoEnergy( fraction * totalHO, fraction * totalHO * totalHcalEnergyCalibrated / totalHcal );
2578 chargedHadron.
setEcalEnergy( fraction * totalEcal, fraction * totalEcalEnergyCalibrated );
2582 for ( IS is = ecalSatellites.begin(); is != ecalSatellites.end(); ++is ) {
2585 unsigned iEcal = is->second.first;
2586 if ( !active[iEcal] )
continue;
2591 PFClusterRef eclusterref = elements[iEcal].clusterRef();
2592 assert(!eclusterref.
isNull() );
2595 active[iEcal] =
false;
2598 std::multimap<double, unsigned> assTracks;
2599 block.associatedElements( iEcal, linkData,
2606 (*pfCandidates_)[tmpi].setEcalEnergy( eclusterref->energy(),
sqrt(is->second.second.Mag2()) );
2607 (*pfCandidates_)[tmpi].setHcalEnergy( 0., 0. );
2608 (*pfCandidates_)[tmpi].setHoEnergy( 0., 0. );
2609 (*pfCandidates_)[tmpi].setPs1Energy( associatedPSs[iEcal].
first );
2610 (*pfCandidates_)[tmpi].setPs2Energy( associatedPSs[iEcal].
second );
2611 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal );
2612 (*pfCandidates_)[tmpi].addElementInBlock( blockref, sortedTracks.begin()->second) ;
2626 <<
"---- loop remaining hcal ------- "<<endl;
2632 for(
unsigned ihcluster=0; ihcluster<hcalIs.size(); ihcluster++) {
2633 unsigned iHcal = hcalIs[ihcluster];
2636 std::vector<unsigned> ecalRefs;
2637 std::vector<unsigned> hoRefs;
2640 cout<<endl<<elements[iHcal]<<
" ";
2643 if( !active[iHcal] ) {
2645 cout<<
"not active"<<endl;
2650 std::multimap<double, unsigned> ecalElems;
2651 block.associatedElements( iHcal, linkData,
2657 float totalEcal = 0.;
2660 for(IE ie = ecalElems.begin(); ie != ecalElems.end(); ++ie ) {
2662 unsigned iEcal = ie->second;
2663 double dist = ie->first;
2668 if( !active[iEcal] )
continue;
2689 std::multimap<double, unsigned> hcalElems;
2690 block.associatedElements( iEcal, linkData,
2695 bool isClosest =
true;
2696 for(IE ih = hcalElems.begin(); ih != hcalElems.end(); ++ih ) {
2698 unsigned jHcal = ih->second;
2699 double distH = ih->first;
2701 if ( !active[jHcal] )
continue;
2703 if ( distH < dist ) {
2710 if (!isClosest)
continue;
2714 cout<<
"\telement "<<elements[iEcal]<<
" linked with dist "<< dist<<endl;
2715 cout<<
"Added to HCAL cluster to form a neutral hadron"<<endl;
2719 assert( !eclusterRef.
isNull() );
2722 vector<double> ps1Ene(1,static_cast<double>(0.));
2724 vector<double> ps2Ene(1,static_cast<double>(0.));
2726 bool crackCorrection =
false;
2727 double ecalEnergy =
calibration_->energyEm(*eclusterRef,ps1Ene,ps2Ene,crackCorrection);
2731 totalEcal += ecalEnergy;
2732 if ( ecalEnergy > ecalMax ) {
2733 ecalMax = ecalEnergy;
2734 eClusterRef = eclusterRef;
2737 ecalRefs.push_back(iEcal);
2738 active[iEcal] =
false;
2744 double totalHO = 0.;
2748 std::multimap<double, unsigned> hoElems;
2749 block.associatedElements( iHcal, linkData,
2759 for(IE ie = hoElems.begin(); ie != hoElems.end(); ++ie ) {
2761 unsigned iHO = ie->second;
2762 double dist = ie->first;
2764 assert( type == PFBlockElement::HO );
2767 if( !active[iHO] )
continue;
2773 std::multimap<double, unsigned> hcalElems;
2774 block.associatedElements( iHO, linkData,
2779 bool isClosest =
true;
2780 for(IE ih = hcalElems.begin(); ih != hcalElems.end(); ++ih ) {
2782 unsigned jHcal = ih->second;
2783 double distH = ih->first;
2785 if ( !active[jHcal] )
continue;
2787 if ( distH < dist ) {
2794 if (!isClosest)
continue;
2797 cout<<
"\telement "<<elements[iHO]<<
" linked with dist "<< dist<<endl;
2798 cout<<
"Added to HCAL cluster to form a neutral hadron"<<endl;
2802 assert( !hoclusterRef.
isNull() );
2804 double hoEnergy = hoclusterRef->energy();
2806 totalHO += hoEnergy;
2807 if ( hoEnergy > hoMax ) {
2809 hoClusterRef = hoclusterRef;
2813 hoRefs.push_back(iHO);
2814 active[iHO] =
false;
2820 = elements[iHcal].clusterRef();
2821 assert( !hclusterRef.
isNull() );
2824 double totalHcal = hclusterRef->energy();
2826 if (
useHO_ ) totalHcal += totalHO;
2834 double calibEcal = totalEcal > 0. ? totalEcal : 0.;
2835 double calibHcal =
std::max(0.,totalHcal);
2839 calibEcal = totalEcal;
2842 hclusterRef->positionREP().Eta(),
2843 hclusterRef->positionREP().Phi());
2856 calibEcal+calibHcal );
2859 (*pfCandidates_)[tmpi].setEcalEnergy( totalEcal, calibEcal );
2861 (*pfCandidates_)[tmpi].setHcalEnergy( totalHcal, calibHcal );
2862 (*pfCandidates_)[tmpi].setHoEnergy(0.,0.);
2864 (*pfCandidates_)[tmpi].setHcalEnergy( totalHcal-totalHO, calibHcal*(1.-totalHO/totalHcal));
2865 (*pfCandidates_)[tmpi].setHoEnergy(totalHO,totalHO*calibHcal/totalHcal);
2867 (*pfCandidates_)[tmpi].setPs1Energy( 0. );
2868 (*pfCandidates_)[tmpi].setPs2Energy( 0. );
2869 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHcal );
2870 for (
unsigned iec=0; iec<ecalRefs.size(); ++iec)
2871 (*
pfCandidates_)[tmpi].addElementInBlock( blockref, ecalRefs[iec] );
2872 for (
unsigned iho=0; iho<hoRefs.size(); ++iho)
2873 (*
pfCandidates_)[tmpi].addElementInBlock( blockref, hoRefs[iho] );
2882 if(
debug_)
cout<<endl<<
"---- loop ecal------- "<<endl;
2887 for(
unsigned i=0;
i<ecalIs.size();
i++) {
2888 unsigned iEcal = ecalIs[
i];
2891 cout<<endl<<elements[iEcal]<<
" ";
2893 if( ! active[iEcal] ) {
2895 cout<<
"not active"<<endl;
2902 PFClusterRef clusterref = elements[iEcal].clusterRef();
2903 assert(!clusterref.
isNull() );
2905 active[iEcal] =
false;
2908 vector<double> ps1Ene(1,static_cast<double>(0.));
2910 vector<double> ps2Ene(1,static_cast<double>(0.));
2912 bool crackCorrection =
false;
2913 float ecalEnergy =
calibration_->energyEm(*clusterref,ps1Ene,ps2Ene,crackCorrection);
2915 double particleEnergy = ecalEnergy;
2920 (*pfCandidates_)[tmpi].setEcalEnergy( clusterref->energy(),ecalEnergy );
2921 (*pfCandidates_)[tmpi].setHcalEnergy( 0., 0. );
2922 (*pfCandidates_)[tmpi].setHoEnergy( 0., 0. );
2923 (*pfCandidates_)[tmpi].setPs1Energy( 0. );
2924 (*pfCandidates_)[tmpi].setPs2Energy( 0. );
2925 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal );
2947 double px = track.
px();
2948 double py = track.
py();
2949 double pz = track.
pz();
2950 double energy =
sqrt(track.
p()*track.
p() + 0.13957*0.13957);
2963 bool globalFitUsed =
false;
2965 if ( thisIsAMuon ) {
2971 energy =
sqrt(muonRef->p()*muonRef->p() + 0.1057*0.1057);
2974 if(
debug_)
if(!trackRef->quality(trackQualityHighPurity))
cout<<
" Low Purity Track "<<endl;
2980 bestMuTrack = muonRef->combinedMuon();
2983 bool useGlobalFit =
false;
2985 if(thisIsAnIsolatedMuon && (!muonRef->isTrackerMuon() || (muonRef->pt() > bestMuTrack->pt() && track.
ptError() > 5.0*bestMuTrack->ptError()))) useGlobalFit =
true;
2986 else if(!trackRef->quality(trackQualityHighPurity)) useGlobalFit =
true;
2987 else if(muonRef->pt() > bestMuTrack->pt() &&
2989 track.
ptError() > 5.0*bestMuTrack->ptError()) useGlobalFit =
true;
2992 px = bestMuTrack->px();
2993 py = bestMuTrack->py();
2994 pz = bestMuTrack->pz();
2995 energy =
sqrt(bestMuTrack->p()*bestMuTrack->p() + 0.1057*0.1057);
2996 globalFitUsed =
true;
3001 if(thisIsAGlobalTightMuon)
3004 if(muonRef->isTrackerMuon()){
3005 if(
sqrt(px*px+py*py) > 10){
3009 bestMuTrack = muonRef->combinedMuon();
3011 px = bestMuTrack->px();
3012 py = bestMuTrack->py();
3013 pz = bestMuTrack->pz();
3014 energy =
sqrt(bestMuTrack->p()*bestMuTrack->p() + 0.1057*0.1057);
3015 globalFitUsed =
true;
3020 reco::TrackRef bestMuTrack = muonRef->combinedMuon()->normalizedChi2() < muonRef->standAloneMuon()->normalizedChi2() ?
3021 muonRef->muonBestTrack() :
3022 muonRef->standAloneMuon() ;
3026 muonRef->combinedMuon()->normalizedChi2() < muonRef->standAloneMuon()->normalizedChi2() ?
3027 muonRef->combinedMuon() :
3028 muonRef->standAloneMuon() ;
3030 px = bestMuTrack->px();
3031 py = bestMuTrack->py();
3032 pz = bestMuTrack->pz();
3033 energy =
sqrt(bestMuTrack->p()*bestMuTrack->p() + 0.1057*0.1057);
3034 globalFitUsed =
true;
3039 else if (isFromDisp) {
3040 double Dpt = trackRef->ptError();
3041 double dptRel = Dpt/trackRef->pt()*100;
3048 cout <<
"Not refitted px = " << px <<
" py = " << py <<
" pz = " << pz <<
" energy = " << energy << endl;
3051 reco::Track trackRefit = vRef->refittedTrack(trackRef);
3052 px = trackRefit.
px();
3053 py = trackRefit.
py();
3054 pz = trackRefit.
pz();
3055 energy =
sqrt(trackRefit.
p()*trackRefit.
p() + 0.13957*0.13957);
3057 cout <<
"Refitted px = " << px <<
" py = " << py <<
" pz = " << pz <<
" energy = " << energy << endl;
3062 if ((isFromDisp || isToDisp) &&
debug_)
cout <<
"Final px = " << px <<
" py = " << py <<
" pz = " << pz <<
" energy = " << energy << endl;
3081 if( isToDisp && !thisIsAMuon ) {
3088 if ( thisIsAMuon && globalFitUsed )
3089 pfCandidates_->back().setVertexSource( PFCandidate::kComMuonVertex );
3091 pfCandidates_->back().setVertexSource( PFCandidate::kTrkVertex );
3106 if(thisIsAGlobalTightMuon)
cout <<
"PFAlgo: particle type set to muon (global, tight), pT = " <<muonRef->pt()<< endl;
3107 else if(thisIsATrackerTightMuon)
cout <<
"PFAlgo: particle type set to muon (tracker, tight), pT = " <<muonRef->pt()<< endl;
3108 else if(thisIsAnIsolatedMuon)
cout <<
"PFAlgo: particle type set to muon (isolated), pT = " <<muonRef->pt()<< endl;
3109 else cout<<
" problem with muon assignment "<<endl;
3130 double particleEnergy,
3143 if ( useDirection ) {
3144 switch( cluster.
layer() ) {
3147 factor =
std::sqrt(cluster.
position().Perp2()/(particleX*particleX+particleY*particleY));
3153 factor = cluster.
position().Z()/particleZ;
3168 cluster.
position().Y()-vertexPos.Y(),
3169 cluster.
position().Z()-vertexPos.Z());
3171 particleY*factor-vertexPos.Y(),
3172 particleZ*factor-vertexPos.Z() );
3177 clusterPos = useDirection ? particleDirection.Unit() : clusterPos.Unit();
3178 clusterPos *= particleEnergy;
3184 ROOT::Math::LorentzVector<ROOT::Math::PxPyPzM4D<double> >
3185 momentum( clusterPos.X(), clusterPos.Y(), clusterPos.Z(),
mass);
3195 switch( cluster.
layer() ) {
3198 particleType = PFCandidate::gamma;
3202 particleType = PFCandidate::h0;
3205 particleType = PFCandidate::h_HF;
3208 particleType = PFCandidate::egamma_HF;
3244 if ( clusterEnergyHCAL < 1. ) clusterEnergyHCAL = 1.;
3246 double resol = fabs(eta) < 1.48 ?
3247 sqrt (1.02*1.02/clusterEnergyHCAL + 0.065*0.065)
3249 sqrt (1.20*1.20/clusterEnergyHCAL + 0.028*0.028);
3257 double nS = fabs(eta) < 1.48 ?
3267 if(!out )
return out;
3269 out<<
"====== Particle Flow Algorithm ======= ";
3276 out<<
"reconstructed particles: "<<endl;
3278 const std::auto_ptr< reco::PFCandidateCollection >&
3281 if(!candidates.get() ) {
3282 out<<
"candidates already transfered"<<endl;
3311 std::vector<bool>& active,
3312 std::vector<double>& psEne) {
3320 std::multimap<double, unsigned> sortedPS;
3321 typedef std::multimap<double, unsigned>::iterator IE;
3323 sortedPS, psElementType,
3327 double totalPS = 0.;
3328 for ( IE ips=sortedPS.begin(); ips!=sortedPS.end(); ++ips ) {
3331 unsigned iPS = ips->second;
3335 if (!active[iPS])
continue;
3338 std::multimap<double, unsigned> sortedECAL;
3343 unsigned jEcal = sortedECAL.begin()->second;
3344 if ( jEcal != iEcal )
continue;
3348 assert( pstype == psElementType );
3349 PFClusterRef psclusterref = elements[iPS].clusterRef();
3350 assert(!psclusterref.
isNull() );
3351 totalPS += psclusterref->energy();
3352 psEne[0] += psclusterref->energy();
3353 active[iPS] =
false;
3368 bool bPrimary = (order.find(
"primary") != string::npos);
3369 bool bSecondary = (order.find(
"secondary") != string::npos);
3370 bool bAll = (order.find(
"all") != string::npos);
3375 if (bPrimary && isToDisp)
return true;
3376 if (bSecondary && isFromDisp )
return true;
3377 if (bAll && ( isToDisp || isFromDisp ) )
return true;
3406 std::vector<unsigned int> pfCandidatesToBeRemoved;
3413 double met2 = metX*metX+metY*metY;
3415 double significance =
std::sqrt(met2/sumet);
3416 double significanceCor = significance;
3419 double metXCor = metX;
3420 double metYCor = metY;
3421 double sumetCor = sumet;
3422 double met2Cor = met2;
3424 double deltaPhiPt = 100.;
3426 unsigned iCor = 1E9;
3431 double metReduc = -1.;
3445 for(
unsigned j=0;
j<pfCandidatesToBeRemoved.size(); ++
j) {
3446 if (
i == pfCandidatesToBeRemoved[
j] ) skip =
true;
3449 if ( skip )
continue;
3452 deltaPhi = std::acos((metX*pfc.
px()+metY*pfc.
py())/(pfc.
pt()*
std::sqrt(met2)));
3453 deltaPhiPt = deltaPhi*pfc.
pt();
3457 double metXInt = metX - pfc.
px();
3458 double metYInt = metY - pfc.
py();
3459 double sumetInt = sumet - pfc.
pt();
3460 double met2Int = metXInt*metXInt+metYInt*metYInt;
3461 if ( met2Int < met2Cor ) {
3464 metReduc = (met2-met2Int)/met2Int;
3466 sumetCor = sumetInt;
3467 significanceCor =
std::sqrt(met2Cor/sumetCor);
3474 pfCandidatesToBeRemoved.push_back(iCor);
3488 std::cout <<
"Significance reduction = " << significance <<
" -> "
3489 << significanceCor <<
" = " << significanceCor - significance
3491 for(
unsigned j=0;
j<pfCandidatesToBeRemoved.size(); ++
j) {
3492 std::cout <<
"Removed : " << (*pfCandidates_)[pfCandidatesToBeRemoved[
j]] << std::endl;
3494 (*pfCandidates_)[pfCandidatesToBeRemoved[
j]].rescaleMomentum(1E-6);
3508 if ( !cleanedHits.size() )
return;
3514 std::vector<unsigned int> hitsToBeAdded;
3521 double met2 = metX*metX+metY*metY;
3522 double met2_Original = met2;
3526 double metXCor = metX;
3527 double metYCor = metY;
3528 double sumetCor = sumet;
3529 double met2Cor = met2;
3531 unsigned iCor = 1E9;
3536 double metReduc = -1.;
3538 for(
unsigned i=0;
i<cleanedHits.size(); ++
i) {
3547 for(
unsigned j=0;
j<hitsToBeAdded.size(); ++
j) {
3548 if (
i == hitsToBeAdded[
j] ) skip =
true;
3551 if ( skip )
continue;
3554 double metXInt = metX + px;
3555 double metYInt = metY + py;
3556 double sumetInt = sumet + pt;
3557 double met2Int = metXInt*metXInt+metYInt*metYInt;
3560 if ( met2Int < met2Cor ) {
3563 metReduc = (met2-met2Int)/met2Int;
3565 sumetCor = sumetInt;
3574 hitsToBeAdded.push_back(iCor);
3588 std::cout << hitsToBeAdded.size() <<
" hits were re-added " << std::endl;
3592 std::cout <<
"Added after cleaning check : " << std::endl;
3594 for(
unsigned j=0;
j<hitsToBeAdded.size(); ++
j) {
3613 bool printout =
false;
3618 double sumetPU = 0.;
3619 for (
unsigned short i=1 ;
i<primaryVertices.size();++
i ) {
3620 if ( !primaryVertices[
i].isValid() || primaryVertices[
i].isFake() )
continue;
3623 itr < primaryVertices[
i].tracks_end(); ++itr ) {
3624 sumetPU += (*itr)->pt();
3634 double metXCosmics = 0.;
3635 double metYCosmics = 0.;
3636 double sumetCosmics = 0.;
3638 std::map<double,unsigned int>
pfMuons;
3639 std::map<double,unsigned int> pfCosmics;
3640 typedef std::multimap<double, unsigned int>::iterator IE;
3656 pfMuons.insert(std::pair<double,unsigned int>(-pfc.
pt(),
i));
3657 if ( origin > 1.0 ) {
3658 pfCosmics.insert(std::pair<double,unsigned int>(-pfc.
pt(),
i));
3659 metXCosmics += pfc.
px();
3660 metYCosmics += pfc.
py();
3661 sumetCosmics += pfc.
pt();
3667 double met2 = metX*metX+metY*metY;
3668 double met2Cosmics = (metX-metXCosmics)*(metX-metXCosmics)+(metY-metYCosmics)*(metY-metYCosmics);
3671 if ( sumetCosmics > (sumet-sumetPU)/10. && met2Cosmics < met2 ) {
3673 std::cout <<
"MEX,MEY,MET Before (Cosmics)" << metX <<
" " << metY <<
" " <<
std::sqrt(met2) << std::endl;
3674 for ( IE imu = pfCosmics.begin(); imu != pfCosmics.end(); ++imu ) {
3675 const PFCandidate& pfc = (*pfCandidates_)[imu->second];
3679 std::cout <<
"Muon cleaned (cosmic). pt/d0 = " << pfc.
pt() <<
" "
3684 (*pfCandidates_)[imu->second].rescaleMomentum(1E-6);
3686 met2 = metX*metX+metY*metY;
3688 std::cout <<
"MEX,MEY,MET After (Cosmics)" << metX <<
" " << metY <<
" " <<
std::sqrt(met2) << std::endl;
3695 for ( IE imu = pfMuons.begin(); imu != pfMuons.end(); ++imu ) {
3696 const PFCandidate& pfc = (*pfCandidates_)[imu->second];
3699 if ( pfc.
pt() < 20. )
continue;
3701 double metXNO = metX - pfc.
px();
3702 double metYNO = metY - pfc.
py();
3703 double met2NO = metXNO*metXNO + metYNO*metYNO;
3704 double sumetNO = sumet - pfc.
pt();
3705 double factor =
std::max(2.,2000./sumetNO);
3710 bestMuTrack = muonRef->combinedMuon();
3714 if ( !bestMuTrack || !trackerMu ) {
3715 if ( sumetNO-sumetPU > 500. && met2NO < met2/4.) {
3718 std::cout <<
"Muon cleaned (NO-bad) " << sumetNO << std::endl;
3719 std::cout <<
"sumet NO " << sumetNO << std::endl;
3721 (*pfCandidates_)[imu->second].rescaleMomentum(1E-6);
3723 std::cout <<
"MEX,MEY,MET " << metX <<
" " << metY <<
" " <<
std::sqrt(met2) << std::endl;
3729 std::cout <<
"Muon cleaned (NO/TK) ! " << std::endl;
3730 std::cout <<
"MEX,MEY,MET Now (NO/TK)" << metX <<
" " << metY <<
" " <<
std::sqrt(met2) << std::endl;
3742 double metXTK = metXNO + trackerMu->px();
3743 double metYTK = metYNO + trackerMu->py();
3744 double met2TK = metXTK*metXTK + metYTK*metYTK;
3746 double metXGL = metXNO + bestMuTrack->px();
3747 double metYGL = metYNO + bestMuTrack->py();
3748 double met2GL = metXGL*metXGL + metYGL*metYGL;
3765 if ( ( sumetNO-sumetPU > 250. && met2TK < met2/4. && met2TK < met2GL ) ||
3766 ( met2TK < met2/2. && trackerMu->pt() < bestMuTrack->pt()/4. && met2TK < met2GL ) ) {
3769 std::sqrt(trackerMu->p()*trackerMu->p()+0.1057*0.1057));
3771 std::cout <<
"Muon cleaned (TK) ! " << met2TK/met2 <<
" " << trackerMu->pt() / bestMuTrack->pt() << std::endl;
3772 (*pfCandidates_)[imu->second].setP4(
p4);
3774 std::cout <<
"MEX,MEY,MET Before (TK)" << metX <<
" " << metY <<
" " <<
std::sqrt(met2) << std::endl;
3780 std::cout <<
"MEX,MEY,MET Now (TK)" << metX <<
" " << metY <<
" " <<
std::sqrt(met2) << std::endl;
3783 else if ( ( sumetNO-sumetPU > 250. && met2GL < met2/4. && met2GL < met2TK ) ||
3784 ( met2GL < met2/2. && bestMuTrack->pt() < trackerMu->pt()/4.&& met2GL < met2TK ) ) {
3787 std::sqrt(bestMuTrack->p()*bestMuTrack->p()+0.1057*0.1057));
3789 std::cout <<
"Muon cleaned (GL) ! " << met2GL/met2 <<
" " << bestMuTrack->pt()/trackerMu->pt() << std::endl;
3790 (*pfCandidates_)[imu->second].setP4(
p4);
3792 std::cout <<
"MEX,MEY,MET before (GL)" << metX <<
" " << metY <<
" " <<
std::sqrt(met2) << std::endl;
3798 std::cout <<
"MEX,MEY,MET Now (GL)" << metX <<
" " << metY <<
" " <<
std::sqrt(met2) << std::endl;
3803 fabs ( pfc.
eta() ) > 2.15 &&
3804 met2NO < met2/25. &&
3805 (met2GL < met2TK/2. || met2TK < met2GL/2.) &&
3806 standAloneMu->pt() < bestMuTrack->pt()/10. &&
3807 standAloneMu->pt() < trackerMu->pt()/10.;
3810 bool punchthrough1 =
3811 ( sumetNO-sumetPU > 250. && met2NO < met2/4. && (met2GL < met2TK/factor || met2TK < met2GL/factor) );
3814 bool punchthrough2 =
3819 if ( punchthrough1 || punchthrough2 || fake ) {
3823 if ( !eleInBlocks.size() ) {
3825 err<<
"A muon has no associated elements in block. Cannot proceed with postMuonCleaning()";
3828 PFBlockRef blockRefMuon = eleInBlocks[0].first;
3829 unsigned indexMuon = eleInBlocks[0].second;
3830 for (
unsigned iele = 1; iele < eleInBlocks.size(); ++iele ) {
3831 indexMuon = eleInBlocks[iele].second;
3837 bool hadron =
false;
3838 for (
unsigned i = imu->second+1; i < pfCandidates_->
size(); ++
i ) {
3841 if ( !ele.size() ) {
3843 err2<<
"A pfCandidate has no associated elements in block. Cannot proceed with postMuonCleaning()";
3848 unsigned indexHadron = ele[0].second;
3850 if ( blockRefHadron.
key() != blockRefMuon.
key() )
break;
3852 if ( indexHadron == indexMuon &&
3857 if ( hadron )
break;
3867 std::cout <<
"Hadron: " << (*pfCandidates_)[iHad] << std::endl;
3869 double rescaleFactor = (*pfCandidates_)[iHad].p()/(*pfCandidates_)[imu->second].p();
3870 metX -= (*pfCandidates_)[imu->second].px() + (*pfCandidates_)[iHad].px();
3871 metY -= (*pfCandidates_)[imu->second].py() + (*pfCandidates_)[iHad].py();
3872 (*pfCandidates_)[imu->second].rescaleMomentum(rescaleFactor);
3873 (*pfCandidates_)[iHad].rescaleMomentum(1E-6);
3876 std::cout <<
"MEX,MEY,MET Before " << metX <<
" " << metY <<
" " <<
std::sqrt(met2) << std::endl;
3877 metX += (*pfCandidates_)[imu->second].px();
3878 metY += (*pfCandidates_)[imu->second].py();
3879 met2 = metX*metX + metY*metY;
3881 std::cout <<
"Muon changed to charged hadron" << std::endl;
3882 std::cout <<
"MEX,MEY,MET Now (NO)" << metX <<
" " << metY <<
" " <<
std::sqrt(met2) << std::endl;
3884 }
else if ( punchthrough1 || fake ) {
3885 const PFCandidate& pfc = (*pfCandidates_)[imu->second];
3888 std::cout <<
"MEX,MEY,MET Before " << metX <<
" " << metY <<
" " <<
std::sqrt(met2) << std::endl;
3889 metX -= (*pfCandidates_)[imu->second].px();
3890 metY -= (*pfCandidates_)[imu->second].py();
3891 met2 = metX*metX + metY*metY;
3892 (*pfCandidates_)[imu->second].rescaleMomentum(1E-6);
3894 std::cout <<
"Muon cleaned (NO)" << std::endl;
3895 std::cout <<
"MEX,MEY,MET Now (NO)" << metX <<
" " << metY <<
" " <<
std::sqrt(met2) << std::endl;
3915 for (
unsigned imu = 0; imu < muonh->size(); ++imu ) {
3920 bestMuTrack = muonRef->combinedMuon();
3926 bool hadron =
false;
3940 if ( pfc.
muonRef()->track() == trackerMu || pfc.
muonRef()->combinedMuon() == bestMuTrack ) {
3942 std::cout <<
"This muon is already used ..." << std::endl;
3944 std::cout << muonRef->p() <<
" " << muonRef->pt() <<
" " << muonRef->eta() <<
" " << muonRef->phi() << std::endl;
3951 if ( pfc.
muonRef()->isStandAloneMuon() && muonRef->isStandAloneMuon() ) {
3952 double dEta = pfc.
muonRef()->standAloneMuon()->eta() - standAloneMu->eta();
3953 double dPhi = pfc.
muonRef()->standAloneMuon()->phi() - standAloneMu->phi();
3954 double dR =
sqrt(dEta*dEta + dPhi*dPhi);
3956 std::cout <<
"StandAlone to be added ? " << std::endl;
3957 std::cout <<
" eta = " << pfc.
muonRef()->standAloneMuon()->eta() <<
" " << standAloneMu->eta() << std::endl;
3958 std::cout <<
" phi = " << pfc.
muonRef()->standAloneMuon()->phi() <<
" " << standAloneMu->phi() << std::endl;
3959 std::cout <<
" pt = " << pfc.
muonRef()->standAloneMuon()->pt() <<
" " << standAloneMu->pt() << std::endl;
3960 std::cout <<
" Delta R = " << dR << std::endl;
3964 if ( printout )
std::cout <<
"Not removed !" << std::endl;
3972 if ( used )
continue;
3974 double ptGL = muonRef->isGlobalMuon() ? bestMuTrack->pt() : 0.;
3975 double pxGL = muonRef->isGlobalMuon() ? bestMuTrack->px() : 0.;
3976 double pyGL = muonRef->isGlobalMuon() ? bestMuTrack->py() : 0.;
3977 double pzGL = muonRef->isGlobalMuon() ? bestMuTrack->pz() : 0.;
3979 double ptTK = muonRef->isTrackerMuon() ? trackerMu->pt() : 0.;
3980 double pxTK = muonRef->isTrackerMuon() ? trackerMu->px() : 0.;
3981 double pyTK = muonRef->isTrackerMuon() ? trackerMu->py() : 0.;
3982 double pzTK = muonRef->isTrackerMuon() ? trackerMu->pz() : 0.;
3984 double ptST = muonRef->isStandAloneMuon() ? standAloneMu->pt() : 0.;
3985 double pxST = muonRef->isStandAloneMuon() ? standAloneMu->px() : 0.;
3986 double pyST = muonRef->isStandAloneMuon() ? standAloneMu->py() : 0.;
3987 double pzST = muonRef->isStandAloneMuon() ? standAloneMu->pz() : 0.;
3991 double metXTK = metX + pxTK;
3992 double metYTK = metY + pyTK;
3993 double met2TK = metXTK*metXTK + metYTK*metYTK;
3995 double metXGL = metX + pxGL;
3996 double metYGL = metY + pyGL;
3997 double met2GL = metXGL*metXGL + metYGL*metYGL;
3999 double metXST = metX + pxST;
4000 double metYST = metY + pyST;
4001 double met2ST = metXST*metXST + metYST*metYST;
4006 if ( ptTK > 20. && met2TK < met2/4. && met2TK < met2GL && met2TK < met2ST ) {
4007 double energy =
std::sqrt(pxTK*pxTK+pyTK*pyTK+pzTK*pzTK+0.1057*0.1057);
4008 int charge = trackerMu->charge()>0 ? 1 : -1;
4017 if ( !hadron && radius < 1.0 ) {
4022 pfCandidates_->back().setVertexSource( PFCandidate::kTrkMuonVertex );
4027 std::cout <<
"MEX,MEY,MET before " << metX <<
" " << metY <<
" " <<
std::sqrt(met2) << std::endl;
4028 std::cout <<
"Muon TK added " << std::endl;
4029 std::cout <<
"pT TK/GL/ST : " << ptTK <<
" " << ptGL <<
" " << ptST << std::endl;
4033 met2 = metX*metX + metY*metY;
4036 std::cout <<
"MEX,MEY,MET now " << metX <<
" " << metY <<
" " <<
std::sqrt(met2) << std::endl;
4044 }
else if ( ptGL > 20. && met2GL < met2/4. && met2GL < met2TK && met2GL < met2ST ) {
4046 double energy =
std::sqrt(pxGL*pxGL+pyGL*pyGL+pzGL*pzGL+0.1057*0.1057);
4047 int charge = bestMuTrack->charge()>0 ? 1 : -1;
4055 if ( radius < 1.0 ) {
4060 pfCandidates_->back().setVertexSource( PFCandidate::kComMuonVertex );
4066 std::cout <<
"MEX,MEY,MET before " << metX <<
" " << metY <<
" " <<
std::sqrt(met2) << std::endl;
4067 std::cout <<
"Muon GL added " << std::endl;
4068 std::cout <<
"pT TK/GL/ST : " << ptTK <<
" " << ptGL <<
" " << ptST << std::endl;
4073 met2 = metX*metX + metY*metY;
4077 std::cout <<
"MEX,MEY,MET now " << metX <<
" " << metY <<
" " <<
std::sqrt(met2) << std::endl;
4085 }
else if ( ptST > 20. && met2ST < met2/4. && met2ST < met2TK && met2ST < met2GL ) {
4087 double energy =
std::sqrt(pxST*pxST+pyST*pyST+pzST*pzST+0.1057*0.1057);
4088 int charge = standAloneMu->charge()>0 ? 1 : -1;
4096 if ( radius < 1.0 ) {
4101 pfCandidates_->back().setVertexSource( PFCandidate::kSAMuonVertex);
4106 std::cout <<
"MEX,MEY,MET before " << metX <<
" " << metY <<
" " <<
std::sqrt(met2) << std::endl;
4107 std::cout <<
"Muon ST added " << std::endl;
4108 std::cout <<
"pT TK/GL/ST : " << ptTK <<
" " << ptGL <<
" " << ptST << std::endl;
4113 met2 = metX*metX + metY*metY;
4117 std::cout <<
"MEX,MEY,MET now " << metX <<
" " << metY <<
" " <<
std::sqrt(met2) << std::endl;
4142 for(
unsigned ic=0;ic<
size;++ic) {
4151 (*pfCandidates_)[ic].setPFElectronExtraRef(theRef);
4163 (*pfCandidates_)[ic].set_mva_e_pi(it->mvaVariable(PFCandidateElectronExtra::MVA_MVA));
4165 (*pfCandidates_)[ic].setPFElectronExtraRef(theRef);
4166 (*pfCandidates_)[ic].setGsfTrackRef(it->gsfTrackRef());
4174 for(
unsigned ic=0;ic<
size;++ic) {
4182 (*pfElectronCandidates_)[ic].setPFElectronExtraRef(theRef);
4193 for(
unsigned ic=0;ic<
size;++ic) {
4198 for(
unsigned pcextra=0;pcextra<sizePhExtra;++pcextra) {
4201 (*pfCandidates_)[ic].setPFPhotonExtraRef(theRef);
PFLayer::Layer layer() const
cluster layer, see PFLayer.h in this directory
const double Z[kNumberCalorimeter]
double p() const
momentum vector magnitude
unsigned int nTrackIsoForEgammaSC_
edm::Ref< PFBlockCollection > PFBlockRef
persistent reference to PFCluster objects
Abstract base class for a PFBlock element (track, cluster...)
static bool isIsolatedMuon(const reco::PFBlockElement &elt)
const math::XYZPoint & position() const
cluster centroid position
bool isFromSecInt(const reco::PFBlockElement &eTrack, std::string order) const
virtual double p() const
magnitude of momentum vector
std::vector< double > muonHCAL_
Variables for muons and fakes.
void setPFMuonAndFakeParameters(std::vector< double > muonHCAL, std::vector< double > muonECAL, std::vector< double > muonHO, double nSigmaTRACK, double ptError, std::vector< double > factors45, bool usePFMuonMomAssign, bool useBestMuonTrack)
ParticleType
particle types
double rawEcalEnergy() const
return corrected Ecal energy
ROOT::Math::LorentzVector< ROOT::Math::PxPyPzE4D< double > > XYZTLorentzVectorD
Lorentz vector with cylindrical internal representation using pseudorapidity.
double sumEtEcalIsoForEgammaSC_endcap_
std::auto_ptr< reco::PFCandidateCollection > pfPhotonCandidates_
the unfiltered photon collection
Particle flow cluster, see clustering algorithm in PFClusterAlgo.
edm::Ref< PFCandidatePhotonExtraCollection > PFCandidatePhotonExtraRef
persistent reference to a PFCandidatePhotonExtra
double coneEcalIsoForEgammaSC_
static bool isMuon(const reco::PFBlockElement &elt)
Check if a block element is a muon.
const std::vector< reco::PFCandidate > & getAllElectronCandidates()
TrackQuality
track quality
std::auto_ptr< reco::PFCandidateCollection > pfFakeMuonCleanedCandidates_
the collection of fake cleaned muon candidates
unsigned reconstructCluster(const reco::PFCluster &cluster, double particleEnergy, bool useDirection=false, double particleX=0., double particleY=0., double particleZ=0.)
void reconstructParticles(const reco::PFBlockHandle &blockHandle)
double y() const
y coordinate
double coneTrackIsoForEgammaSC_
double nSigmaHCAL_
number of sigma to judge energy excess in HCAL
std::map< unsigned int, Link > LinkData
static bool isGlobalLooseMuon(const reco::PFBlockElement &elt)
virtual void processBlock(const reco::PFBlockRef &blockref, std::list< reco::PFBlockRef > &hcalBlockRefs, std::list< reco::PFBlockRef > &ecalBlockRefs)
math::Error< dimension >::type Error
covariance error matrix (3x3)
std::vector< Vertex > VertexCollection
collection of Vertex objects
const edm::OwnVector< reco::PFBlockElement > & elements() const
std::vector< PFRecHit > PFRecHitCollection
collection of PFRecHit objects
void checkCleaning(const reco::PFRecHitCollection &cleanedHF)
Check HF Cleaning.
edm::Ref< PFCandidateElectronExtraCollection > PFCandidateElectronExtraRef
persistent reference to a PFCandidateElectronExtra
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< float > > XYZPointF
point in space with cartesian internal representation
double px() const
x coordinate of momentum vector
void setDisplacedVerticesParameters(bool rejectTracks_Bad, bool rejectTracks_Step45, bool usePFNuclearInteractions, bool usePFConversions, bool usePFDecays, double dptRel_DispVtx)
static void printMuonProperties(const reco::MuonRef &muonRef)
std::ostream & operator<<(std::ostream &out, const ALILine &li)
PFCandidateCollection::const_iterator PFCandidateConstIterator
iterator
double sumEtEcalIsoForEgammaSC_barrel_
std::auto_ptr< reco::PFCandidateCollection > pfCleanedCandidates_
void setPFEleParameters(double mvaEleCut, std::string mvaWeightFileEleID, bool usePFElectrons, const boost::shared_ptr< PFSCEnergyCalibration > &thePFSCEnergyCalibration, const boost::shared_ptr< PFEnergyCalibration > &thePFEnergyCalibration, double sumEtEcalIsoForEgammaSC_barrel, double sumEtEcalIsoForEgammaSC_endcap, double coneEcalIsoForEgammaSC, double sumPtTrackIsoForEgammaSC_barrel, double sumPtTrackIsoForEgammaSC_endcap, unsigned int nTrackIsoForEgammaSC, double coneTrackIsoForEgammaSC, bool applyCrackCorrections=false, bool usePFSCEleCalib=true, bool useEGElectrons=false, bool useEGammaSupercluster=true)
void setEGElectronCollection(const reco::GsfElectronCollection &egelectrons)
static bool isGlobalTightMuon(const reco::PFBlockElement &elt)
std::vector< GsfElectron > GsfElectronCollection
collection of GsfElectron objects
bool rejectTracks_Step45_
const math::XYZPointF & positionAtECALEntrance() const
virtual double eta() const
momentum pseudorapidity
std::vector< ElementInBlock > ElementsInBlocks
double minSignificanceReduction_
void setPFPhotonParameters(bool usePFPhoton, std::string mvaWeightFileConvID, double mvaConvCut, bool useReg, std::string X0_Map, const boost::shared_ptr< PFEnergyCalibration > &thePFEnergyCalibration, double sumPtTrackIsoForPhoton, double sumPtTrackIsoSlopeForPhoton)
virtual double vx() const
x coordinate of vertex position
std::vector< double > factors45_
const ElementsInBlocks & elementsInBlocks() const
reco::TrackRef trackRef() const
PFLayer::Layer layer() const
rechit layer
bool useEGammaSupercluster_
U second(std::pair< T, U > const &p)
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
bool isNonnull() const
Checks for non-null.
reco::MuonRef muonRef() const
bool usePFNuclearInteractions_
virtual double energy() const
energy
bool isNull() const
Checks for null.
Particle flow rechit (rechit + geometry and topology information). See clustering algorithm in PFClus...
void setParameters(double nSigmaECAL, double nSigmaHCAL, const boost::shared_ptr< PFEnergyCalibration > &calibration, const boost::shared_ptr< PFEnergyCalibrationHF > &thepfEnergyCalibrationHF)
double dPhi(double phi1, double phi2)
const T & max(const T &a, const T &b)
void associatePSClusters(unsigned iEcal, reco::PFBlockElement::Type psElementType, const reco::PFBlock &block, const edm::OwnVector< reco::PFBlockElement > &elements, const reco::PFBlock::LinkData &linkData, std::vector< bool > &active, std::vector< double > &psEne)
Associate PS clusters to a given ECAL cluster, and return their energy.
std::string mvaWeightFileEleID_
Variables for PFElectrons.
bool check(const DataFrame &df, bool capcheck, bool dvercheck)
const std::vector< reco::PFCandidateElectronExtra > & getElectronExtra()
double ptError() const
error on Pt (set to 1000 TeV if charge==0 for safety)
void setPFPhotonRegWeights(const GBRForest *LCorrForestEB, const GBRForest *LCorrForestEE, const GBRForest *GCorrForestBarrel, const GBRForest *GCorrForestEndcapHr9, const GBRForest *GCorrForestEndcapLr9, const GBRForest *PFEcalResolution)
double z() const
y coordinate
reco::Vertex primaryVertex_
double nSigmaHCAL(double clusterEnergy, double clusterEta) const
std::vector< double > muonECAL_
void setPositionAtECALEntrance(float x, float y, float z)
set position at ECAL entrance
math::XYZPoint Point
point in the space
std::vector< LinkConnSpec >::const_iterator IT
const HitPattern & hitPattern() const
Access the hit pattern, indicating in which Tracker layers the track has hits.
void setPostHFCleaningParameters(bool postHFCleaning, double minHFCleaningPt, double minSignificance, double maxSignificance, double minSignificanceReduction, double maxDeltaPhiPt, double minDeltaMet)
std::vector< PFBlock > PFBlockCollection
collection of PFBlock objects
reco::PFBlockRef createBlockRef(const reco::PFBlockCollection &blocks, unsigned bi)
reco::MuonRef muonRef() const
reco::PFCandidatePhotonExtraCollection pfPhotonExtra_
the extra photon collection
double pz() const
z coordinate of momentum vector
void setEcalEnergy(float eeRaw, float eeCorr)
set corrected Ecal energy
const std::vector< reco::PFCandidate > & getElectronCandidates()
const math::XYZPoint & position() const
is seed ?
std::vector< reco::PFCandidate > PFCandidateCollection
collection of PFCandidates
double x() const
x coordinate
virtual bool trackType(TrackType trType) const
void setPFVertexParameters(bool useVertex, const reco::VertexCollection &primaryVertices)
std::list< reco::PFBlockRef >::iterator IBR
std::vector< double > muonHO_
virtual double px() const
x coordinate of momentum vector
XYZVectorD XYZVector
spatial vector with cartesian internal representation
std::auto_ptr< reco::PFCandidateCollection > pfCosmicsMuonCleanedCandidates_
the collection of cosmics cleaned muon candidates
void setGBRForest(const GBRForest *LCorrForest, const GBRForest *GCorrForest, const GBRForest *ResForest)
virtual double pt() const
transverse momentum
void associatedElements(unsigned i, const LinkData &linkData, std::multimap< double, unsigned > &sortedAssociates, reco::PFBlockElement::Type type=PFBlockElement::NONE, LinkTest test=LINKTEST_RECHIT) const
static bool isLooseMuon(const reco::PFBlockElement &elt)
XYZPointD XYZPoint
point in space with cartesian internal representation
boost::shared_ptr< PFEnergyCalibration > calibration_
key_type key() const
Accessor for product key.
reco::PFBlockHandle blockHandle_
input block handle (full framework case)
virtual double vy() const
y coordinate of vertex position
virtual bool trackType(TrackType trType) const
boost::shared_ptr< PFSCEnergyCalibration > thePFSCEnergyCalibration_
std::auto_ptr< reco::PFCandidateCollection > pfPunchThroughHadronCleanedCandidates_
the collection of punch-through cleaned neutral hadron candidates
reco::TrackRef trackRef() const
int numberOfValidTrackerHits() const
virtual ~PFAlgo()
destructor
void setHoEnergy(float eoRaw, float eoCorr)
set corrected Hcal energy
std::vector< std::vector< double > > tmp
bool isElectronValidCandidate(const reco::PFBlockRef &blockRef, std::vector< bool > &active, const reco::Vertex &primaryVertex)
Particle reconstructed by the particle flow algorithm.
double energy() const
rechit energy
std::auto_ptr< reco::PFCandidateCollection > pfCleanedTrackerAndGlobalMuonCandidates_
the collection of tracker/global cleaned muon candidates
boost::shared_ptr< PFEnergyCalibrationHF > thepfEnergyCalibrationHF_
std::auto_ptr< reco::PFCandidateCollection > pfCandidates_
std::vector< TrackBaseRef >::const_iterator trackRef_iterator
The iteratator for the vector<TrackRef>
int numberOfValidPixelHits() const
void postMuonCleaning(const edm::Handle< reco::MuonCollection > &muonh, const reco::VertexCollection &primaryVertices)
void setPhotonExtraRef(const edm::OrphanHandle< reco::PFCandidatePhotonExtraCollection > &pf_extrah)
bool applyCrackCorrectionsElectrons_
int charge() const
track electric charge
double sumPtTrackIsoForEgammaSC_endcap_
unsigned reconstructTrack(const reco::PFBlockElement &elt)
virtual ParticleType particleId() const
std::auto_ptr< reco::PFCandidateCollection > pfPunchThroughMuonCleanedCandidates_
the collection of punch-through cleaned muon candidates
std::auto_ptr< reco::PFCandidateCollection > pfElectronCandidates_
the unfiltered electron collection
double time() const
timing for cleaned hits
double neutralHadronEnergyResolution(double clusterEnergy, double clusterEta) const
todo: use PFClusterTools for this
std::auto_ptr< reco::PFCandidateCollection > pfAddedMuonCandidates_
the collection of added muon candidates
reco::PFCandidateElectronExtraCollection pfElectronExtra_
the unfiltered electron collection
bool isPhotonValidCandidate(const reco::PFBlockRef &blockRef, std::vector< bool > &active, std::auto_ptr< reco::PFCandidateCollection > &pfPhotonCandidates, std::vector< reco::PFCandidatePhotonExtra > &pfPhotonExtraCandidates, std::vector< reco::PFCandidate > &tempElectronCandidates)
tuple size
Write out results.
double sumPtTrackIsoForEgammaSC_barrel_
virtual double py() const
y coordinate of momentum vector
const std::auto_ptr< reco::PFCandidateCollection > & pfCandidates() const
void setHcalEnergy(float ehRaw, float ehCorr)
set corrected Hcal energy
double py() const
y coordinate of momentum vector
static bool isTrackerTightMuon(const reco::PFBlockElement &elt)
double rawHcalEnergy() const
return raw Hcal energy
void setElectronExtraRef(const edm::OrphanHandle< reco::PFCandidateElectronExtraCollection > &extrah)
void setEGElectronCollection(const reco::GsfElectronCollection &egelectrons)
PFDisplacedTrackerVertexRef displacedVertexRef(TrackType trType) const
double nSigmaECAL_
number of sigma to judge energy excess in ECAL