00001 #include "RecoParticleFlow/Benchmark/interface/PFMETBenchmark.h"
00002
00003 #include "TProfile.h"
00004 #include "TF1.h"
00005 #include "TH1F.h"
00006
00007
00008 #define BOOK1D(name,title,nbinsx,lowx,highx) \
00009 h##name = dbe_ ? dbe_->book1D(#name,title,nbinsx,lowx,highx)->getTH1F() \
00010 : new TH1F(#name,title,nbinsx,lowx,highx)
00011
00012
00013 #define BOOK2D(name,title,nbinsx,lowx,highx,nbinsy,lowy,highy) \
00014 h##name = dbe_ ? dbe_->book2D(#name,title,nbinsx,lowx,highx,nbinsy,lowy,highy)->getTH2F() \
00015 : new TH2F(#name,title,nbinsx,lowx,highx,nbinsy,lowy,highy)
00016
00017
00018
00019 #define SETAXES(name,xtitle,ytitle) \
00020 h##name->GetXaxis()->SetTitle(xtitle); h##name->GetYaxis()->SetTitle(ytitle)
00021
00022
00023
00024
00025
00026
00027 #define PT (plotAgainstReco_)?"reconstructed P_{T}" :"generated P_{T}"
00028
00029 using namespace reco;
00030 using namespace std;
00031
00032 class MonitorElement;
00033
00034 PFMETBenchmark::PFMETBenchmark() : file_(0) {}
00035
00036 PFMETBenchmark::~PFMETBenchmark() {
00037 if(file_) file_->Close();
00038 }
00039
00040 void PFMETBenchmark::write() {
00041
00042 if (outputFile_.size() != 0) {
00043 if (dbe_)
00044 dbe_->save(outputFile_.c_str());
00045
00046 else if (file_) {
00047 file_->Write(outputFile_.c_str());
00048 cout << "Benchmark output written to file " << outputFile_.c_str() << endl;
00049 file_->Close();
00050 }
00051 }
00052 else
00053 cout << "No output file specified ("<<outputFile_<<"). Results will not be saved!" << endl;
00054
00055 }
00056
00057 void PFMETBenchmark::setup(
00058 string Filename,
00059 bool debug,
00060 bool plotAgainstReco,
00061 string benchmarkLabel_,
00062 DQMStore * dbe_store) {
00063 debug_ = debug;
00064 plotAgainstReco_ = plotAgainstReco;
00065 outputFile_=Filename;
00066 file_ = NULL;
00067 dbe_ = dbe_store;
00068
00069
00070 cout << "Filename to write histograms " << Filename<<endl;
00071 cout << "PFMETBenchmark debug " << debug_<< endl;
00072 cout << "plotAgainstReco " << plotAgainstReco_ << endl;
00073 cout << "benchmarkLabel " << benchmarkLabel_ << endl;
00074
00075
00076
00077
00078 string path = "PFTask/Benchmarks/"+ benchmarkLabel_ + "/";
00079 if (plotAgainstReco) path += "Reco"; else path += "Gen";
00080 if (dbe_) {
00081 dbe_->setCurrentFolder(path.c_str());
00082 }
00083 else {
00084 file_ = new TFile(outputFile_.c_str(), "recreate");
00085
00086
00087 cout << "Info: DQM is not available to provide data storage service. Using TFile to save histograms. "<<endl;
00088 }
00089
00090
00091 BOOK1D(MEX,"Particle Flow",400,-200,200);
00092 BOOK1D(DeltaMEX,"Particle Flow",400,-200,200);
00093 BOOK1D(DeltaMET,"Particle Flow",400,-200,200);
00094 BOOK1D(DeltaPhi,"Particle Flow", 1000, -3.2, 3.2);
00095 BOOK1D(DeltaSET,"Particle Flow",400,-200,200);
00096 BOOK2D(SETvsDeltaMET,"Particle Flow",200, 0.0, 1000.0, 400, -200.0, 200.0);
00097 BOOK2D(SETvsDeltaSET,"Particle Flow",200, 0.0, 1000.0, 400, -200.0, 200.0);
00098 profileSETvsSETresp = new TProfile("#DeltaPFSET / trueSET vs trueSET", "", 200, 0.0, 1000.0, -1.0, 1.0);
00099 profileMETvsMETresp = new TProfile("#DeltaPFMET / trueMET vs trueMET", "", 50, 0.0, 200.0, -1.0, 1.0);
00100
00101 BOOK1D(CaloMEX,"Calorimeter",400,-200,200);
00102 BOOK1D(DeltaCaloMEX,"Calorimeter",400,-200,200);
00103 BOOK1D(DeltaCaloMET,"Calorimeter",400,-200,200);
00104 BOOK1D(DeltaCaloPhi,"Calorimeter", 1000, -3.2, 3.2);
00105 BOOK1D(DeltaCaloSET,"Calorimeter",400,-200,200);
00106 BOOK2D(CaloSETvsDeltaCaloMET,"Calorimeter",200, 0.0, 1000.0, 400, -200.0, 200.0);
00107 BOOK2D(CaloSETvsDeltaCaloSET,"Calorimeter",200, 0.0, 1000.0, 400, -200.0, 200.0);
00108 profileCaloSETvsCaloSETresp = new TProfile("#DeltaCaloSET / trueSET vs trueSET", "", 200, 0.0, 1000.0, -1.0, 1.0);
00109 profileCaloMETvsCaloMETresp = new TProfile("#DeltaCaloMET / trueMET vs trueMET", "", 200, 0.0, 200.0, -1.0, 1.0);
00110
00111 BOOK2D(DeltaPFMETvstrueMET,"Particle Flow", 500, 0.0, 1000.0, 400, -200.0, 200.0);
00112 BOOK2D(DeltaCaloMETvstrueMET,"Calorimeter", 500, 0.0, 1000.0, 400, -200.0, 200.0);
00113 BOOK2D(DeltaPFPhivstrueMET,"Particle Flow", 500, 0.0, 1000.0, 400, -3.2, 3.2);
00114 BOOK2D(DeltaCaloPhivstrueMET,"Calorimeter", 500, 0.0, 1000.0, 400, -3.2, 3.2);
00115 BOOK2D(CaloMETvstrueMET,"Calorimeter", 500, 0.0, 1000.0, 500, 0.0, 1000.0);
00116 BOOK2D(PFMETvstrueMET,"Particle Flow", 500, 0.0, 1000.0, 500, 0.0, 1000.0);
00117
00118 BOOK2D(DeltaCaloMEXvstrueSET,"Calorimeter",200, 0.0, 1000.0, 400, -200.0, 200.0);
00119 BOOK2D(DeltaPFMEXvstrueSET,"Particle Flow",200, 0.0, 1000.0, 400, -200.0, 200.0);
00120
00121 BOOK1D(TrueMET,"MC truth", 500, 0.0, 1000.0);
00122 BOOK1D(CaloMET,"Calorimeter", 500, 0.0, 1000.0);
00123 BOOK1D(PFMET,"Particle Flow", 500, 0.0, 1000.0);
00124
00125 BOOK1D(TCMEX,"Track Corrected",400,-200,200);
00126 BOOK1D(DeltaTCMEX,"Track Corrected",400,-200,200);
00127 BOOK1D(DeltaTCMET,"Track Corrected",400,-200,200);
00128 BOOK1D(DeltaTCPhi,"Track Corrected", 1000, -3.2, 3.2);
00129 BOOK1D(DeltaTCSET,"Track Corrected",400,-200,200);
00130 BOOK2D(TCSETvsDeltaTCMET,"Track Corrected",200, 0.0, 1000.0, 400, -200.0, 200.0);
00131 BOOK2D(TCSETvsDeltaTCSET,"Track Corrected",200, 0.0, 1000.0, 400, -200.0, 200.0);
00132 profileTCSETvsTCSETresp = new TProfile("#DeltaTCSET / trueSET vs trueSET", "", 200, 0.0, 1000.0, -1.0, 1.0);
00133 profileTCMETvsTCMETresp = new TProfile("#DeltaTCMET / trueMET vs trueMET", "", 200, 0.0, 200.0, -1.0, 1.0);
00134
00135 BOOK1D(TCMET,"Track Corrected",500,0,1000);
00136 BOOK2D(DeltaTCMETvstrueMET,"Track Corrected", 500, 0.0, 1000.0, 400, -200.0, 200.0);
00137 BOOK2D(DeltaTCPhivstrueMET,"Track Corrected", 500, 0.0, 1000.0, 400, -3.2, 3.2);
00138
00139 BOOK2D(DeltaTCMEXvstrueSET,"Track Corrected", 200, 0.0, 1000.0, 400, -200.0, 200.0);
00140 BOOK2D(TCMETvstrueMET,"Track Corrected", 200, 0.0, 1000.0, 500, 0.0, 1000.0);
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151 SETAXES(MEX, "MEX", "Events");
00152 SETAXES(DeltaMEX, "#DeltaMEX", "Events");
00153 SETAXES(DeltaMET, "#DeltaMET", "Events");
00154 SETAXES(DeltaPhi, "#Delta#phi", "Events");
00155 SETAXES(DeltaSET, "#DeltaSET", "Events");
00156 SETAXES(SETvsDeltaMET, "SET", "#DeltaMET");
00157 SETAXES(SETvsDeltaSET, "SET", "#DeltaSET");
00158
00159 SETAXES(DeltaPFMETvstrueMET, "trueMET", "#DeltaMET");
00160 SETAXES(DeltaCaloMETvstrueMET, "trueMET", "#DeltaCaloMET");
00161 SETAXES(DeltaPFPhivstrueMET, "trueMET", "#DeltaPFPhi");
00162 SETAXES(DeltaCaloPhivstrueMET, "trueMET", "#DeltaCaloPhi");
00163 SETAXES(CaloMETvstrueMET, "trueMET", "CaloMET");
00164 SETAXES(PFMETvstrueMET, "trueMET", "PFMET");
00165 SETAXES(DeltaCaloMEXvstrueSET, "trueSET", "#DeltaCaloMEX");
00166 SETAXES(DeltaPFMEXvstrueSET, "trueSET", "#DeltaPFMEX");
00167 SETAXES(TrueMET, "trueMET", "Events");
00168 SETAXES(CaloMET, "CaloMET", "Events");
00169 SETAXES(PFMET, "PFMET", "Events");
00170 SETAXES(TCMET, "TCMET", "Events");
00171
00172 SETAXES(CaloMEX, "MEX", "Events");
00173 SETAXES(DeltaCaloMEX, "#DeltaMEX", "Events");
00174 SETAXES(DeltaCaloMET, "#DeltaMET", "Events");
00175 SETAXES(DeltaCaloPhi, "#Delta#phi", "Events");
00176 SETAXES(DeltaCaloSET, "#DeltaSET", "Events");
00177 SETAXES(CaloSETvsDeltaCaloMET, "SET", "#DeltaMET");
00178 SETAXES(CaloSETvsDeltaCaloSET, "SET", "#DeltaSET");
00179
00180 SETAXES(TCMEX, "MEX", "Events");
00181 SETAXES(DeltaTCMEX, "#DeltaMEX", "Events");
00182 SETAXES(DeltaTCMET, "#DeltaMET", "Events");
00183 SETAXES(DeltaTCPhi, "#Delta#phi", "Events");
00184 SETAXES(DeltaTCSET, "#DeltaSET", "Events");
00185 SETAXES(TCSETvsDeltaTCMET, "SET", "#DeltaMET");
00186 SETAXES(TCSETvsDeltaTCSET, "SET", "#DeltaSET");
00187
00188 SETAXES(DeltaTCMETvstrueMET, "trueMET", "#DeltaTCMET");
00189 SETAXES(DeltaTCPhivstrueMET, "trueMET", "#DeltaTCPhi");
00190
00191 SETAXES(DeltaTCMEXvstrueSET, "trueSET", "#DeltaTCMEX");
00192 SETAXES(TCMETvstrueMET, "trueMET", "TCMET");
00193 }
00194
00195
00196
00197 void PFMETBenchmark::process( const reco::PFMETCollection& pfMets,
00198 const reco::GenParticleCollection& genParticleList,
00199 const reco::CaloMETCollection& caloMets,
00200 const reco::METCollection& tcMets ) {
00201 calculateQuantities(pfMets, genParticleList, caloMets, tcMets);
00202 if (debug_) {
00203 cout << " =========PFMET " << rec_met << ", " << rec_phi << endl;
00204 cout << " =========GenMET " << true_met << ", " << true_phi << endl;
00205 cout << " =========CaloMET " << calo_met << ", " << calo_phi << endl;
00206 cout << " =========TCMET " << tc_met << ", " << tc_phi << endl;
00207 }
00208
00209 hTrueMET->Fill(true_met);
00210
00211
00212 hDeltaMET->Fill( rec_met - true_met );
00213 hMEX->Fill( rec_mex );
00214 hMEX->Fill( rec_mey );
00215 hDeltaMEX->Fill( rec_mex - true_mex );
00216 hDeltaMEX->Fill( rec_mey - true_mey );
00217 hDeltaPhi->Fill( rec_phi - true_phi );
00218 hDeltaSET->Fill( rec_set - true_set );
00219 if( true_met > 5.0 ) hSETvsDeltaMET->Fill( rec_set, rec_met - true_met );
00220 else hSETvsDeltaMET->Fill( rec_set, rec_mex - true_mex );
00221 hSETvsDeltaSET->Fill( rec_set, rec_set - true_set );
00222 if( true_met > 5.0 ) profileMETvsMETresp->Fill(true_met, (rec_met-true_met)/true_met);
00223 profileSETvsSETresp->Fill(true_set, (rec_set-true_set)/true_set);
00224
00225 hDeltaPFMETvstrueMET->Fill(true_met, rec_met - true_met);
00226 hDeltaPFPhivstrueMET->Fill(true_met, rec_phi - true_phi);
00227 hPFMETvstrueMET->Fill(true_met, rec_met);
00228 hPFMET->Fill(rec_met);
00229
00230 hDeltaPFMEXvstrueSET->Fill(true_set, rec_mex - true_mex);
00231 hDeltaPFMEXvstrueSET->Fill(true_set, rec_mey - true_mey);
00232
00233
00234 hDeltaCaloMET->Fill( calo_met - true_met );
00235 hCaloMEX->Fill( calo_mex );
00236 hCaloMEX->Fill( calo_mey );
00237 hDeltaCaloMEX->Fill( calo_mex - true_mex);
00238 hDeltaCaloMEX->Fill( calo_mey - true_mey);
00239 hDeltaCaloPhi->Fill( calo_phi - true_phi );
00240 hDeltaCaloSET->Fill( calo_set - true_set );
00241 if( true_met > 5.0 ) hCaloSETvsDeltaCaloMET->Fill( calo_set, calo_met - true_met );
00242 else hCaloSETvsDeltaCaloMET->Fill( calo_set, calo_mex - true_mex);
00243 hCaloSETvsDeltaCaloSET->Fill( calo_set, calo_set - true_set );
00244 if( true_met > 5.0 ) profileCaloMETvsCaloMETresp->Fill(true_met, (calo_met-true_met)/true_met);
00245 profileCaloSETvsCaloSETresp->Fill(true_set, (calo_set-true_set)/true_set);
00246
00247 hDeltaCaloMETvstrueMET->Fill(true_met, calo_met - true_met);
00248 hDeltaCaloPhivstrueMET->Fill(true_met, calo_phi - true_phi);
00249 hCaloMETvstrueMET->Fill(true_met, calo_met);
00250 hCaloMET->Fill(calo_met);
00251
00252 hDeltaCaloMEXvstrueSET->Fill(true_set, calo_mex - true_mex);
00253 hDeltaCaloMEXvstrueSET->Fill(true_set, calo_mey - true_mey);
00254
00255
00256 hDeltaTCMET->Fill( tc_met - true_met );
00257 hTCMET->Fill( tc_met );
00258 hTCMEX->Fill( tc_mex );
00259 hTCMEX->Fill( tc_mey );
00260 hDeltaTCMEX->Fill( tc_mex - true_mex);
00261 hDeltaTCMEX->Fill( tc_mey - true_mey);
00262 hDeltaTCPhi->Fill( tc_phi - true_phi );
00263 hDeltaTCSET->Fill( tc_set - true_set );
00264 if( true_met > 5.0 ) hTCSETvsDeltaTCMET->Fill( tc_set, tc_met - true_met );
00265 else hTCSETvsDeltaTCMET->Fill( tc_set, tc_mex - true_mex);
00266 hTCSETvsDeltaTCSET->Fill( tc_set, tc_set - true_set );
00267 if( true_met > 5.0 ) profileTCMETvsTCMETresp->Fill(true_met, (tc_met-true_met)/true_met);
00268 profileTCSETvsTCSETresp->Fill(true_set, (tc_set-true_set)/true_set);
00269
00270 hDeltaTCMETvstrueMET->Fill( true_met, tc_met - true_met);
00271 hDeltaTCPhivstrueMET->Fill( true_met, tc_phi - true_phi);
00272 hDeltaTCMEXvstrueSET->Fill( true_set, tc_mex - true_mex);
00273 hDeltaTCMEXvstrueSET->Fill( true_set, tc_mey - true_mey);
00274 hTCMETvstrueMET->Fill( true_met, tc_met );
00275
00276 }
00277
00278 void PFMETBenchmark::calculateQuantities( const reco::PFMETCollection& pfMets,
00279 const reco::GenParticleCollection& genParticleList,
00280 const reco::CaloMETCollection& caloMets,
00281 const reco::METCollection& tcMets)
00282 {
00283 const reco::PFMET& pfm = pfMets[0];
00284 const reco::CaloMET& cm = caloMets[0];
00285 const reco::MET& tcm = tcMets[0];
00286
00287 double trueMEY = 0.0;
00288 double trueMEX = 0.0;;
00289 true_set = 0.0;;
00290
00291
00292 for( unsigned i = 0; i < genParticleList.size(); i++ ) {
00293 if( genParticleList[i].status() == 1 && fabs(genParticleList[i].eta()) < 5.0 ) {
00294 if( std::abs(genParticleList[i].pdgId()) == 12 ||
00295 std::abs(genParticleList[i].pdgId()) == 14 ||
00296 std::abs(genParticleList[i].pdgId()) == 16 ||
00297 std::abs(genParticleList[i].pdgId()) < 7 ||
00298 std::abs(genParticleList[i].pdgId()) == 21 ) {
00299 trueMEX += genParticleList[i].px();
00300 trueMEY += genParticleList[i].py();
00301 } else {
00302 true_set += genParticleList[i].pt();
00303 }
00304 }
00305 }
00306 true_mex = -trueMEX;
00307 true_mey = -trueMEY;
00308 true_met = sqrt( trueMEX*trueMEX + trueMEY*trueMEY );
00309 true_phi = atan2(trueMEY,trueMEX);
00310 rec_met = pfm.pt();
00311 rec_mex = pfm.px();
00312 rec_mex = pfm.py();
00313 rec_phi = pfm.phi();
00314 rec_set = pfm.sumEt();
00315 calo_met = cm.pt();
00316 calo_mex = cm.px();
00317 calo_mey = cm.py();
00318 calo_phi = cm.phi();
00319 calo_set = cm.sumEt();
00320 tc_met = tcm.pt();
00321 tc_mex = tcm.px();
00322 tc_mey = tcm.py();
00323 tc_phi = tcm.phi();
00324 tc_set = tcm.sumEt();
00325
00326 if (debug_) {
00327 cout << " =========PFMET " << rec_met << ", " << rec_phi << endl;
00328 cout << " =========trueMET " << true_met << ", " << true_phi << endl;
00329 cout << " =========CaloMET " << calo_met << ", " << calo_phi << endl;
00330 cout << " =========TCMET " << tc_met << ", " << tc_phi << endl;
00331 }
00332 }
00333
00334 void PFMETBenchmark::calculateQuantities( const reco::PFMETCollection& pfMets,
00335 const reco::GenParticleCollection& genParticleList,
00336 const reco::CaloMETCollection& caloMets,
00337 const reco::METCollection& tcMets,
00338 const std::vector<reco::CaloJet> caloJets,
00339 const std::vector<reco::CaloJet> corr_caloJets)
00340 {
00341 const reco::PFMET& pfm = pfMets[0];
00342 const reco::CaloMET& cm = caloMets[0];
00343 const reco::MET& tcm = tcMets[0];
00344
00345 double trueMEY = 0.0;
00346 double trueMEX = 0.0;;
00347 true_set = 0.0;;
00348
00349
00350 for( unsigned i = 0; i < genParticleList.size(); i++ ) {
00351 if( genParticleList[i].status() == 1 && fabs(genParticleList[i].eta()) < 5.0 ) {
00352 if( std::abs(genParticleList[i].pdgId()) == 12 ||
00353 std::abs(genParticleList[i].pdgId()) == 14 ||
00354 std::abs(genParticleList[i].pdgId()) == 16 ||
00355 std::abs(genParticleList[i].pdgId()) < 7 ||
00356 std::abs(genParticleList[i].pdgId()) == 21 ) {
00357 trueMEX += genParticleList[i].px();
00358 trueMEY += genParticleList[i].py();
00359 } else {
00360 true_set += genParticleList[i].pt();
00361 }
00362 }
00363 }
00364 true_mex = -trueMEX;
00365 true_mey = -trueMEY;
00366 true_met = sqrt( trueMEX*trueMEX + trueMEY*trueMEY );
00367 true_phi = atan2(trueMEY,trueMEX);
00368 rec_met = pfm.pt();
00369 rec_mex = pfm.px();
00370 rec_mex = pfm.py();
00371 rec_phi = pfm.phi();
00372 rec_set = pfm.sumEt();
00373
00374
00375 double caloJetCorPX = 0.0;
00376 double caloJetCorPY = 0.0;
00377
00378 for(unsigned int caloJetc=0;caloJetc<caloJets.size();++caloJetc)
00379 {
00380
00381
00382
00383
00384 for(unsigned int corr_caloJetc=0;corr_caloJetc<corr_caloJets.size();++corr_caloJetc)
00385 {
00386
00387
00388
00389
00390 Float_t DeltaPhi = corr_caloJets[corr_caloJetc].phi() - caloJets[caloJetc].phi();
00391 Float_t DeltaEta = corr_caloJets[corr_caloJetc].eta() - caloJets[caloJetc].eta();
00392 Float_t DeltaR2 = DeltaPhi*DeltaPhi + DeltaEta*DeltaEta;
00393 if( DeltaR2 < 0.0001 && caloJets[caloJetc].pt() > 20.0 )
00394 {
00395 caloJetCorPX += (corr_caloJets[corr_caloJetc].px() - caloJets[caloJetc].px());
00396 caloJetCorPY += (corr_caloJets[corr_caloJetc].py() - caloJets[caloJetc].py());
00397 }
00398 }
00399 }
00400 double corr_calomet=sqrt((cm.px()-caloJetCorPX)*(cm.px()-caloJetCorPX)+(cm.py()-caloJetCorPY)*(cm.py()-caloJetCorPY));
00401 calo_met = corr_calomet;
00402 calo_mex = cm.px()-caloJetCorPX;
00403 calo_mey = cm.py()-caloJetCorPY;
00404 calo_phi = atan2((cm.py()-caloJetCorPY),(cm.px()-caloJetCorPX));
00405
00406
00407
00408
00409
00410 calo_set = cm.sumEt();
00411 tc_met = tcm.pt();
00412 tc_mex = tcm.px();
00413 tc_mey = tcm.py();
00414 tc_phi = tcm.phi();
00415 tc_set = tcm.sumEt();
00416
00417 if (debug_) {
00418 cout << " =========PFMET " << rec_met << ", " << rec_phi << endl;
00419 cout << " =========trueMET " << true_met << ", " << true_phi << endl;
00420 cout << " =========CaloMET " << calo_met << ", " << calo_phi << endl;
00421 cout << " =========TCMET " << tc_met << ", " << tc_phi << endl;
00422 }
00423 }
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433 void PFMETBenchmark::analyse()
00434 {
00435
00436
00437
00438
00439
00440
00441
00446
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523 }
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626 double
00627 PFMETBenchmark::mpi_pi(double angle) {
00628
00629 const double pi = 3.14159265358979323;
00630 const double pi2 = pi*2.;
00631 while(angle>pi) angle -= pi2;
00632 while(angle<-pi) angle += pi2;
00633 return angle;
00634
00635 }