00001 #include "RecoParticleFlow/PFRootEvent/interface/METManager.h"
00002
00003 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
00004 #include "DataFormats/HepMCCandidate/interface/GenParticle.h"
00005
00006 #include "DataFormats/METReco/interface/MET.h"
00007 #include "DataFormats/METReco/interface/PFMET.h"
00008 #include "DataFormats/METReco/interface/GenMET.h"
00009
00010 #include "RecoParticleFlow/Benchmark/interface/PFBenchmarkAlgo.h"
00011
00012 METManager::METManager(std::string Filename)
00013 {
00014 outmetfilename_=Filename;
00015 std::cout << "Info: DQM is not yet used in METManager."<<std::endl;
00016 std::cout << "pfMET validation histograms will be saved to '" << outmetfilename_ << "'" << std::endl;
00017 outfile_ = new TFile(outmetfilename_.c_str(), "RECREATE");
00018
00019
00020
00021 }
00022
00023 void METManager::FillHisto(std::string Name)
00024 {
00025
00026 const std::string fullname=outmetfilename_+":/PFTask/Benchmarks/"+Name;
00027
00028 std::map<std::string, GenericBenchmark>::const_iterator i = GenBenchmarkMap_.find( Name );
00029 if ( i == GenBenchmarkMap_.end() )
00030 {
00031 std::cout << "Error in METManager::FillHisto(string): " << Name << " is not in GenBenchmarkMap_" << std::endl;
00032 }
00033 else
00034 {
00035 GenBenchmarkMap_[Name].setfile(outfile_);
00036 std::vector<reco::MET> vmet1;
00037 std::vector<reco::MET> vmet2;
00038 vmet1.push_back(MET1_);
00039 vmet2.push_back(MET2_);
00040 GenBenchmarkMap_[Name].fill(&vmet2,&vmet1,true,false,false,-1.,-1.,-1.,999.);
00041
00042
00043
00044 }
00045 return;
00046 }
00047
00048 void METManager::write()
00049 {
00050 if (GenBenchmarkMap_.size()>0)
00051 {
00052 std::map<std::string, GenericBenchmark>::iterator i = GenBenchmarkMap_.begin();
00053 ((*i).second).write(outmetfilename_);
00054 }
00055 }
00056
00057 void METManager::setMET1(const reco::MET *met)
00058 {
00059 MET1_=*met;
00060 }
00061
00062 void METManager::setMET2(const reco::MET *met)
00063 {
00064 MET2_=*met;
00065 }
00066
00067 void METManager::setMET1(const reco::GenParticleCollection *genParticleList)
00068 {
00069 MET1_=computeGenMET(genParticleList);
00070 }
00071
00072 void METManager::setMET2(const reco::GenParticleCollection *genParticleList)
00073 {
00074 MET2_=computeGenMET(genParticleList);
00075 }
00076
00077 void METManager::setMET1(const reco::PFCandidateCollection& pfCandidates)
00078 {
00079 MET1_=recomputePFMET(pfCandidates);
00080 }
00081
00082 void METManager::setMET2(const reco::PFCandidateCollection& pfCandidates)
00083 {
00084 MET2_=recomputePFMET(pfCandidates);
00085 }
00086
00087 void METManager::SetIgnoreParticlesIDs(const std::vector<unsigned int>* vIgnoreParticlesIDs)
00088 {
00089 vIgnoreParticlesIDs_=(*vIgnoreParticlesIDs);
00090 }
00091
00092 void METManager::SetSpecificIdCut(const std::vector<unsigned int>* Id, const std::vector<double>* Eta)
00093 {
00094 trueMetSpecificIdCut_=(*Id);
00095 trueMetSpecificEtaCut_=(*Eta);
00096 }
00097
00098 reco::MET METManager::computeGenMET(const reco::GenParticleCollection *genParticleList) const
00099 {
00100
00101 double trueMEY = 0.0;
00102 double trueMEX = 0.0;;
00103 double true_met = 0.0;;
00104 double true_set = 0.0;;
00105
00106
00107 for( unsigned i = 0; i < (*genParticleList).size(); i++ ) {
00108
00109
00110
00111 if( (*genParticleList)[i].status() == 1 && fabs((*genParticleList)[i].eta()) < 5.0 ) {
00112
00113 bool ignoreThisPart=false;
00114 if (vIgnoreParticlesIDs_.size()==0) std::cout << "Warning : METManager: vIgnoreParticlesIDs_.size()==0" << std::endl;
00115 for (unsigned int idc=0;idc<vIgnoreParticlesIDs_.size();++idc)
00116 {
00117 if(std::abs((*genParticleList)[i].pdgId()) == (int)vIgnoreParticlesIDs_[idc])
00118 ignoreThisPart=true;
00119 }
00120 for (unsigned int specificIdc=0;specificIdc<trueMetSpecificIdCut_.size();++specificIdc)
00121 {
00122 if (std::abs((*genParticleList)[i].pdgId())== (int)trueMetSpecificIdCut_[specificIdc] &&
00123 fabs((*genParticleList)[i].eta()) > trueMetSpecificEtaCut_[specificIdc])
00124 ignoreThisPart=true;
00125 }
00126
00127 if (!ignoreThisPart) {
00128
00129
00130 trueMEX -= (*genParticleList)[i].et()*cos((*genParticleList)[i].phi());
00131 trueMEY -= (*genParticleList)[i].et()*sin((*genParticleList)[i].phi());
00132 true_set += (*genParticleList)[i].pt();
00133 }
00134 }
00135 }
00136 true_met = sqrt( trueMEX*trueMEX + trueMEY*trueMEY );
00137
00138
00139
00140 math::XYZTLorentzVector p4(trueMEX, trueMEY, 0., true_met);
00141 math::XYZPoint vtx(0.,0.,0.);
00142 return reco::MET(true_set,p4,vtx);
00143 }
00144
00145 void METManager::addGenBenchmark(std::string GenBenchmarkName)
00146 {
00147 GenericBenchmark GenBenchmark;
00148 std::string path = outmetfilename_+":/PFTask";
00149 if (GenBenchmarkMap_.size()==0)
00150 {
00151
00152 outfile_->mkdir("PFTask");
00153
00154
00155
00156 gDirectory->cd(path.c_str());
00157
00158
00159 gDirectory->mkdir("Benchmarks");
00160
00161
00162 }
00163 path = outmetfilename_+":/PFTask/Benchmarks";
00164 gDirectory->cd(path.c_str());
00165 gDirectory->mkdir(GenBenchmarkName.c_str());
00166 path = outmetfilename_+":/PFTask/Benchmarks/"+GenBenchmarkName;
00167
00168 gDirectory->cd(path.c_str());
00169
00170
00171
00172
00173
00174 GenBenchmark.setfile(outfile_);
00175 GenBenchmark.setup(NULL, true, -200., 200., -3.2, 3.2, true);
00176
00177 GenBenchmarkMap_[GenBenchmarkName]=GenBenchmark;
00178
00179 }
00180
00181 reco::MET METManager::recomputePFMET(const reco::PFCandidateCollection& pfCandidates) const
00182 {
00183
00184 typedef math::XYZTLorentzVector LorentzVector;
00185 typedef math::XYZPoint Point;
00186
00187 double sum_et = 0.0;
00188 double sum_ex = 0.0;
00189 double sum_ey = 0.0;
00190 double sum_ez = 0.0;
00191
00192 double NeutralEMEt = 0.0;
00193 double NeutralHadEt = 0.0;
00194 double ChargedEMEt = 0.0;
00195 double ChargedHadEt = 0.0;
00196 double MuonEt = 0.0;
00197 double type6Et = 0.0;
00198 double type7Et = 0.0;
00199
00200 for (unsigned int pfc=0;pfc<pfCandidates.size();++pfc) {
00201 double phi = pfCandidates[pfc].phi();
00202 double theta = pfCandidates[pfc].theta();
00203 double e = pfCandidates[pfc].energy();
00204 double et = e*sin(theta);
00205 sum_ez += e*cos(theta);
00206 sum_et += et;
00207 sum_ex += et*cos(phi);
00208 sum_ey += et*sin(phi);
00209
00210
00211 if (pfCandidates[pfc].particleId() == 1) ChargedHadEt += et;
00212 if (pfCandidates[pfc].particleId() == 2) ChargedEMEt += et;
00213 if (pfCandidates[pfc].particleId() == 3) MuonEt += et;
00214 if (pfCandidates[pfc].particleId() == 4) NeutralEMEt += et;
00215 if (pfCandidates[pfc].particleId() == 5) NeutralHadEt += et;
00216 if (pfCandidates[pfc].particleId() == 6) type6Et += et;
00217 if (pfCandidates[pfc].particleId() == 7) type7Et += et;
00218
00219 }
00220
00221 const double Et_total=NeutralEMEt+NeutralHadEt+ChargedEMEt+ChargedHadEt+MuonEt+type6Et+type7Et;
00222
00223 double met = sqrt( sum_ex*sum_ex + sum_ey*sum_ey );
00224 const LorentzVector p4( -sum_ex, -sum_ey, 0.0, met);
00225 const Point vtx(0.0,0.0,0.0);
00226
00227 SpecificPFMETData specific;
00228 specific.NeutralEMFraction = NeutralEMEt/Et_total;
00229 specific.NeutralHadFraction = NeutralHadEt/Et_total;
00230 specific.ChargedEMFraction = ChargedEMEt/Et_total;
00231 specific.ChargedHadFraction = ChargedHadEt/Et_total;
00232 specific.MuonFraction = MuonEt/Et_total;
00233 specific.Type6Fraction = type6Et/Et_total;
00234 specific.Type7Fraction = type7Et/Et_total;
00235
00236 reco::PFMET specificPFMET( specific, sum_et, p4, vtx );
00237 return specificPFMET;
00238 }
00239
00240 void METManager::coutTailEvents(const int entry, const double DeltaMETcut, const double DeltaPhicut, const double MET1cut) const
00241 {
00242 const double deltaMET=MET2_.pt()-MET1_.pt();
00243 const double deltaPhi=PFBenchmarkAlgo::deltaPhi(&MET1_,&MET2_);
00244
00245
00246
00247 if (MET1_.pt()>MET1cut && (fabs(deltaMET)>DeltaMETcut || fabs(deltaPhi)>DeltaPhicut))
00248 {
00249 std::cout << " =====================PFMETBenchmark =================" << std::endl;
00250 std::cout << "process entry "<< entry << std::endl;
00251 std::cout << "Delta MET = " << deltaMET << std::endl;
00252 std::cout << "MET1 = " << MET1_.pt() << std::endl;
00253 std::cout << "MET2 = " << MET2_.pt() << std::endl;
00254
00255 std::cout << "Delta Phi = " << deltaPhi << std::endl;
00256 std::cout << "Phi1 = " << MET1_.phi() << std::endl;
00257 std::cout << "Phi2 = " << MET2_.phi() << std::endl;
00258
00259 }
00260 }
00261
00262 void METManager::propagateJECtoMET1(const std::vector<reco::CaloJet> caloJets,
00263 const std::vector<reco::CaloJet> corr_caloJets)
00264 {
00265 MET1_=propagateJEC(MET1_,caloJets,corr_caloJets);
00266 }
00267
00268 void METManager::propagateJECtoMET2(const std::vector<reco::CaloJet> caloJets,
00269 const std::vector<reco::CaloJet> corr_caloJets)
00270 {
00271 MET2_=propagateJEC(MET2_,caloJets,corr_caloJets);
00272 }
00273
00274 reco::MET METManager::propagateJEC(const reco::MET &MET, const std::vector<reco::CaloJet> caloJets,
00275 const std::vector<reco::CaloJet> corr_caloJets) const
00276 {
00277
00278
00279 double caloJetCorPX = 0.0;
00280 double caloJetCorPY = 0.0;
00281 double caloJetCorSET = 0.0;
00282
00283 if (caloJets.size()>0 && corr_caloJets.size()==0) std::cout << "No corrected calo jets found !" << std::endl;
00284
00285
00286
00287 for(unsigned int caloJetc=0;caloJetc<caloJets.size();++caloJetc)
00288 {
00289
00290
00291
00292
00293 for(unsigned int corr_caloJetc=0;corr_caloJetc<corr_caloJets.size();++corr_caloJetc)
00294 {
00295
00296
00297
00298
00299 Float_t DeltaPhi = corr_caloJets[corr_caloJetc].phi() - caloJets[caloJetc].phi();
00300 Float_t DeltaEta = corr_caloJets[corr_caloJetc].eta() - caloJets[caloJetc].eta();
00301 Float_t DeltaR2 = DeltaPhi*DeltaPhi + DeltaEta*DeltaEta;
00302 if( DeltaR2 < 0.0001 && caloJets[caloJetc].pt() > 20.0 )
00303 {
00304 caloJetCorPX += (corr_caloJets[corr_caloJetc].px() - caloJets[caloJetc].px());
00305 caloJetCorPY += (corr_caloJets[corr_caloJetc].py() - caloJets[caloJetc].py());
00306 caloJetCorSET += (corr_caloJets[corr_caloJetc].pt() - caloJets[caloJetc].pt());
00307 }
00308 }
00309 }
00310 const double corr_calomet=sqrt((MET.px()-caloJetCorPX)*(MET.px()-caloJetCorPX)+(MET.py()-caloJetCorPY)*(MET.py()-caloJetCorPY));
00311 const double corr_set=MET.sumEt()+caloJetCorSET;
00312
00313 math::XYZTLorentzVector p4(MET.px()-caloJetCorPX, MET.py()-caloJetCorPY, 0., corr_calomet);
00314 math::XYZPoint vtx(0.,0.,0.);
00315
00316
00317 return reco::MET(corr_set,p4,vtx);
00318 }