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) {
96 string mvaWeightFileEleID,
98 const boost::shared_ptr<PFSCEnergyCalibration>& thePFSCEnergyCalibration,
99 const boost::shared_ptr<PFEnergyCalibration>& thePFEnergyCalibration,
100 double sumEtEcalIsoForEgammaSC_barrel,
101 double sumEtEcalIsoForEgammaSC_endcap,
102 double coneEcalIsoForEgammaSC,
103 double sumPtTrackIsoForEgammaSC_barrel,
104 double sumPtTrackIsoForEgammaSC_endcap,
105 unsigned int nTrackIsoForEgammaSC,
106 double coneTrackIsoForEgammaSC,
107 bool applyCrackCorrections,
108 bool usePFSCEleCalib,
110 bool useEGammaSupercluster) {
135 string err =
"PFAlgo: cannot open weight file '";
136 err += mvaWeightFileEleID;
138 throw invalid_argument( err );
142 thePFEnergyCalibration,
162 const boost::shared_ptr<PFEnergyCalibration>& thePFEnergyCalibration,
163 double sumPtTrackIsoForPhoton,
164 double sumPtTrackIsoSlopeForPhoton)
177 e(0, 0) = 0.0015 * 0.0015;
178 e(1, 1) = 0.0015 * 0.0015;
185 FILE * filePhotonConvID = fopen(mvaWeightFileConvID.c_str(),
"r");
186 if (filePhotonConvID) {
187 fclose(filePhotonConvID);
190 string err =
"PFAlgo: cannot open weight file '";
191 err += mvaWeightFileConvID;
193 throw invalid_argument( err );
201 thePFEnergyCalibration,
202 sumPtTrackIsoForPhoton,
203 sumPtTrackIsoSlopeForPhoton
226 GCorrForestBarrel, GCorrForestEndcapHr9,
227 GCorrForestEndcapLr9, PFEcalResolution);
249 assert (
muonHCAL_.size() == 2 && muonECAL_.size() == 2 && muonHO_.size() == 2);
253 assert ( factors45_.size() == 2 );
266 double minHFCleaningPt,
267 double minSignificance,
268 double maxSignificance,
269 double minSignificanceReduction,
270 double maxDeltaPhiPt,
271 double minDeltaMet) {
283 bool rejectTracks_Step45,
284 bool usePFNuclearInteractions,
285 bool usePFConversions,
287 double dptRel_DispVtx){
309 bool primaryVertexFound =
false;
310 int nVtx=primaryVertices->size();
314 for (
unsigned short i=0 ;
i<primaryVertices->size();++
i)
316 if(primaryVertices->at(
i).isValid()&&(!primaryVertices->at(
i).isFake()))
319 primaryVertexFound =
true;
331 e(0, 0) = 0.0015 * 0.0015;
332 e(1, 1) = 0.0015 * 0.0015;
380 cout<<
"*********************************************************"<<endl;
381 cout<<
"***** Particle flow algorithm *****"<<endl;
382 cout<<
"*********************************************************"<<endl;
386 std::list< reco::PFBlockRef > hcalBlockRefs;
387 std::list< reco::PFBlockRef > ecalBlockRefs;
388 std::list< reco::PFBlockRef > hoBlockRefs;
389 std::list< reco::PFBlockRef > otherBlockRefs;
391 for(
unsigned i=0;
i<blocks.size(); ++
i ) {
399 bool singleEcalOrHcal =
false;
400 if( elements.
size() == 1 ){
402 ecalBlockRefs.push_back( blockref );
403 singleEcalOrHcal =
true;
406 hcalBlockRefs.push_back( blockref );
407 singleEcalOrHcal =
true;
411 hoBlockRefs.push_back( blockref );
412 singleEcalOrHcal =
true;
416 if(!singleEcalOrHcal) {
417 otherBlockRefs.push_back( blockref );
422 cout<<
"# Ecal blocks: "<<ecalBlockRefs.size()
423 <<
", # Hcal blocks: "<<hcalBlockRefs.size()
424 <<
", # HO blocks: "<<hoBlockRefs.size()
425 <<
", # Other blocks: "<<otherBlockRefs.size()<<endl;
433 for(
IBR io = otherBlockRefs.begin(); io!=otherBlockRefs.end(); ++io) {
438 std::list< reco::PFBlockRef >
empty;
442 for(
IBR ih = hcalBlockRefs.begin(); ih!=hcalBlockRefs.end(); ++ih) {
443 if (
debug_ )
std::cout <<
"HCAL block number " << hblcks++ << std::endl;
449 for(
IBR ie = ecalBlockRefs.begin(); ie!=ecalBlockRefs.end(); ++ie) {
450 if (
debug_ )
std::cout <<
"ECAL block number " << eblcks++ << std::endl;
467 std::list<reco::PFBlockRef>& hcalBlockRefs,
468 std::list<reco::PFBlockRef>& ecalBlockRefs ) {
471 assert(!blockref.
isNull() );
474 typedef std::multimap<double, unsigned>::iterator IE;
475 typedef std::multimap<double, std::pair<unsigned,math::XYZVector> >::iterator IS;
476 typedef std::multimap<double, std::pair<unsigned,bool> >::iterator
IT;
477 typedef std::multimap< unsigned, std::pair<double, unsigned> >::iterator II;
480 cout<<
"#########################################################"<<endl;
481 cout<<
"##### Process Block: #####"<<endl;
482 cout<<
"#########################################################"<<endl;
492 vector<bool> active( elements.
size(),
true );
497 std::vector<reco::PFCandidate> tempElectronCandidates;
498 tempElectronCandidates.clear();
503 for ( std::vector<reco::PFCandidate>::const_iterator ec=PFElectCandidates_.begin(); ec != PFElectCandidates_.end(); ++ec )tempElectronCandidates.push_back(*ec);
523 cout<<endl<<
"--------------- entering PFPhotonAlgo ----------------"<<endl;
524 vector<PFCandidatePhotonExtra> pfPhotonExtraCand;
529 tempElectronCandidates
539 unsigned int extracand =0;
547 pfPhotonExtraCand.clear();
554 for(
unsigned iEle=0; iEle<elements.
size(); iEle++) {
556 if(type==PFBlockElement::TRACK)
558 if(elements[iEle].trackRef()->algo() == 12)
563 if(elements[iEle].convRef().isNonnull())active[iEle]=
false;
567 for ( std::vector<reco::PFCandidate>::const_iterator ec=tempElectronCandidates.begin(); ec != tempElectronCandidates.end(); ++ec ){
570 tempElectronCandidates.clear();
574 cout<<endl<<
"--------------- loop 1 ------------------"<<endl;
601 vector<unsigned> hcalIs;
602 vector<unsigned> hoIs;
603 vector<unsigned> ecalIs;
604 vector<unsigned> trackIs;
605 vector<unsigned> ps1Is;
606 vector<unsigned> ps2Is;
608 vector<unsigned> hfEmIs;
609 vector<unsigned> hfHadIs;
612 for(
unsigned iEle=0; iEle<elements.
size(); iEle++) {
615 if(
debug_ && type != PFBlockElement::BREM )
cout<<endl<<elements[iEle];
618 case PFBlockElement::TRACK:
619 if ( active[iEle] ) {
621 if(
debug_)
cout<<
"TRACK, stored index, continue"<<endl;
625 if ( active[iEle] ) {
626 ecalIs.push_back( iEle );
627 if(
debug_)
cout<<
"ECAL, stored index, continue"<<endl;
631 if ( active[iEle] ) {
632 hcalIs.push_back( iEle );
633 if(
debug_)
cout<<
"HCAL, stored index, continue"<<endl;
636 case PFBlockElement::HO:
638 if ( active[iEle] ) {
639 hoIs.push_back( iEle );
640 if(
debug_)
cout<<
"HO, stored index, continue"<<endl;
644 case PFBlockElement::HFEM:
645 if ( active[iEle] ) {
646 hfEmIs.push_back( iEle );
647 if(
debug_)
cout<<
"HFEM, stored index, continue"<<endl;
650 case PFBlockElement::HFHAD:
651 if ( active[iEle] ) {
652 hfHadIs.push_back( iEle );
653 if(
debug_)
cout<<
"HFHAD, stored index, continue"<<endl;
661 unsigned iTrack = iEle;
667 if (active[iTrack] &&
isFromSecInt(elements[iEle],
"primary")){
668 bool isPrimaryTrack = elements[iEle].displacedVertexRef(PFBlockElement::T_TO_DISP)->displacedVertexRef()->isTherePrimaryTracks();
669 if (isPrimaryTrack) {
670 if (
debug_)
cout <<
"Primary Track reconstructed alone" << endl;
673 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEle );
674 active[iTrack] =
false;
680 if ( !active[iTrack] )
681 cout <<
"Already used by electrons, muons, conversions" << endl;
686 if ( ! active[iTrack] )
continue;
689 assert( !trackRef.
isNull() );
692 cout <<
"PFAlgo:processBlock "<<
" "<<trackIs.size()<<
" "<<ecalIs.size()<<
" "<<hcalIs.size()<<
" "<<hoIs.size()<<endl;
699 std::multimap<double, unsigned> ecalElems;
700 block.associatedElements( iTrack, linkData,
705 std::multimap<double, unsigned> hcalElems;
706 block.associatedElements( iTrack, linkData,
714 if ( hcalElems.empty() && !ecalElems.empty() ) {
717 unsigned index = ecalElems.begin()->second;
718 std::multimap<double, unsigned> sortedTracks;
719 block.associatedElements( index, linkData,
726 for(IE ie = sortedTracks.begin(); ie != sortedTracks.end(); ++ie ) {
727 unsigned jTrack = ie->second;
730 if ( !active[jTrack] )
continue;
734 if ( jTrack == iTrack )
continue;
739 std::multimap<double, unsigned> sortedECAL;
740 block.associatedElements( jTrack, linkData,
744 if ( sortedECAL.begin()->second !=
index )
continue;
749 std::multimap<double, unsigned> sortedHCAL;
750 block.associatedElements( jTrack, linkData,
754 if ( !sortedHCAL.size() )
continue;
759 block.setLink( iTrack,
760 sortedHCAL.begin()->second,
761 sortedECAL.begin()->first,
763 PFBlock::LINKTEST_RECHIT );
768 block.associatedElements( iTrack, linkData,
773 if (
debug_ && hcalElems.size() )
774 std::cout <<
"Track linked back to HCAL due to ECAL sharing with other tracks" << std::endl;
784 std::multimap<double,unsigned> gsfElems;
786 block.associatedElements( iTrack, linkData,
792 if(hcalElems.empty() &&
debug_) {
793 cout<<
"no hcal element connected to track "<<iTrack<<endl;
799 bool hcalFound =
false;
802 cout<<
"now looping on elements associated to the track"<<endl;
806 for(IE ie = ecalElems.begin(); ie != ecalElems.end(); ++ie ) {
808 unsigned index = ie->second;
812 double dist = ie->first;
813 cout<<
"\telement "<<elements[
index]<<
" linked with distance = "<< dist <<endl;
814 if ( ! active[index] )
cout <<
"This ECAL is already used - skip it" << endl;
819 if ( ! active[index] )
continue;
825 if( !hcalElems.empty() &&
debug_)
826 cout<<
"\t\tat least one hcal element connected to the track."
827 <<
" Sparing Ecal cluster for the hcal loop"<<endl;
835 if( hcalElems.empty() ) {
838 std::cout <<
"Now deals with tracks linked to no HCAL clusters" << std::endl;
845 std::cout << elements[iTrack] << std::endl;
851 if ( thisIsAMuon ) trackMomentum = 0.;
855 bool rejectFake =
false;
856 if ( !thisIsAMuon && elements[iTrack].trackRef()->ptError() >
ptError_ ) {
860 elements[iTrack].trackRef()->
eta());
863 if ( !ecalElems.empty() ) {
864 unsigned thisEcal = ecalElems.begin()->second;
866 deficit -= clusterRef->energy();
868 clusterRef->positionREP().Eta());
872 bool isPrimary =
isFromSecInt(elements[iTrack],
"primary");
876 active[iTrack] =
false;
878 std::cout << elements[iTrack] << std::endl
879 <<
"is probably a fake (1) --> lock the track"
884 if ( rejectFake )
continue;
889 std::vector<unsigned> tmpi;
890 std::vector<unsigned> kTrack;
893 double Dpt = trackRef->ptError();
896 trackMomentum > 30. && Dpt > 0.5 &&
897 ( trackRef->algo() == TrackBase::iter4 ||
898 trackRef->algo() == TrackBase::iter5 ||
899 trackRef->algo() == TrackBase::iter6 ) ) {
902 double dptRel = Dpt/trackRef->pt()*100;
903 bool isPrimaryOrSecondary =
isFromSecInt(elements[iTrack],
"all");
906 unsigned nHits = elements[iTrack].trackRef()->hitPattern().trackerLayersWithMeasurement();
907 unsigned int NLostHit = trackRef->hitPattern().trackerLayersWithoutMeasurement();
910 std::cout <<
"A track (algo = " << trackRef->algo() <<
") with momentum " << trackMomentum
911 <<
" / " << elements[iTrack].trackRef()->pt() <<
" +/- " << Dpt
912 <<
" / " << elements[iTrack].trackRef()->eta()
913 <<
" without any link to ECAL/HCAL and with " << nHits <<
" (" << NLostHit
914 <<
") hits (lost hits) has been cleaned" << std::endl;
915 active[iTrack] =
false;
922 kTrack.push_back(iTrack);
923 active[iTrack] =
false;
926 if ( ecalElems.empty() ) {
927 (*pfCandidates_)[tmpi[0]].setEcalEnergy( 0., 0. );
928 (*pfCandidates_)[tmpi[0]].setHcalEnergy( 0., 0. );
929 (*pfCandidates_)[tmpi[0]].setHoEnergy( 0., 0. );
930 (*pfCandidates_)[tmpi[0]].setPs1Energy( 0 );
931 (*pfCandidates_)[tmpi[0]].setPs2Energy( 0 );
932 (*pfCandidates_)[tmpi[0]].addElementInBlock( blockref, kTrack[0] );
937 unsigned thisEcal = ecalElems.begin()->second;
939 if (
debug_ )
std::cout <<
" is associated to " << elements[thisEcal] << std::endl;
944 (*pfCandidates_)[tmpi[0]].setEcalEnergy( clusterRef->energy(),
946 (*pfCandidates_)[tmpi[0]].setHcalEnergy( 0., 0. );
947 (*pfCandidates_)[tmpi[0]].setHoEnergy( 0., 0. );
948 (*pfCandidates_)[tmpi[0]].setPs1Energy( 0 );
949 (*pfCandidates_)[tmpi[0]].setPs2Energy( 0 );
950 (*pfCandidates_)[tmpi[0]].addElementInBlock( blockref, kTrack[0] );
953 double slopeEcal = 1.;
954 bool connectedToEcal =
false;
955 unsigned iEcal = 99999;
956 double calibEcal = 0.;
957 double calibHcal = 0.;
958 double totalEcal = thisIsAMuon ? -
muonECAL_[0] : 0.;
961 std::multimap<double, unsigned> sortedTracks;
962 block.associatedElements( thisEcal, linkData,
967 for(IE ie = sortedTracks.begin(); ie != sortedTracks.end(); ++ie ) {
968 unsigned jTrack = ie->second;
971 if ( !active[jTrack] )
continue;
974 if ( jTrack == iTrack )
continue;
979 std::multimap<double, unsigned> sortedECAL;
980 block.associatedElements( jTrack, linkData,
984 if ( sortedECAL.begin()->second != thisEcal )
continue;
991 bool rejectFake =
false;
993 if ( !thatIsAMuon && trackRef->ptError() >
ptError_) {
994 double deficit = trackMomentum + trackRef->p() - clusterRef->energy();
996 clusterRef->positionREP().Eta());
997 resol *= (trackMomentum+trackRef->p());
1000 kTrack.push_back(jTrack);
1001 active[jTrack] =
false;
1003 std::cout << elements[jTrack] << std::endl
1004 <<
"is probably a fake (2) --> lock the track"
1008 if ( rejectFake )
continue;
1014 if ( !thatIsAMuon ) {
1016 std::cout <<
"Track momentum increased from " << trackMomentum <<
" GeV ";
1017 trackMomentum += trackRef->p();
1019 std::cout <<
"to " << trackMomentum <<
" GeV." << std::endl;
1020 std::cout <<
"with " << elements[jTrack] << std::endl;
1024 totalEcal =
std::max(totalEcal, 0.);
1032 kTrack.push_back(jTrack);
1033 active[jTrack] =
false;
1035 if ( thatIsAMuon ) {
1036 (*pfCandidates_)[tmpi.back()].setEcalEnergy(clusterRef->energy(),
1038 (*pfCandidates_)[tmpi.back()].setHcalEnergy( 0., 0. );
1039 (*pfCandidates_)[tmpi.back()].setHoEnergy( 0., 0. );
1040 (*pfCandidates_)[tmpi.back()].setPs1Energy( 0 );
1041 (*pfCandidates_)[tmpi.back()].setPs2Energy( 0 );
1042 (*pfCandidates_)[tmpi.back()].addElementInBlock( blockref, kTrack.back() );
1047 if (
debug_ )
std::cout <<
"Loop over all associated ECAL clusters" << std::endl;
1049 for(IE ie = ecalElems.begin(); ie != ecalElems.end(); ++ie ) {
1051 unsigned index = ie->second;
1057 if (
debug_ && ! active[index] )
std::cout <<
"is not active - ignore " << std::endl;
1058 if ( ! active[index] )
continue;
1062 block.associatedElements( index, linkData,
1067 for (
unsigned ic=0; ic<kTrack.size();++ic) {
1068 if ( sortedTracks.begin()->second == kTrack[ic] ) {
1073 if (
debug_ && skip )
std::cout <<
"is closer to another track - ignore " << std::endl;
1074 if ( skip )
continue;
1079 assert( !clusterRef.
isNull() );
1082 double dist = ie->first;
1083 std::cout <<
"Ecal cluster with raw energy = " << clusterRef->energy()
1084 <<
" linked with distance = " << dist << std::endl;
1097 vector<double> ps1Ene(1,static_cast<double>(0.));
1099 vector<double> ps2Ene(1,static_cast<double>(0.));
1103 bool crackCorrection =
false;
1104 double ecalEnergy =
calibration_->energyEm(*clusterRef,ps1Ene,ps2Ene,crackCorrection);
1106 std::cout <<
"Corrected ECAL(+PS) energy = " << ecalEnergy << std::endl;
1110 totalEcal += ecalEnergy;
1111 double previousCalibEcal = calibEcal;
1112 double previousSlopeEcal = slopeEcal;
1113 calibEcal =
std::max(totalEcal,0.);
1115 calibration_->energyEmHad(trackMomentum,calibEcal,calibHcal,
1116 clusterRef->positionREP().Eta(),
1117 clusterRef->positionREP().Phi());
1118 if ( totalEcal > 0.) slopeEcal = calibEcal/totalEcal;
1121 std::cout <<
"The total calibrated energy so far amounts to = " << calibEcal << std::endl;
1125 if ( connectedToEcal && calibEcal - trackMomentum >= 0. ) {
1128 calibEcal = previousCalibEcal;
1129 slopeEcal = previousSlopeEcal;
1130 totalEcal = calibEcal/slopeEcal;
1134 active[
index] =
false;
1137 std::multimap<double, unsigned> assTracks;
1138 block.associatedElements( index, linkData,
1145 (*pfCandidates_)[tmpe].setEcalEnergy( clusterRef->energy(), ecalEnergy );
1146 (*pfCandidates_)[tmpe].setHcalEnergy( 0., 0. );
1147 (*pfCandidates_)[tmpe].setHoEnergy( 0., 0. );
1148 (*pfCandidates_)[tmpe].setPs1Energy( ps1Ene[0] );
1149 (*pfCandidates_)[tmpe].setPs2Energy( ps2Ene[0] );
1150 (*pfCandidates_)[tmpe].addElementInBlock( blockref, index );
1152 if(assTracks.size()) {
1153 (*pfCandidates_)[tmpe].addElementInBlock( blockref, assTracks.begin()->second );
1164 connectedToEcal =
true;
1166 active[
index] =
false;
1167 for (
unsigned ic=0; ic<tmpi.size();++ic)
1168 (*
pfCandidates_)[tmpi[ic]].addElementInBlock( blockref, iEcal );
1173 bool bNeutralProduced =
false;
1176 if( connectedToEcal ) {
1218 neutralEnergy /= slopeEcal;
1220 (*pfCandidates_)[tmpj].setEcalEnergy( pivotalRef->energy(),
neutralEnergy );
1221 (*pfCandidates_)[tmpj].setHcalEnergy( 0., 0. );
1222 (*pfCandidates_)[tmpj].setHoEnergy( 0., 0. );
1223 (*pfCandidates_)[tmpj].setPs1Energy( 0. );
1224 (*pfCandidates_)[tmpj].setPs2Energy( 0. );
1225 (*pfCandidates_)[tmpj].addElementInBlock(blockref, iEcal);
1226 bNeutralProduced =
true;
1227 for (
unsigned ic=0; ic<kTrack.size();++ic)
1228 (*
pfCandidates_)[tmpj].addElementInBlock( blockref, kTrack[ic] );
1232 for (
unsigned ic=0; ic<tmpi.size();++ic) {
1237 double fraction = (*pfCandidates_)[tmpi[ic]].trackRef()->p()/
trackMomentum;
1238 double ecalCal = bNeutralProduced ?
1239 (calibEcal-neutralEnergy*slopeEcal)*fraction : calibEcal*fraction;
1240 double ecalRaw = totalEcal*fraction;
1242 if (
debug_)
cout <<
"The fraction after photon supression is " << fraction <<
" calibrated ecal = " << ecalCal << endl;
1244 (*pfCandidates_)[tmpi[ic]].setEcalEnergy( ecalRaw, ecalCal );
1245 (*pfCandidates_)[tmpi[ic]].setHcalEnergy( 0., 0. );
1246 (*pfCandidates_)[tmpi[ic]].setHoEnergy( 0., 0. );
1247 (*pfCandidates_)[tmpi[ic]].setPs1Energy( 0 );
1248 (*pfCandidates_)[tmpi[ic]].setPs2Energy( 0 );
1249 (*pfCandidates_)[tmpi[ic]].addElementInBlock( blockref, kTrack[ic] );
1255 for (
unsigned ic=0; ic<tmpi.size();++ic) {
1256 const PFCandidate& pfc = (*pfCandidates_)[tmpi[ic]];
1258 if ( eleInBlocks.size() == 0 ) {
1259 if (
debug_ )
std::cout <<
"Single track / Fill element in block! " << std::endl;
1260 (*pfCandidates_)[tmpi[ic]].addElementInBlock( blockref, kTrack[ic] );
1269 for(IE ie = hcalElems.begin(); ie != hcalElems.end(); ++ie ) {
1271 unsigned index = ie->second;
1277 cout<<
"\telement "<<elements[
index]<<
" linked with distance "<< dist <<endl;
1286 cout<<
"\t\tclosest hcal cluster, doing nothing"<<endl;
1296 cout<<
"\t\tsecondary hcal cluster. unlinking"<<endl;
1297 block.setLink( iTrack, index, -1., linkData,
1298 PFBlock::LINKTEST_RECHIT );
1306 if( !(hfEmIs.empty() && hfHadIs.empty() ) ) {
1309 assert( hfEmIs.size() + hfHadIs.size() == elements.
size() );
1311 if( elements.
size() == 1 ) {
1314 double energyHF = 0.;
1315 double uncalibratedenergyHF = 0.;
1317 switch( clusterRef->layer() ) {
1320 energyHF = clusterRef->energy();
1321 uncalibratedenergyHF = energyHF;
1324 clusterRef->positionREP().Eta(),
1325 clusterRef->positionREP().Phi());
1328 (*pfCandidates_)[tmpi].setEcalEnergy( uncalibratedenergyHF, energyHF );
1329 (*pfCandidates_)[tmpi].setHcalEnergy( 0., 0.);
1330 (*pfCandidates_)[tmpi].setHoEnergy( 0., 0.);
1331 (*pfCandidates_)[tmpi].setPs1Energy( 0. );
1332 (*pfCandidates_)[tmpi].setPs2Energy( 0. );
1333 (*pfCandidates_)[tmpi].addElementInBlock( blockref, hfEmIs[0] );
1338 energyHF = clusterRef->energy();
1339 uncalibratedenergyHF = energyHF;
1342 clusterRef->positionREP().Eta(),
1343 clusterRef->positionREP().Phi());
1346 (*pfCandidates_)[tmpi].setHcalEnergy( uncalibratedenergyHF, energyHF );
1347 (*pfCandidates_)[tmpi].setEcalEnergy( 0., 0.);
1348 (*pfCandidates_)[tmpi].setHoEnergy( 0., 0.);
1349 (*pfCandidates_)[tmpi].setPs1Energy( 0. );
1350 (*pfCandidates_)[tmpi].setPs2Energy( 0. );
1351 (*pfCandidates_)[tmpi].addElementInBlock( blockref, hfHadIs[0] );
1358 else if( elements.
size() == 2 ) {
1368 cem = c0; chad =
c1;
1373 double energyHfEm = cem->energy();
1374 double energyHfHad = chad->energy();
1375 double uncalibratedenergyHFEm = energyHfEm;
1376 double uncalibratedenergyHFHad = energyHfHad;
1381 c0->positionREP().Eta(),
1382 c0->positionREP().Phi());
1384 uncalibratedenergyHFHad,
1385 c1->positionREP().Eta(),
1386 c1->positionREP().Phi());
1389 (*pfCandidates_)[tmpi].setEcalEnergy( uncalibratedenergyHFEm, energyHfEm );
1390 (*pfCandidates_)[tmpi].setHcalEnergy( uncalibratedenergyHFHad, energyHfHad);
1391 (*pfCandidates_)[tmpi].setHoEnergy( 0., 0.);
1392 (*pfCandidates_)[tmpi].setPs1Energy( 0. );
1393 (*pfCandidates_)[tmpi].setPs2Energy( 0. );
1394 (*pfCandidates_)[tmpi].addElementInBlock( blockref, hfEmIs[0] );
1395 (*pfCandidates_)[tmpi].addElementInBlock( blockref, hfHadIs[0] );
1400 cerr<<
"Warning: 2 elements, but not 1 HFEM and 1 HFHAD"<<endl;
1409 cerr<<
"Warning: HF, but n elem different from 1 or 2"<<endl;
1420 cout<<endl<<
"--------------- loop hcal ---------------------"<<endl;
1429 for(
unsigned i=0;
i<hcalIs.size();
i++) {
1431 unsigned iHcal= hcalIs[
i];
1436 if(
debug_)
cout<<endl<<elements[iHcal]<<endl;
1442 std::multimap<double, unsigned> sortedTracks;
1443 block.associatedElements( iHcal, linkData,
1448 std::multimap< unsigned, std::pair<double, unsigned> > associatedEcals;
1450 std::map< unsigned, std::pair<double, double> > associatedPSs;
1452 std::multimap<double, std::pair<unsigned,bool> > associatedTracks;
1455 std::multimap<double,std::pair<unsigned,math::XYZVector> > ecalSatellites;
1456 std::pair<unsigned,math::XYZVector> fakeSatellite = make_pair(iHcal,
math::XYZVector(0.,0.,0.));
1457 ecalSatellites.insert( make_pair(-1., fakeSatellite) );
1459 std::multimap< unsigned, std::pair<double, unsigned> > associatedHOs;
1461 PFClusterRef hclusterref = elements[iHcal].clusterRef();
1462 assert(!hclusterref.
isNull() );
1472 if( sortedTracks.empty() ) {
1474 cout<<
"\tno associated tracks, keep for later"<<endl;
1479 active[iHcal] =
false;
1487 if(
debug_)
cout<<
"\t"<<sortedTracks.size()<<
" associated tracks:"<<endl;
1489 double totalChargedMomentum = 0;
1490 double sumpError2 = 0.;
1491 double totalHO = 0.;
1492 double totalEcal = 0.;
1493 double totalHcal = hclusterref->energy();
1494 vector<double> hcalP;
1495 vector<double> hcalDP;
1496 vector<unsigned> tkIs;
1497 double maxDPovP = -9999.;
1500 vector< unsigned > chargedHadronsIndices;
1501 vector< unsigned > chargedHadronsInBlock;
1502 double mergedNeutralHadronEnergy = 0;
1503 double mergedPhotonEnergy = 0;
1504 double muonHCALEnergy = 0.;
1505 double muonECALEnergy = 0.;
1506 double muonHCALError = 0.;
1507 double muonECALError = 0.;
1508 unsigned nMuons = 0;
1513 hclusterref->position().Y(),
1514 hclusterref->position().Z());
1515 hadronDirection = hadronDirection.Unit();
1519 for(IE ie = sortedTracks.begin(); ie != sortedTracks.end(); ++ie ) {
1521 unsigned iTrack = ie->second;
1524 if ( !active[iTrack] )
continue;
1530 assert( !trackRef.
isNull() );
1535 math::XYZVector chargedDirection(chargedPosition.X(),chargedPosition.Y(),chargedPosition.Z());
1536 chargedDirection = chargedDirection.Unit();
1539 std::multimap<double, unsigned> sortedEcals;
1540 block.associatedElements( iTrack, linkData,
1545 if(
debug_)
cout<<
"\t\t\tnumber of Ecal elements linked to this track: "
1546 <<sortedEcals.size()<<endl;
1549 std::multimap<double, unsigned> sortedHOs;
1551 block.associatedElements( iTrack, linkData,
1558 cout<<
"PFAlgo : number of HO elements linked to this track: "
1559 <<sortedHOs.size()<<endl;
1567 bool thisIsALooseMuon =
false;
1575 if ( thisIsAMuon ) {
1577 std::cout <<
"\t\tThis track is identified as a muon - remove it from the stack" << std::endl;
1578 std::cout <<
"\t\t" << elements[iTrack] << std::endl;
1586 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iTrack );
1587 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHcal );
1593 bool letMuonEatCaloEnergy =
false;
1595 if(thisIsAnIsolatedMuon){
1597 double totalCaloEnergy = totalHcal / 1.30;
1599 if( !sortedEcals.empty() ) {
1600 iEcal = sortedEcals.begin()->second;
1601 PFClusterRef eclusterref = elements[iEcal].clusterRef();
1602 totalCaloEnergy += eclusterref->energy();
1608 if( !sortedHOs.empty() ) {
1609 iHO = sortedHOs.begin()->second;
1611 totalCaloEnergy += eclusterref->energy() / 1.30;
1617 if( (
pfCandidates_->back()).
p() > totalCaloEnergy ) letMuonEatCaloEnergy =
true;
1620 if(letMuonEatCaloEnergy) muonHcal = totalHcal;
1621 double muonEcal =0.;
1623 if( !sortedEcals.empty() ) {
1624 iEcal = sortedEcals.begin()->second;
1625 PFClusterRef eclusterref = elements[iEcal].clusterRef();
1626 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal);
1628 if(letMuonEatCaloEnergy) muonEcal = eclusterref->energy();
1630 if ( eclusterref->energy() - muonEcal < 0.2 ) active[iEcal] =
false;
1631 (*pfCandidates_)[tmpi].setEcalEnergy(eclusterref->energy(), muonEcal);
1636 if( !sortedHOs.empty() ) {
1637 iHO = sortedHOs.begin()->second;
1638 PFClusterRef hoclusterref = elements[iHO].clusterRef();
1639 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHO);
1641 if(letMuonEatCaloEnergy) muonHO = hoclusterref->energy();
1643 if ( hoclusterref->energy() - muonHO < 0.2 ) active[iHO] =
false;
1644 (*pfCandidates_)[tmpi].setHcalEnergy(totalHcal, muonHcal);
1645 (*pfCandidates_)[tmpi].setHoEnergy(hoclusterref->energy(), muonHO);
1648 (*pfCandidates_)[tmpi].setHcalEnergy(totalHcal, muonHcal);
1651 if(letMuonEatCaloEnergy){
1652 muonHCALEnergy += totalHcal;
1653 if (
useHO_) muonHCALEnergy +=muonHO;
1654 muonHCALError += 0.;
1655 muonECALEnergy += muonEcal;
1656 muonECALError += 0.;
1657 photonAtECAL -= muonEcal*chargedDirection;
1658 hadronAtECAL -= totalHcal*chargedDirection;
1659 if ( !sortedEcals.empty() ) active[iEcal] =
false;
1660 active[iHcal] =
false;
1661 if (
useHO_ && !sortedHOs.empty() ) active[iHO] =
false;
1667 if ( muonHO > 0. ) {
1674 photonAtECAL -= muonECAL_[0]*chargedDirection;
1675 hadronAtECAL -= muonHCAL_[0]*chargedDirection;
1679 active[iTrack] =
false;
1686 if(
debug_)
cout<<
"\t\t"<<elements[iTrack]<<endl;
1694 if ( thisIsALooseMuon && !thisIsAMuon ) nMuons += 1;
1699 double Dpt = trackRef->ptError();
1700 double blowError = 1.;
1701 switch (trackRef->algo()) {
1702 case TrackBase::ctf:
1703 case TrackBase::iter0:
1704 case TrackBase::iter1:
1705 case TrackBase::iter2:
1706 case TrackBase::iter3:
1707 case TrackBase::iter4:
1710 case TrackBase::iter5:
1713 case TrackBase::iter6:
1721 bool isPrimaryOrSecondary =
isFromSecInt(elements[iTrack],
"all");
1723 if ( isPrimaryOrSecondary ) blowError = 1.;
1725 std::pair<unsigned,bool> tkmuon = make_pair(iTrack,thisIsALooseMuon);
1726 associatedTracks.insert( make_pair(-Dpt*blowError, tkmuon) );
1729 double Dp = trackRef->qoverpError()*trackMomentum*
trackMomentum;
1730 sumpError2 += Dp*Dp;
1732 bool connectedToEcal =
false;
1733 if( !sortedEcals.empty() )
1737 for ( IE iec=sortedEcals.begin();
1738 iec!=sortedEcals.end(); ++iec ) {
1740 unsigned iEcal = iec->second;
1741 double dist = iec->first;
1744 if( !active[iEcal] ) {
1752 PFClusterRef eclusterref = elements[iEcal].clusterRef();
1753 assert(!eclusterref.
isNull() );
1756 std::multimap<double, unsigned> sortedTracksEcal;
1757 block.associatedElements( iEcal, linkData,
1761 unsigned jTrack = sortedTracksEcal.
begin()->second;
1762 if ( jTrack != iTrack )
continue;
1766 double distEcal = block.dist(jTrack,iEcal,linkData,
1774 vector<double> ps1Ene(1,static_cast<double>(0.));
1776 block, elements, linkData, active,
1778 vector<double> ps2Ene(1,static_cast<double>(0.));
1780 block, elements, linkData, active,
1782 std::pair<double,double> psEnes = make_pair(ps1Ene[0],
1784 associatedPSs.insert(make_pair(iEcal,psEnes));
1787 bool crackCorrection =
false;
1788 float ecalEnergyCalibrated =
calibration_->energyEm(*eclusterref,ps1Ene,ps2Ene,crackCorrection);
1790 eclusterref->position().Y(),
1791 eclusterref->position().Z());
1792 photonDirection = photonDirection.Unit();
1794 if ( !connectedToEcal ) {
1797 <<elements[iEcal]<<endl;
1799 connectedToEcal =
true;
1803 std::pair<unsigned,math::XYZVector> satellite =
1804 make_pair(iEcal,ecalEnergyCalibrated*photonDirection);
1805 ecalSatellites.insert( make_pair(-1., satellite) );
1809 std::pair<unsigned,math::XYZVector> satellite =
1810 make_pair(iEcal,ecalEnergyCalibrated*photonDirection);
1811 ecalSatellites.insert( make_pair(dist, satellite) );
1815 std::pair<double, unsigned> associatedEcal
1816 = make_pair( distEcal, iEcal );
1817 associatedEcals.insert( make_pair(iTrack, associatedEcal) );
1822 if(
useHO_ && !sortedHOs.empty() )
1826 for ( IE ieho=sortedHOs.begin(); ieho!=sortedHOs.end(); ++ieho ) {
1828 unsigned iHO = ieho->second;
1829 double distHO = ieho->first;
1832 if( !active[iHO] ) {
1839 assert( type == PFBlockElement::HO );
1840 PFClusterRef hoclusterref = elements[iHO].clusterRef();
1841 assert(!hoclusterref.
isNull() );
1844 std::multimap<double, unsigned> sortedTracksHO;
1845 block.associatedElements( iHO, linkData,
1849 unsigned jTrack = sortedTracksHO.
begin()->second;
1850 if ( jTrack != iTrack )
continue;
1858 totalHO += hoclusterref->energy();
1859 active[iHO] =
false;
1861 std::pair<double, unsigned> associatedHO
1862 = make_pair( distHO, iHO );
1863 associatedHOs.insert( make_pair(iTrack, associatedHO) );
1872 totalHcal += totalHO;
1876 double caloEnergy = 0.;
1877 double slopeEcal = 1.0;
1878 double calibEcal = 0.;
1879 double calibHcal = 0.;
1880 hadronDirection = hadronAtECAL.Unit();
1884 Caloresolution *= totalChargedMomentum;
1886 Caloresolution =
std::sqrt(Caloresolution*Caloresolution + muonHCALError + muonECALError);
1887 totalEcal -=
std::min(totalEcal,muonECALEnergy);
1888 totalHcal -=
std::min(totalHcal,muonHCALEnergy);
1896 for ( IS is = ecalSatellites.begin(); is != ecalSatellites.end(); ++is ) {
1899 double previousCalibEcal = calibEcal;
1900 double previousCalibHcal = calibHcal;
1901 double previousCaloEnergy = caloEnergy;
1902 double previousSlopeEcal = slopeEcal;
1905 totalEcal +=
sqrt(is->second.second.Mag2());
1906 photonAtECAL += is->second.second;
1907 calibEcal =
std::max(0.,totalEcal);
1908 calibHcal =
std::max(0.,totalHcal);
1909 hadronAtECAL = calibHcal * hadronDirection;
1911 calibration_->energyEmHad(totalChargedMomentum,calibEcal,calibHcal,
1912 hclusterref->positionREP().Eta(),
1913 hclusterref->positionREP().Phi());
1914 caloEnergy = calibEcal+calibHcal;
1915 if ( totalEcal > 0.) slopeEcal = calibEcal/totalEcal;
1917 hadronAtECAL = calibHcal * hadronDirection;
1921 if ( is->first < 0. || caloEnergy - totalChargedMomentum <= 0. ) {
1922 if(
debug_)
cout<<
"\t\t\tactive, adding "<<is->second.second
1923 <<
" to ECAL energy, and locking"<<endl;
1924 active[is->second.first] =
false;
1930 totalEcal -=
sqrt(is->second.second.Mag2());
1931 photonAtECAL -= is->second.second;
1932 calibEcal = previousCalibEcal;
1933 calibHcal = previousCalibHcal;
1934 hadronAtECAL = previousHadronAtECAL;
1935 slopeEcal = previousSlopeEcal;
1936 caloEnergy = previousCaloEnergy;
1943 assert(caloEnergy>=0);
1956 double TotalError =
sqrt(sumpError2 + Caloresolution*Caloresolution);
1960 if ( totalChargedMomentum - caloEnergy >
nSigmaTRACK_*Caloresolution ) {
1975 for ( IT it = associatedTracks.begin(); it != associatedTracks.end(); ++it ) {
1976 unsigned iTrack = it->second.first;
1978 if ( !active[iTrack] )
continue;
1980 if ( !it->second.second )
continue;
1982 double trackMomentum = elements[it->second.first].trackRef()->p();
1985 std::multimap<double, unsigned> sortedEcals;
1986 block.associatedElements( iTrack, linkData,
1990 std::multimap<double, unsigned> sortedHOs;
1991 block.associatedElements( iTrack, linkData,
1999 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iTrack );
2000 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHcal );
2003 (*pfCandidates_)[tmpi].setHcalEnergy(totalHcal,muonHcal);
2004 if( !sortedEcals.empty() ) {
2005 unsigned iEcal = sortedEcals.begin()->second;
2006 PFClusterRef eclusterref = elements[iEcal].clusterRef();
2007 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal);
2009 (*pfCandidates_)[tmpi].setEcalEnergy(eclusterref->energy(),muonEcal);
2011 if(
useHO_ && !sortedHOs.empty() ) {
2012 unsigned iHO = sortedHOs.begin()->second;
2013 PFClusterRef hoclusterref = elements[iHO].clusterRef();
2014 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHO);
2016 (*pfCandidates_)[tmpi].setHcalEnergy(totalHcal-totalHO,muonHcal);
2017 (*pfCandidates_)[tmpi].setHoEnergy(hoclusterref->energy(),muonHO);
2022 math::XYZVector chargedDirection(chargedPosition.X(), chargedPosition.Y(), chargedPosition.Z());
2023 chargedDirection = chargedDirection.Unit();
2026 if ( totalEcal > 0. )
2028 if ( totalHcal > 0. )
2033 if ( totalHcal >
muonHCAL_[0] ) hadronAtECAL -=
muonHCAL_[0]*calibHcal/totalHcal * chargedDirection;
2034 caloEnergy = calibEcal+calibHcal;
2037 if ( muonHO > 0. ) {
2040 if ( totalHcal > 0. ) {
2041 calibHcal -=
std::min(calibHcal,muonHO_[0]*calibHcal/totalHcal);
2042 totalHcal -=
std::min(totalHcal,muonHO_[0]);
2047 active[iTrack] =
false;
2054 Caloresolution *= totalChargedMomentum;
2055 Caloresolution =
std::sqrt(Caloresolution*Caloresolution + muonHCALError + muonECALError);
2073 unsigned corrTrack = 10000000;
2074 double corrFact = 1.;
2077 totalChargedMomentum - caloEnergy >
nSigmaTRACK_*Caloresolution) {
2079 for ( IT it = associatedTracks.begin(); it != associatedTracks.end(); ++it ) {
2080 unsigned iTrack = it->second.first;
2082 if ( !active[iTrack] )
continue;
2083 const reco::TrackRef& trackref = elements[it->second.first].trackRef();
2085 double dptRel = fabs(it->first)/trackref->pt()*100;
2086 bool isSecondary =
isFromSecInt(elements[iTrack],
"secondary");
2087 bool isPrimary =
isFromSecInt(elements[iTrack],
"primary");
2091 if ( fabs(it->first) <
ptError_ )
break;
2093 double wouldBeTotalChargedMomentum =
2094 totalChargedMomentum - trackref->p();
2098 if ( wouldBeTotalChargedMomentum > caloEnergy ) {
2100 if (
debug_ && isSecondary) {
2101 cout <<
"In bad track rejection step dptRel = " << dptRel <<
" dptRel_DispVtx_ = " <<
dptRel_DispVtx_ << endl;
2102 cout <<
"The calo energy would be still smaller even without this track but it is attached to a NI"<< endl;
2107 active[iTrack] =
false;
2108 totalChargedMomentum = wouldBeTotalChargedMomentum;
2110 std::cout <<
"\tElement " << elements[iTrack]
2111 <<
" rejected (Dpt = " << -it->first
2112 <<
" GeV/c, algo = " << trackref->algo() <<
")" << std::endl;
2115 if(isPrimary)
break;
2117 corrFact = (caloEnergy - wouldBeTotalChargedMomentum)/elements[it->second.first].trackRef()->p();
2118 if ( trackref->p()*corrFact < 0.05 ) {
2120 active[iTrack] =
false;
2122 totalChargedMomentum -= trackref->p()*(1.-corrFact);
2124 std::cout <<
"\tElement " << elements[iTrack]
2125 <<
" (Dpt = " << -it->first
2126 <<
" GeV/c, algo = " << trackref->algo()
2127 <<
") rescaled by " << corrFact
2128 <<
" Now the total charged momentum is " << totalChargedMomentum << endl;
2136 Caloresolution *= totalChargedMomentum;
2137 Caloresolution =
std::sqrt(Caloresolution*Caloresolution + muonHCALError + muonECALError);
2143 sortedTracks.size() > 1 &&
2144 totalChargedMomentum - caloEnergy >
nSigmaTRACK_*Caloresolution ) {
2145 for ( IT it = associatedTracks.begin(); it != associatedTracks.end(); ++it ) {
2146 unsigned iTrack = it->second.first;
2148 if ( !active[iTrack] )
continue;
2150 double dptRel = fabs(it->first)/trackref->pt()*100;
2151 bool isPrimaryOrSecondary =
isFromSecInt(elements[iTrack],
"all");
2158 switch (trackref->algo()) {
2159 case TrackBase::ctf:
2160 case TrackBase::iter0:
2161 case TrackBase::iter1:
2162 case TrackBase::iter2:
2163 case TrackBase::iter3:
2164 case TrackBase::iter4:
2166 case TrackBase::iter5:
2167 case TrackBase::iter6:
2168 active[iTrack] =
false;
2169 totalChargedMomentum -= trackref->p();
2172 std::cout <<
"\tElement " << elements[iTrack]
2173 <<
" rejected (Dpt = " << -it->first
2174 <<
" GeV/c, algo = " << trackref->algo() <<
")" << std::endl;
2184 Caloresolution *= totalChargedMomentum;
2185 Caloresolution =
std::sqrt(Caloresolution*Caloresolution + muonHCALError + muonECALError);
2189 for ( IT it = associatedTracks.begin(); it != associatedTracks.end(); ++it ) {
2190 unsigned iTrack = it->second.first;
2191 if ( !active[iTrack] )
continue;
2194 double Dp = trackRef->qoverpError()*trackMomentum*
trackMomentum;
2198 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iTrack );
2199 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHcal );
2200 std::pair<II,II> myEcals = associatedEcals.equal_range(iTrack);
2201 for (II
ii=myEcals.first;
ii!=myEcals.second; ++
ii ) {
2202 unsigned iEcal =
ii->second.second;
2203 if ( active[iEcal] )
continue;
2204 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal );
2208 std::pair<II,II> myHOs = associatedHOs.equal_range(iTrack);
2209 for (II
ii=myHOs.first;
ii!=myHOs.second; ++
ii ) {
2210 unsigned iHO =
ii->second.second;
2211 if ( active[iHO] )
continue;
2212 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHO );
2216 if ( iTrack == corrTrack ) {
2217 (*pfCandidates_)[tmpi].rescaleMomentum(corrFact);
2218 trackMomentum *= corrFact;
2220 chargedHadronsIndices.push_back( tmpi );
2221 chargedHadronsInBlock.push_back( iTrack );
2222 active[iTrack] =
false;
2223 hcalP.push_back(trackMomentum);
2224 hcalDP.push_back(Dp);
2225 if (Dp/trackMomentum > maxDPovP) maxDPovP = Dp/
trackMomentum;
2226 sumpError2 += Dp*Dp;
2230 TotalError =
sqrt(sumpError2 + Caloresolution*Caloresolution);
2233 cout<<
"\tCompare Calo Energy to total charged momentum "<<endl;
2234 cout<<
"\t\tsum p = "<<totalChargedMomentum<<
" +- "<<
sqrt(sumpError2)<<endl;
2235 cout<<
"\t\tsum ecal = "<<totalEcal<<endl;
2236 cout<<
"\t\tsum hcal = "<<totalHcal<<endl;
2237 cout<<
"\t\t => Calo Energy = "<<caloEnergy<<
" +- "<<Caloresolution<<endl;
2238 cout<<
"\t\t => Calo Energy- total charged momentum = "
2239 <<caloEnergy-totalChargedMomentum<<
" +- "<<TotalError<<endl;
2246 double nsigma =
nSigmaHCAL(totalChargedMomentum,hclusterref->positionREP().Eta());
2248 if (
abs(totalChargedMomentum-caloEnergy)<nsigma*TotalError ) {
2254 cout<<
"\t\tcase 1: COMPATIBLE "
2255 <<
"|Calo Energy- total charged momentum| = "
2256 <<
abs(caloEnergy-totalChargedMomentum)
2257 <<
" < "<<nsigma<<
" x "<<TotalError<<endl;
2258 if (maxDPovP < 0.1 )
2259 cout<<
"\t\t\tmax DP/P = "<< maxDPovP
2260 <<
" less than 0.1: do nothing "<<endl;
2262 cout<<
"\t\t\tmax DP/P = "<< maxDPovP
2263 <<
" > 0.1: take weighted averages "<<endl;
2267 if (maxDPovP > 0.1) {
2271 int nrows = chargedHadronsIndices.size();
2272 TMatrixTSym<double>
a (nrows);
2274 TVectorD
check(nrows);
2275 double sigma2E = Caloresolution*Caloresolution;
2276 for(
int i=0;
i<nrows;
i++) {
2277 double sigma2i = hcalDP[
i]*hcalDP[
i];
2279 cout<<
"\t\t\ttrack associated to hcal "<<
i
2280 <<
" P = "<<hcalP[
i]<<
" +- "
2283 a(
i,
i) = 1./sigma2i + 1./sigma2E;
2284 b(
i) = hcalP[
i]/sigma2i + caloEnergy/sigma2E;
2285 for(
int j=0;
j<nrows;
j++) {
2287 a(
i,
j) = 1./sigma2E;
2298 TDecompChol decomp(a);
2300 TVectorD
x = decomp.Solve(b, ok);
2304 for (
int i=0;
i<nrows;
i++){
2306 unsigned ich = chargedHadronsIndices[
i];
2307 double rescaleFactor =
x(
i)/hcalP[
i];
2308 (*pfCandidates_)[ich].rescaleMomentum( rescaleFactor );
2311 cout<<
"\t\t\told p "<<hcalP[
i]
2313 <<
" rescale "<<rescaleFactor<<endl;
2318 cerr<<
"not ok!"<<endl;
2325 else if( caloEnergy > totalChargedMomentum ) {
2344 double eNeutralHadron = caloEnergy - totalChargedMomentum;
2345 double ePhoton = (caloEnergy - totalChargedMomentum) / slopeEcal;
2348 if(!sortedTracks.empty() ){
2349 cout<<
"\t\tcase 2: NEUTRAL DETECTION "
2350 <<caloEnergy<<
" > "<<nsigma<<
"x"<<TotalError
2351 <<
" + "<<totalChargedMomentum<<endl;
2352 cout<<
"\t\tneutral activity detected: "<<endl
2353 <<
"\t\t\t photon = "<<ePhoton<<endl
2354 <<
"\t\t\tor neutral hadron = "<<eNeutralHadron<<endl;
2356 cout<<
"\t\tphoton or hadron ?"<<endl;}
2358 if(sortedTracks.empty() )
2359 cout<<
"\t\tno track -> hadron "<<endl;
2361 cout<<
"\t\t"<<sortedTracks.size()
2362 <<
"tracks -> check if the excess is photonic or hadronic"<<endl;
2366 double ratioMax = 0.;
2368 unsigned maxiEcal= 9999;
2372 for(IE ie = sortedTracks.begin(); ie != sortedTracks.end(); ++ie ) {
2374 unsigned iTrack = ie->second;
2380 assert( !trackRef.
isNull() );
2382 II iae = associatedEcals.find(iTrack);
2384 if( iae == associatedEcals.end() )
continue;
2387 unsigned iEcal = iae->second.second;
2393 assert( !clusterRef.
isNull() );
2395 double pTrack = trackRef->p();
2396 double eECAL = clusterRef->energy();
2397 double eECALOverpTrack = eECAL / pTrack;
2399 if ( eECALOverpTrack > ratioMax ) {
2400 ratioMax = eECALOverpTrack;
2401 maxEcalRef = clusterRef;
2407 std::vector<reco::PFClusterRef> pivotalClusterRef;
2408 std::vector<unsigned> iPivotal;
2409 std::vector<double> particleEnergy, ecalEnergy, hcalEnergy, rawecalEnergy, rawhcalEnergy;
2410 std::vector<math::XYZVector> particleDirection;
2414 if ( ePhoton < totalEcal || eNeutralHadron-calibEcal < 1E-10 ) {
2416 if ( !maxEcalRef.
isNull() ) {
2417 particleEnergy.push_back(ePhoton);
2418 particleDirection.push_back(photonAtECAL);
2419 ecalEnergy.push_back(ePhoton);
2420 hcalEnergy.push_back(0.);
2421 rawecalEnergy.push_back(totalEcal);
2422 rawhcalEnergy.push_back(totalHcal);
2423 pivotalClusterRef.push_back(maxEcalRef);
2424 iPivotal.push_back(maxiEcal);
2426 mergedPhotonEnergy = ePhoton;
2432 if ( !maxEcalRef.
isNull() ) {
2433 pivotalClusterRef.push_back(maxEcalRef);
2434 particleEnergy.push_back(totalEcal);
2435 particleDirection.push_back(photonAtECAL);
2436 ecalEnergy.push_back(totalEcal);
2437 hcalEnergy.push_back(0.);
2438 rawecalEnergy.push_back(totalEcal);
2439 rawhcalEnergy.push_back(totalHcal);
2440 iPivotal.push_back(maxiEcal);
2442 mergedPhotonEnergy = totalEcal;
2446 mergedNeutralHadronEnergy = eNeutralHadron-calibEcal;
2447 if ( mergedNeutralHadronEnergy > 1.0 ) {
2448 pivotalClusterRef.push_back(hclusterref);
2449 particleEnergy.push_back(mergedNeutralHadronEnergy);
2450 particleDirection.push_back(hadronAtECAL);
2451 ecalEnergy.push_back(0.);
2452 hcalEnergy.push_back(mergedNeutralHadronEnergy);
2453 rawecalEnergy.push_back(totalEcal);
2454 rawhcalEnergy.push_back(totalHcal);
2455 iPivotal.push_back(iHcal);
2465 for (
unsigned iPivot=0; iPivot<iPivotal.size(); ++iPivot ) {
2467 if ( particleEnergy[iPivot] < 0. )
2468 std::cout <<
"ALARM = Negative energy ! "
2469 << particleEnergy[iPivot] << std::endl;
2471 bool useDirection =
true;
2473 particleEnergy[iPivot],
2475 particleDirection[iPivot].
X(),
2476 particleDirection[iPivot].Y(),
2477 particleDirection[iPivot].
Z());
2480 (*pfCandidates_)[tmpi].setEcalEnergy( rawecalEnergy[iPivot],ecalEnergy[iPivot] );
2482 (*pfCandidates_)[tmpi].setHcalEnergy( rawhcalEnergy[iPivot],hcalEnergy[iPivot] );
2483 (*pfCandidates_)[tmpi].setHoEnergy(0., 0.);
2485 (*pfCandidates_)[tmpi].setHcalEnergy( rawhcalEnergy[iPivot]-totalHO,hcalEnergy[iPivot]*(1.-totalHO/rawhcalEnergy[iPivot]));
2486 (*pfCandidates_)[tmpi].setHoEnergy(totalHO, totalHO * hcalEnergy[iPivot]/rawhcalEnergy[iPivot]);
2488 (*pfCandidates_)[tmpi].setPs1Energy( 0. );
2489 (*pfCandidates_)[tmpi].setPs2Energy( 0. );
2490 (*pfCandidates_)[tmpi].set_mva_nothing_gamma( -1. );
2493 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHcal );
2494 for (
unsigned ich=0; ich<chargedHadronsInBlock.size(); ++ich) {
2495 unsigned iTrack = chargedHadronsInBlock[ich];
2496 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iTrack );
2502 std::pair<II,II> myEcals = associatedEcals.equal_range(iTrack);
2503 for (II
ii=myEcals.first;
ii!=myEcals.second; ++
ii ) {
2504 unsigned iEcal =
ii->second.second;
2505 if ( active[iEcal] )
continue;
2506 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal );
2518 double totalHcalEnergyCalibrated = calibHcal;
2519 double totalEcalEnergyCalibrated = calibEcal;
2534 totalHcalEnergyCalibrated -= mergedNeutralHadronEnergy;
2536 totalEcalEnergyCalibrated -= mergedPhotonEnergy;
2541 double chargedHadronsTotalEnergy = 0;
2542 for(
unsigned ich=0; ich<chargedHadronsIndices.size(); ++ich ) {
2543 unsigned index = chargedHadronsIndices[ich];
2545 chargedHadronsTotalEnergy += chargedHadron.
energy();
2548 for(
unsigned ich=0; ich<chargedHadronsIndices.size(); ++ich ) {
2549 unsigned index = chargedHadronsIndices[ich];
2551 float fraction = chargedHadron.
energy()/chargedHadronsTotalEnergy;
2554 chargedHadron.
setHcalEnergy( fraction * totalHcal, fraction * totalHcalEnergyCalibrated );
2557 chargedHadron.
setHcalEnergy( fraction * (totalHcal-totalHO), fraction * totalHcalEnergyCalibrated * (1.-totalHO/totalHcal) );
2558 chargedHadron.
setHoEnergy( fraction * totalHO, fraction * totalHO * totalHcalEnergyCalibrated / totalHcal );
2561 chargedHadron.
setEcalEnergy( fraction * totalEcal, fraction * totalEcalEnergyCalibrated );
2565 for ( IS is = ecalSatellites.begin(); is != ecalSatellites.end(); ++is ) {
2568 unsigned iEcal = is->second.first;
2569 if ( !active[iEcal] )
continue;
2574 PFClusterRef eclusterref = elements[iEcal].clusterRef();
2575 assert(!eclusterref.
isNull() );
2578 active[iEcal] =
false;
2581 std::multimap<double, unsigned> assTracks;
2582 block.associatedElements( iEcal, linkData,
2589 (*pfCandidates_)[tmpi].setEcalEnergy( eclusterref->energy(),
sqrt(is->second.second.Mag2()) );
2590 (*pfCandidates_)[tmpi].setHcalEnergy( 0., 0. );
2591 (*pfCandidates_)[tmpi].setHoEnergy( 0., 0. );
2592 (*pfCandidates_)[tmpi].setPs1Energy( associatedPSs[iEcal].
first );
2593 (*pfCandidates_)[tmpi].setPs2Energy( associatedPSs[iEcal].
second );
2594 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal );
2595 (*pfCandidates_)[tmpi].addElementInBlock( blockref, sortedTracks.begin()->second) ;
2609 <<
"---- loop remaining hcal ------- "<<endl;
2615 for(
unsigned ihcluster=0; ihcluster<hcalIs.size(); ihcluster++) {
2616 unsigned iHcal = hcalIs[ihcluster];
2619 std::vector<unsigned> ecalRefs;
2620 std::vector<unsigned> hoRefs;
2623 cout<<endl<<elements[iHcal]<<
" ";
2626 if( !active[iHcal] ) {
2628 cout<<
"not active"<<endl;
2633 std::multimap<double, unsigned> ecalElems;
2634 block.associatedElements( iHcal, linkData,
2640 float totalEcal = 0.;
2643 for(IE ie = ecalElems.begin(); ie != ecalElems.end(); ++ie ) {
2645 unsigned iEcal = ie->second;
2646 double dist = ie->first;
2651 if( !active[iEcal] )
continue;
2672 std::multimap<double, unsigned> hcalElems;
2673 block.associatedElements( iEcal, linkData,
2678 bool isClosest =
true;
2679 for(IE ih = hcalElems.begin(); ih != hcalElems.end(); ++ih ) {
2681 unsigned jHcal = ih->second;
2682 double distH = ih->first;
2684 if ( !active[jHcal] )
continue;
2686 if ( distH < dist ) {
2693 if (!isClosest)
continue;
2697 cout<<
"\telement "<<elements[iEcal]<<
" linked with dist "<< dist<<endl;
2698 cout<<
"Added to HCAL cluster to form a neutral hadron"<<endl;
2702 assert( !eclusterRef.
isNull() );
2705 vector<double> ps1Ene(1,static_cast<double>(0.));
2707 vector<double> ps2Ene(1,static_cast<double>(0.));
2709 bool crackCorrection =
false;
2710 double ecalEnergy =
calibration_->energyEm(*eclusterRef,ps1Ene,ps2Ene,crackCorrection);
2714 totalEcal += ecalEnergy;
2715 if ( ecalEnergy > ecalMax ) {
2716 ecalMax = ecalEnergy;
2717 eClusterRef = eclusterRef;
2720 ecalRefs.push_back(iEcal);
2721 active[iEcal] =
false;
2727 double totalHO = 0.;
2731 std::multimap<double, unsigned> hoElems;
2732 block.associatedElements( iHcal, linkData,
2742 for(IE ie = hoElems.begin(); ie != hoElems.end(); ++ie ) {
2744 unsigned iHO = ie->second;
2745 double dist = ie->first;
2747 assert( type == PFBlockElement::HO );
2750 if( !active[iHO] )
continue;
2756 std::multimap<double, unsigned> hcalElems;
2757 block.associatedElements( iHO, linkData,
2762 bool isClosest =
true;
2763 for(IE ih = hcalElems.begin(); ih != hcalElems.end(); ++ih ) {
2765 unsigned jHcal = ih->second;
2766 double distH = ih->first;
2768 if ( !active[jHcal] )
continue;
2770 if ( distH < dist ) {
2777 if (!isClosest)
continue;
2780 cout<<
"\telement "<<elements[iHO]<<
" linked with dist "<< dist<<endl;
2781 cout<<
"Added to HCAL cluster to form a neutral hadron"<<endl;
2785 assert( !hoclusterRef.
isNull() );
2787 double hoEnergy = hoclusterRef->energy();
2789 totalHO += hoEnergy;
2790 if ( hoEnergy > hoMax ) {
2792 hoClusterRef = hoclusterRef;
2796 hoRefs.push_back(iHO);
2797 active[iHO] =
false;
2803 = elements[iHcal].clusterRef();
2804 assert( !hclusterRef.
isNull() );
2807 double totalHcal = hclusterRef->energy();
2809 if (
useHO_ ) totalHcal += totalHO;
2817 double calibEcal = totalEcal > 0. ? totalEcal : 0.;
2818 double calibHcal =
std::max(0.,totalHcal);
2822 calibEcal = totalEcal;
2825 hclusterRef->positionREP().Eta(),
2826 hclusterRef->positionREP().Phi());
2839 calibEcal+calibHcal );
2842 (*pfCandidates_)[tmpi].setEcalEnergy( totalEcal, calibEcal );
2844 (*pfCandidates_)[tmpi].setHcalEnergy( totalHcal, calibHcal );
2845 (*pfCandidates_)[tmpi].setHoEnergy(0.,0.);
2847 (*pfCandidates_)[tmpi].setHcalEnergy( totalHcal-totalHO, calibHcal*(1.-totalHO/totalHcal));
2848 (*pfCandidates_)[tmpi].setHoEnergy(totalHO,totalHO*calibHcal/totalHcal);
2850 (*pfCandidates_)[tmpi].setPs1Energy( 0. );
2851 (*pfCandidates_)[tmpi].setPs2Energy( 0. );
2852 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHcal );
2853 for (
unsigned iec=0; iec<ecalRefs.size(); ++iec)
2854 (*
pfCandidates_)[tmpi].addElementInBlock( blockref, ecalRefs[iec] );
2855 for (
unsigned iho=0; iho<hoRefs.size(); ++iho)
2856 (*
pfCandidates_)[tmpi].addElementInBlock( blockref, hoRefs[iho] );
2865 if(
debug_)
cout<<endl<<
"---- loop ecal------- "<<endl;
2870 for(
unsigned i=0;
i<ecalIs.size();
i++) {
2871 unsigned iEcal = ecalIs[
i];
2874 cout<<endl<<elements[iEcal]<<
" ";
2876 if( ! active[iEcal] ) {
2878 cout<<
"not active"<<endl;
2885 PFClusterRef clusterref = elements[iEcal].clusterRef();
2886 assert(!clusterref.
isNull() );
2888 active[iEcal] =
false;
2891 vector<double> ps1Ene(1,static_cast<double>(0.));
2893 vector<double> ps2Ene(1,static_cast<double>(0.));
2895 bool crackCorrection =
false;
2896 float ecalEnergy =
calibration_->energyEm(*clusterref,ps1Ene,ps2Ene,crackCorrection);
2898 double particleEnergy = ecalEnergy;
2903 (*pfCandidates_)[tmpi].setEcalEnergy( clusterref->energy(),ecalEnergy );
2904 (*pfCandidates_)[tmpi].setHcalEnergy( 0., 0. );
2905 (*pfCandidates_)[tmpi].setHoEnergy( 0., 0. );
2906 (*pfCandidates_)[tmpi].setPs1Energy( 0. );
2907 (*pfCandidates_)[tmpi].setPs2Energy( 0. );
2908 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal );
2927 double px = track.
px();
2928 double py = track.
py();
2929 double pz = track.
pz();
2930 double energy =
sqrt(track.
p()*track.
p() + 0.13957*0.13957);
2942 pfCandidates_->back().setVertexSource( PFCandidate::kTrkVertex );
2955 if ((!isMuon) && isFromDisp) {
2956 double Dpt = trackRef->ptError();
2957 double dptRel = Dpt/trackRef->pt()*100;
2963 cout <<
"Not refitted px = " << px <<
" py = " << py <<
" pz = " << pz <<
" energy = " << energy << endl;
2966 reco::Track trackRefit = vRef->refittedTrack(trackRef);
2971 sqrt(trackRefit.
p()*trackRefit.
p() + 0.13957*0.13957));
2973 cout <<
"Refitted px = " << px <<
" py = " << py <<
" pz = " << pz <<
" energy = " << energy << endl;
2991 double particleEnergy,
3004 if ( useDirection ) {
3005 switch( cluster.
layer() ) {
3008 factor =
std::sqrt(cluster.
position().Perp2()/(particleX*particleX+particleY*particleY));
3014 factor = cluster.
position().Z()/particleZ;
3029 cluster.
position().Y()-vertexPos.Y(),
3030 cluster.
position().Z()-vertexPos.Z());
3032 particleY*factor-vertexPos.Y(),
3033 particleZ*factor-vertexPos.Z() );
3038 clusterPos = useDirection ? particleDirection.Unit() : clusterPos.Unit();
3039 clusterPos *= particleEnergy;
3045 ROOT::Math::LorentzVector<ROOT::Math::PxPyPzM4D<double> >
3046 momentum( clusterPos.X(), clusterPos.Y(), clusterPos.Z(), mass);
3056 switch( cluster.
layer() ) {
3059 particleType = PFCandidate::gamma;
3063 particleType = PFCandidate::h0;
3066 particleType = PFCandidate::h_HF;
3069 particleType = PFCandidate::egamma_HF;
3105 if ( clusterEnergyHCAL < 1. ) clusterEnergyHCAL = 1.;
3107 double resol = fabs(eta) < 1.48 ?
3108 sqrt (1.02*1.02/clusterEnergyHCAL + 0.065*0.065)
3110 sqrt (1.20*1.20/clusterEnergyHCAL + 0.028*0.028);
3118 double nS = fabs(eta) < 1.48 ?
3128 if(!out )
return out;
3130 out<<
"====== Particle Flow Algorithm ======= ";
3137 out<<
"reconstructed particles: "<<endl;
3139 const std::auto_ptr< reco::PFCandidateCollection >&
3142 if(!candidates.get() ) {
3143 out<<
"candidates already transfered"<<endl;
3172 std::vector<bool>& active,
3173 std::vector<double>& psEne) {
3181 std::multimap<double, unsigned> sortedPS;
3182 typedef std::multimap<double, unsigned>::iterator IE;
3184 sortedPS, psElementType,
3188 double totalPS = 0.;
3189 for ( IE ips=sortedPS.begin(); ips!=sortedPS.end(); ++ips ) {
3192 unsigned iPS = ips->second;
3196 if (!active[iPS])
continue;
3199 std::multimap<double, unsigned> sortedECAL;
3204 unsigned jEcal = sortedECAL.begin()->second;
3205 if ( jEcal != iEcal )
continue;
3209 assert( pstype == psElementType );
3210 PFClusterRef psclusterref = elements[iPS].clusterRef();
3211 assert(!psclusterref.
isNull() );
3212 totalPS += psclusterref->energy();
3213 psEne[0] += psclusterref->energy();
3214 active[iPS] =
false;
3229 bool bPrimary = (order.find(
"primary") != string::npos);
3230 bool bSecondary = (order.find(
"secondary") != string::npos);
3231 bool bAll = (order.find(
"all") != string::npos);
3236 if (bPrimary && isToDisp)
return true;
3237 if (bSecondary && isFromDisp )
return true;
3238 if (bAll && ( isToDisp || isFromDisp ) )
return true;
3267 std::vector<unsigned int> pfCandidatesToBeRemoved;
3274 double met2 = metX*metX+metY*metY;
3276 double significance =
std::sqrt(met2/sumet);
3277 double significanceCor = significance;
3280 double metXCor = metX;
3281 double metYCor = metY;
3282 double sumetCor = sumet;
3283 double met2Cor = met2;
3285 double deltaPhiPt = 100.;
3287 unsigned iCor = 1E9;
3292 double metReduc = -1.;
3306 for(
unsigned j=0;
j<pfCandidatesToBeRemoved.size(); ++
j) {
3307 if (
i == pfCandidatesToBeRemoved[
j] ) skip =
true;
3310 if ( skip )
continue;
3313 deltaPhi = std::acos((metX*pfc.
px()+metY*pfc.
py())/(pfc.
pt()*
std::sqrt(met2)));
3314 deltaPhiPt = deltaPhi*pfc.
pt();
3318 double metXInt = metX - pfc.
px();
3319 double metYInt = metY - pfc.
py();
3320 double sumetInt = sumet - pfc.
pt();
3321 double met2Int = metXInt*metXInt+metYInt*metYInt;
3322 if ( met2Int < met2Cor ) {
3325 metReduc = (met2-met2Int)/met2Int;
3327 sumetCor = sumetInt;
3328 significanceCor =
std::sqrt(met2Cor/sumetCor);
3335 pfCandidatesToBeRemoved.push_back(iCor);
3349 std::cout <<
"Significance reduction = " << significance <<
" -> "
3350 << significanceCor <<
" = " << significanceCor - significance
3352 for(
unsigned j=0;
j<pfCandidatesToBeRemoved.size(); ++
j) {
3353 std::cout <<
"Removed : " << (*pfCandidates_)[pfCandidatesToBeRemoved[
j]] << std::endl;
3355 (*pfCandidates_)[pfCandidatesToBeRemoved[
j]].rescaleMomentum(1E-6);
3369 if ( !cleanedHits.size() )
return;
3375 std::vector<unsigned int> hitsToBeAdded;
3382 double met2 = metX*metX+metY*metY;
3383 double met2_Original = met2;
3387 double metXCor = metX;
3388 double metYCor = metY;
3389 double sumetCor = sumet;
3390 double met2Cor = met2;
3392 unsigned iCor = 1E9;
3397 double metReduc = -1.;
3399 for(
unsigned i=0;
i<cleanedHits.size(); ++
i) {
3408 for(
unsigned j=0;
j<hitsToBeAdded.size(); ++
j) {
3409 if (
i == hitsToBeAdded[
j] ) skip =
true;
3412 if ( skip )
continue;
3415 double metXInt = metX + px;
3416 double metYInt = metY + py;
3417 double sumetInt = sumet + pt;
3418 double met2Int = metXInt*metXInt+metYInt*metYInt;
3421 if ( met2Int < met2Cor ) {
3424 metReduc = (met2-met2Int)/met2Int;
3426 sumetCor = sumetInt;
3435 hitsToBeAdded.push_back(iCor);
3449 std::cout << hitsToBeAdded.size() <<
" hits were re-added " << std::endl;
3453 std::cout <<
"Added after cleaning check : " << std::endl;
3455 for(
unsigned j=0;
j<hitsToBeAdded.size(); ++
j) {
3475 for(
unsigned ic=0;ic<
size;++ic) {
3484 (*pfCandidates_)[ic].setPFElectronExtraRef(theRef);
3496 (*pfCandidates_)[ic].set_mva_e_pi(it->mvaVariable(PFCandidateElectronExtra::MVA_MVA));
3498 (*pfCandidates_)[ic].setPFElectronExtraRef(theRef);
3499 (*pfCandidates_)[ic].setGsfTrackRef(it->gsfTrackRef());
3507 for(
unsigned ic=0;ic<
size;++ic) {
3515 (*pfElectronCandidates_)[ic].setPFElectronExtraRef(theRef);
3526 for(
unsigned ic=0;ic<
size;++ic) {
3531 for(
unsigned pcextra=0;pcextra<sizePhExtra;++pcextra) {
3534 (*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
virtual double energy() const GCC11_FINAL
energy
T getParameter(std::string const &) const
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
std::vector< double > muonHCAL_
Variables for muons and fakes.
ParticleType
particle types
void setPFMuonAndFakeParameters(const edm::ParameterSet &pset)
void addMissingMuons(edm::Handle< reco::MuonCollection >, reco::PFCandidateCollection *cands)
double sumEtEcalIsoForEgammaSC_endcap_
std::auto_ptr< reco::PFCandidateCollection > pfPhotonCandidates_
the unfiltered photon collection
bool isMuon(const Candidate &part)
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)
const std::vector< reco::PFCandidate > & getAllElectronCandidates()
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_
void setParameters(const edm::ParameterSet &)
double nSigmaHCAL_
number of sigma to judge energy excess in HCAL
std::map< unsigned int, Link > LinkData
virtual void processBlock(const reco::PFBlockRef &blockref, std::list< reco::PFBlockRef > &hcalBlockRefs, std::list< reco::PFBlockRef > &ecalBlockRefs)
void setMuonHandle(const edm::Handle< reco::MuonCollection > &)
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)
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 setPFVertexParameters(bool useVertex, const reco::VertexCollection *primaryVertices)
void setEGElectronCollection(const reco::GsfElectronCollection &egelectrons)
std::vector< GsfElectron > GsfElectronCollection
collection of GsfElectron objects
virtual double py() const GCC11_FINAL
y coordinate of momentum vector
bool rejectTracks_Step45_
const math::XYZPointF & positionAtECALEntrance() const
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)
std::vector< double > factors45_
const ElementsInBlocks & elementsInBlocks() 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_
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)
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()
void setPFPhotonRegWeights(const GBRForest *LCorrForestEB, const GBRForest *LCorrForestEE, const GBRForest *GCorrForestBarrel, const GBRForest *GCorrForestEndcapHr9, const GBRForest *GCorrForestEndcapLr9, const GBRForest *PFEcalResolution)
virtual double px() const GCC11_FINAL
x coordinate of momentum vector
double z() const
y coordinate
reco::Vertex primaryVertex_
double nSigmaHCAL(double clusterEnergy, double clusterEta) const
edm::Handle< reco::MuonCollection > muonHandle_
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
void setPostHFCleaningParameters(bool postHFCleaning, double minHFCleaningPt, double minSignificance, double maxSignificance, double minSignificanceReduction, double maxDeltaPhiPt, double minDeltaMet)
block
Formating index page's pieces.
std::vector< PFBlock > PFBlockCollection
collection of PFBlock objects
reco::PFBlockRef createBlockRef(const reco::PFBlockCollection &blocks, unsigned bi)
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
unsigned reconstructTrack(const reco::PFBlockElement &elt, bool allowLoose=false)
std::vector< double > muonHO_
XYZVectorD XYZVector
spatial vector with cartesian internal representation
void setGBRForest(const GBRForest *LCorrForest, const GBRForest *GCorrForest, const GBRForest *ResForest)
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_
reco::PFBlockHandle blockHandle_
input block handle (full framework case)
virtual bool trackType(TrackType trType) const
boost::shared_ptr< PFSCEnergyCalibration > thePFSCEnergyCalibration_
reco::TrackRef trackRef() 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
boost::shared_ptr< PFEnergyCalibrationHF > thepfEnergyCalibrationHF_
std::auto_ptr< reco::PFCandidateCollection > pfCandidates_
PFMuonAlgo * getPFMuonAlgo()
void setPhotonExtraRef(const edm::OrphanHandle< reco::PFCandidatePhotonExtraCollection > &pf_extrah)
bool applyCrackCorrectionsElectrons_
int charge() const
track electric charge
double sumPtTrackIsoForEgammaSC_endcap_
void setPhotonPrimaryVtx(const reco::Vertex &primary)
std::list< reco::PFBlockRef >::iterator IBR
virtual ParticleType particleId() const
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
void postClean(reco::PFCandidateCollection *)
virtual float pt() const GCC11_FINAL
transverse momentum
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)
void setInputsForCleaning(const reco::VertexCollection *)
tuple size
Write out results.
double sumPtTrackIsoForEgammaSC_barrel_
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
void setElectronExtraRef(const edm::OrphanHandle< reco::PFCandidateElectronExtraCollection > &extrah)
void setEGElectronCollection(const reco::GsfElectronCollection &egelectrons)
bool reconstructMuon(reco::PFCandidate &, const reco::MuonRef &, bool allowLoose=false)
PFDisplacedTrackerVertexRef displacedVertexRef(TrackType trType) const
double nSigmaECAL_
number of sigma to judge energy excess in ECAL