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)
block
Formating index page's pieces.
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