diff --git a/Validation/RecoMuon/test/README b/Validation/RecoMuon/test/README index 7054689073bbb..3e304edbc3099 100644 --- a/Validation/RecoMuon/test/README +++ b/Validation/RecoMuon/test/README @@ -2,7 +2,16 @@ Muon Summary Validation script ******************************* -Version 0 ---------- -a) User needs to set input data in the file userparams.py -b) User needs to run muonReleaseSummary.py +New Muon Validation: from CMSSW_10_1_0_pre1 + +* set the input data in: new_userparams.py +* then run: python new_muonReleaseSummary.py + +------------------------------- + +Old Muon Validation: up to CMSSW_10_1_0_pre1 + +* set the input data in: userparams.py +* then run: python muonReleaseSummary.py + + diff --git a/Validation/RecoMuon/test/macro/IsoValHistoPublisher.C b/Validation/RecoMuon/test/macro/IsoValHistoPublisher.C index ec17832246ebe..02771ad6fe8d3 100644 --- a/Validation/RecoMuon/test/macro/IsoValHistoPublisher.C +++ b/Validation/RecoMuon/test/macro/IsoValHistoPublisher.C @@ -1,7 +1,7 @@ #include #include #include "TMath.h" -#include "PlotHelpers.C" +#include "macro/PlotHelpers.C" // Uncomment the following line for some extra debug information // #define DEBUG diff --git a/Validation/RecoMuon/test/macro/NewTrackValHistoPublisher.C b/Validation/RecoMuon/test/macro/NewTrackValHistoPublisher.C deleted file mode 100644 index 9ea2df6272144..0000000000000 --- a/Validation/RecoMuon/test/macro/NewTrackValHistoPublisher.C +++ /dev/null @@ -1,508 +0,0 @@ -#include -#include -#include "TMath.h" -#include "PlotHelpers.C" - - -//Uncomment the following line to get some more output -//#define DEBUG 1 - -TList* GetListOfBranches(const char* dataType, TFile* file) { - if (TString(dataType) == "HLT") { - if(file->cd("DQMData/Run 1/HLT")) - file->cd("DQMData/Run 1/HLT/Run summary/Muon/MultiTrack"); - else - file->cd("DQMData/HLT/Muon/MultiTrack"); - } - else if (TString(dataType) == "RECO") { - if(file->cd("DQMData/Run 1/RecoMuonV")) - file->cd("DQMData/Run 1/RecoMuonV/Run summary/MultiTrack"); - else if(file->cd("DQMData/Run 1/Muons/Run summary/RecoMuonV")) - file->cd("DQMData/Run 1/Muons/Run summary/RecoMuonV/MultiTrack"); - else - file->cd("DQMData/RecoMuonV/MultiTrack"); - } - else { - cout << "ERROR: Data type " << dataType << " not allowed: only RECO and HLT are considered" << endl; - return 0; - } - - TDirectory * dir=gDirectory; - TList* sl = GetListOfDirectories(dir); - - if (sl->GetSize() == 0) { - cout << "ERROR: No DQM muon reco histos found in NEW file " << endl; - delete sl; - return 0; - } - - return sl; -} - - - -void NewTrackValHistoPublisher(const char* newFile="NEW_FILE",const char* refFile="REF_FILE") { - - cout << ">> Starting TrackValHistoPublisher(" - << newFile << "," << refFile << ")..." << endl; - - //==== To be replaced from python ==================== - - const char* dataType = "DATATYPE"; - const char* refLabel("REF_LABEL, REF_RELEASE REFSELECTION"); - const char* newLabel("NEW_LABEL, NEW_RELEASE NEWSELECTION"); - - - // ==== Initial settings and loads - //gROOT->ProcessLine(".x HistoCompare_Tracks.C"); - //gROOT ->Reset(); - gROOT ->SetBatch(); - gErrorIgnoreLevel = kWarning; // Get rid of the info messages - - - SetGlobalStyle(); - - Float_t maxPT; - TString File = newFile; - if (File.Contains("SingleMuPt1000") ||File.Contains("WpM")||File.Contains("ZpMM") ) maxPT=1400.; - else if (File.Contains("SingleMuPt100")) {maxPT = 400.;} - else if(File.Contains("SingleMuPt10")) {maxPT = 70.;} - else maxPT = 400.; - - bool ctf=1; - - bool resol = false; - - // ==== Some cleaning... is this needed? - delete gROOT->GetListOfFiles()->FindObject(refFile); - delete gROOT->GetListOfFiles()->FindObject(newFile); - - - - // ==== Opening files, moving to the right branch and getting the list of sub-branches - cout << ">> Openning file, moving to the right branch and getting sub-branches..." << endl; - - cout << ">> Finding sources..." << endl; - TFile * sfile = new TFile(newFile); - TList* sl = GetListOfBranches(dataType, sfile); - if (!sl) { - cout << "ERROR: Could not find keys!!!" << endl; - cerr << "ERROR: Could not find keys!!!" << endl; - return; - } - TDirectory* sdir = gDirectory; - for (unsigned int i = 0; i < sl->GetEntries(); i++) - cout << " + " << sl->At(i)->GetName() << endl; - - cout << ">> Finding references..." << endl; - TFile * rfile = new TFile(refFile); - TList* rl = GetListOfBranches(dataType, rfile); - if (!rl) { - cout << "ERROR: Could not find keys!!!" << endl; - cerr << "ERROR: Could not find keys!!!" << endl; - return; - } - TDirectory* rdir = gDirectory; - for (unsigned int i = 0; i < sl->GetEntries(); i++) - cout << " + " << sl->At(i)->GetName() << endl; - - - - - - - //==== Find if the collection has muon associator or track associator - cout << ">> Find if the collection has muon associator or track associator..." << endl; - bool hasOnlyMuonAssociatorInRef = true; - bool hasOnlyMuonAssociatorInSig = true; - bool hasOnlyTrackAssociatorInRef = true; - bool hasOnlyTrackAssociatorInSig = true; - TIter iter_r0( rl ); - TIter iter_s0( sl ); - TKey* rKey = 0; - TKey* sKey = 0; - - /*while ( (rKey = (TKey*)iter_r0()) ) { - TString myName = rKey->GetName(); - if ( !(myName.Contains("TkAsso")) && !(myName.Contains("MuonAssociation")) ) { - hasOnlyMuonAssociatorInRef = false; - } - if ( !(myName.Contains("TkAsso")) && (myName.Contains("MuonAssociation")) ) { - hasOnlyTrackAssociatorInRef = false; - } - } - - while ( (sKey = (TKey*)iter_s0()) ) { - TString myName = sKey->GetName(); - if ( !(myName.Contains("TkAsso")) && !(myName.Contains("MuonAssociation")) ) { - hasOnlyMuonAssociatorInSig = false; - } - if ( !(myName.Contains("TkAsso")) && (myName.Contains("MuonAssociation")) ) { - hasOnlyTrackAssociatorInSig = false; - } - } - */ - bool considerOnlyMuonAssociator = hasOnlyMuonAssociatorInRef || hasOnlyMuonAssociatorInSig; - - cout << " + Has Only Muon Associator (reference): " << hasOnlyMuonAssociatorInRef << endl; - cout << " + Has Only Muon Associator (signal): " << hasOnlyMuonAssociatorInSig << endl; - cout << " + Has Only Track Associator (reference): " << hasOnlyTrackAssociatorInRef << endl; - cout << " + Has Only Track Associator (signal): " << hasOnlyTrackAssociatorInSig << endl; - cout << " + Consider only Muon Associator: " << considerOnlyMuonAssociator << endl; - - - - //==== Iterate now over histograms and collections - cout << ">> Iterating over histograms and collections..." << endl; - - TIter iter_r( rl ); - TIter iter_s( sl ); - TString scollname; - TString rcollname; - - TKey *myNext2=0; - while ( (rKey = (TKey*)iter_r()) ) { - TString myName = rKey->GetName(); -#ifdef DEBUG - cout << "DEBUG: Checking key " << myName << endl; -#endif - /* if (!(myName.Contains("TkAsso")) && - considerOnlyMuonAssociator && - hasOnlyTrackAssociatorInRef) { - if (myName.Contains("TrackAssociation")) - myName.ReplaceAll("TrackAssociation","MuonAssociation"); - else - myName.ReplaceAll("Association","MuonAssociation"); - } - while (considerOnlyMuonAssociator && - !(myName.Contains("TkAsso")) && - !(myName.Contains("MuonAssociation")) ) { - rKey = (TKey*)iter_r(); - myName = rKey->GetName(); - }*/ - rcollname = myName; - // ==> extractedGlobalMuons are in a different position wrt globalMuons: - if (myNext2) { - sKey = myNext2; - myNext2 = 0; - } - else { - sKey = (TKey*)iter_s(); - } - if (!sKey) continue; - TString myName2 = sKey->GetName(); - /* this was thought for when there are different names - */ - if (myName2 != myName) { - myNext2 = (TKey*)iter_s(); - TKey* myTemp = sKey; - sKey = myNext2; - myName2 = sKey->GetName(); - myNext2 = myTemp; - if(myName2 != myName) - {myNext2 = (TKey*)iter_s(); - TKey* myTemp = sKey; - sKey = myNext2; - myName2 = sKey->GetName(); - myNext2 = myTemp; - } - } - - scollname=myName2; -#ifdef DEBUG - cout << "DEBUG: Comparing " << rcollname << " and " << scollname << endl; -#endif - if ( - (myName == myName2) || (myName+"FS" == myName2) || (myName == myName2+"FS" ) - || (myName.Contains("extractedGlobalMuons") && myName2.Contains("globalMuons") ) - || (myName.Contains("globalMuons") && myName2.Contains("extractedGlobalMuons") ) - ) { - rcollname = rKey->GetName(); - scollname = sKey->GetName(); - } - else if ( (rcollname != scollname) && (rcollname+"FS" != scollname) && (rcollname != scollname+"FS") ) { - bool goodAsWell = false; - if (rcollname.BeginsWith("StandAloneMuons_UpdAtVtx") && - scollname.BeginsWith("StandAloneMuons_UpdAtVtx")) { - if (rcollname.Contains("MuonAssociation")==scollname.Contains("MuonAssociation")){} - goodAsWell = true; - } - if (rcollname.BeginsWith("hltL2Muons_UpdAtVtx") && - scollname.BeginsWith("hltL2Muons_UpdAtVtx")) { - if (rcollname.Contains("MuonAssociation")==scollname.Contains("MuonAssociation")){} - goodAsWell = true; - } - if (rcollname.BeginsWith("hltL3Tk") && scollname.BeginsWith("hltL3Tk")) { - if (rcollname.Contains("MuonAssociation")==scollname.Contains("MuonAssociation")){} - goodAsWell = true; - } - // TString isGood = (goodAsWell? "good": "NOT good"); - // cout << " -- The two collections: " << rcollname << " : " << scollname << " -> " << isGood << endl; - if (! goodAsWell) { - - if (rcollname.Contains("SET") && !scollname.Contains("SET")) { - while (rcollname.Contains("SET")) { - if ((rKey = (TKey*)iter_r())) rcollname = rKey->GetName(); - } - } - else if (scollname.Contains("SET") && !rcollname.Contains("SET")) { - while (scollname.Contains("SET")) { - if ((sKey = (TKey*)iter_s())) scollname = sKey->GetName(); - } - } - - if (rcollname.Contains("dyt") && !scollname.Contains("dyt")) { - while (rcollname.Contains("dyt")) { - if ((rKey = (TKey*)iter_r())) rcollname = rKey->GetName(); - } - } - else if (scollname.Contains("dyt") && !rcollname.Contains("dyt")) { - while (scollname.Contains("dyt")) { - if ((sKey = (TKey*)iter_s())) scollname = sKey->GetName(); - } - } - - if (rcollname.Contains("refitted") && !scollname.Contains("refitted")) { - while (rcollname.Contains("refitted")) { - if ((rKey = (TKey*)iter_r())) rcollname = rKey->GetName(); - } - } - else if (scollname.Contains("refitted") && !rcollname.Contains("refitted")) { - while (scollname.Contains("refitted")) { - if ((sKey = (TKey*)iter_s())) scollname = sKey->GetName(); - } - } - - if ( (rcollname != scollname) && - (rcollname+"FS" != scollname) && - (rcollname != scollname+"FS") ) { - cout << " Different collection names, please check: " << rcollname - << " : " << scollname << endl; - continue; - } - else { - // cout << " The NEW collections: " << rcollname << " : " << scollname << endl; - myName = rKey->GetName(); - } - } - } - - // ==== Now let's go for the plotting... - // cout << ">> Comparing plots in " << myName << "..." << endl; - //cerr << ">> Comparing plots in " << myName << "..." << endl; - TString newDir("NEW_RELEASE/NEWSELECTION/NEW_LABEL/"); - newDir+=myName; - gSystem->mkdir(newDir,kTRUE); - - bool logyfalse [] = {false, false, false, false, false, false }; - bool doKolmo [] = {true, true, true, true, true, true }; - Double_t norm [] = {-999.,-999.,-999.,-999.,-999.,-999.}; - Double_t minx [] = {-1E100, -1E100, 5., 5., -1E100, -1E100 }; - Double_t maxx [] = {-1E100, -1E100, maxPT, maxPT, -1E100, -1E100 }; - Double_t miny [] = {0.5, -1E100, 0, -1E100, 0.5, -1E100 }; - Double_t maxy [] = {1.0125, -1E100, 1.025, -1E100, 1.0125, -1E100 }; - - ////////////////////////////////////// - /////////// CTF ////////////////////// - ////////////////////////////////////// - - - if (ctf) { - //===== building - - const char* plots0[] = {"effic_vs_eta", "fakerate_vs_eta", "effic_vs_pt", "fakerate_vs_pt"}; - const char* plotsl0[] = {"efficiency vs #eta", "fakerate vs #eta", "efficiency vs Pt", "fakerate vs Pt"}; - bool logy0 [] = {false, false, false, false }; - Plot4Histograms(newDir + "/building.pdf", - rdir, sdir, - rcollname, scollname, - "Seeds", "Efficiency Vs Pt and Vs #eta", - refLabel, newLabel, - plots0, plotsl0, - logy0, doKolmo, norm,0,minx,maxx,miny,maxy); - cout<<"HICE EL HISTO "<> Merging partial pdfs to " << mergefile << "..." << endl; -#ifdef DEBUG - cout << "DEBUG: ...with command \"" << gscommand << "\"" << endl; -#endif - gSystem->Exec(gscommand); - cout << ">> Moving " << mergefile << " to " << destfile << "..." << endl; - gSystem->Rename(mergefile, destfile); - - cout << ">> Deleting partial pdf files" << endl; - gSystem->Exec("rm -rf "+newDir); - cout << " ... Done" << endl; - } // end of "while loop" - - cout << ">> Removing the relval files from ROOT before closing..." << endl; - gROOT->GetListOfFiles()->Remove(sfile); - gROOT->GetListOfFiles()->Remove(rfile); - -#ifdef DEBUG - cout << "DEBUG: Exiting!" << endl; - cerr << "DEBUG: Exiting!" << endl; -#endif -} - diff --git a/Validation/RecoMuon/test/macro/RecoMuonValHistoPublisher.C b/Validation/RecoMuon/test/macro/RecoMuonValHistoPublisher.C index 7671dcd1ebd70..58560926973d0 100644 --- a/Validation/RecoMuon/test/macro/RecoMuonValHistoPublisher.C +++ b/Validation/RecoMuon/test/macro/RecoMuonValHistoPublisher.C @@ -1,7 +1,7 @@ #include #include #include "TMath.h" -#include "PlotHelpers.C" +#include "macro/PlotHelpers.C" ///// // Uncomment the following line to get more debuggin output @@ -74,6 +74,7 @@ void RecoMuonValHistoPublisher(const char* newFile="NEW_FILE",const char* refFil TKey* sKey = 0; TString rcollname; TString scollname; + while ( (rKey = (TKey*)iter_r()) ) { TString myName = rKey->GetName(); #ifdef DEBUG @@ -106,11 +107,16 @@ void RecoMuonValHistoPublisher(const char* newFile="NEW_FILE",const char* refFil //===== reco muon distributions: GLB - TString baseh = Form("RecoMuon_MuonAssoc_Glb%s/",fastSim); - const char* plots1 [] = {(baseh + "ErrPt").Data(), (baseh + "ErrP").Data(), - (baseh + "ErrPt_vs_Eta_Sigma").Data(), (baseh + "ErrPt_vs_Pt_Sigma").Data()}; - const char* plotst1[] = {"GlobalMuon(GLB) #Delta p_{T}/p_{T}", "GlobalMuon(GLB) #Delta p/p", - "GlobalMuon(GLB) #Delta p_{T}/p_{T} vs #sigma(#eta)", "GlobalMuon(GLB) #Delta p_{T}/p_{T} vs #sigma(p_{T})"}; + //TString baseh = Form("RecoMuon_MuonAssoc_Glb%s/",fastSim); + + const char* plots1[] = {"RecoMuon_MuonAssoc_Glb/ErrPt", + "RecoMuon_MuonAssoc_Glb/ErrP", + "RecoMuon_MuonAssoc_Glb/ErrPt_vs_Eta_Sigma", + "RecoMuon_MuonAssoc_Glb/ErrPt_vs_Pt_Sigma"}; + const char* plotst1[] = {"GlobalMuon(GLB) #Delta p_{T}/p_{T}", + "GlobalMuon(GLB) #Delta p/p", + "GlobalMuon(GLB) #Delta p_{T}/p_{T} vs #sigma(#eta)", + "GlobalMuon(GLB) #Delta p_{T}/p_{T} vs #sigma(p_{T})"}; Plot4Histograms(newDir + "/muonRecoGlb.pdf", rdir, sdir, rcollname, scollname, @@ -121,10 +127,14 @@ void RecoMuonValHistoPublisher(const char* newFile="NEW_FILE",const char* refFil //==== efficiencies and fractions GLB - const char* plots2 [] = {(baseh + "EffP").Data(), (baseh + "EffEta").Data(), - (baseh + "FractP").Data(), (baseh + "FractEta").Data()}; - const char* plotst2[] = {"GlobalMuon(GLB) #epsilon vs. p", "GlobalMuon(GLB) #epsilon vs. #eta", - "GlobalMuon(GLB) fraction vs. p", "GlobalMuon(GLB) fraction vs. #eta"}; + const char* plots2 [] = {"RecoMuon_MuonAssoc_Glb/EffP", + "RecoMuon_MuonAssoc_Glb/EffEta", + "RecoMuon_MuonAssoc_Glb/FractP", + "RecoMuon_MuonAssoc_Glb/FractEta"}; + const char* plotst2[] = {"GlobalMuon(GLB) #epsilon vs. p", + "GlobalMuon(GLB) #epsilon vs. #eta", + "GlobalMuon(GLB) fraction vs. p", + "GlobalMuon(GLB) fraction vs. #eta"}; Double_t minx1 [] = {5., -1E100, 5., -1E100, -1E100, -1E100 }; Double_t maxx1 [] = {maxPT, -1E100,maxPT, -1E100, -1E100, -1E100 }; Double_t norm2 [] = {-999.,-999.,-999.,-999.,-999.,-999.}; //Normalize to first histogram @@ -167,11 +177,15 @@ void RecoMuonValHistoPublisher(const char* newFile="NEW_FILE",const char* refFil */ //===== reco muon distributions: STA - baseh = Form("RecoMuon_MuonAssoc_Sta%s/",fastSim); - const char* plots5 [] = {(baseh + "ErrPt").Data(), (baseh + "ErrP").Data(), - (baseh + "ErrPt_vs_Eta_Sigma").Data(), (baseh + "ErrPt_vs_Pt_Sigma").Data()}; - const char* plotst5[] = {"StandAloneMuon(STA) #Delta p_{T}/p_{T}", "StandAloneMuon(STA) #Delta p/p", - "StandAloneMuon(STA) #Delta p_{T}/p_{T} vs #sigma(#eta)", "StandAloneMuon(STA) #Delta p_{T}/p_{T} vs #sigma(p_{T})"}; + //baseh = Form("RecoMuon_MuonAssoc_Sta%s/",fastSim); + const char* plots5 [] = {"RecoMuon_MuonAssoc_Sta/ErrPt", + "RecoMuon_MuonAssoc_Sta/ErrP", + "RecoMuon_MuonAssoc_Sta/ErrPt_vs_Eta_Sigma", + "RecoMuon_MuonAssoc_Sta/ErrPt_vs_Pt_Sigma"}; + const char* plotst5[] = {"StandAloneMuon(STA) #Delta p_{T}/p_{T}", + "StandAloneMuon(STA) #Delta p/p", + "StandAloneMuon(STA) #Delta p_{T}/p_{T} vs #sigma(#eta)", + "StandAloneMuon(STA) #Delta p_{T}/p_{T} vs #sigma(p_{T})"}; Plot4Histograms(newDir + "/muonRecoSta.pdf", rdir, sdir, rcollname, scollname, @@ -183,10 +197,14 @@ void RecoMuonValHistoPublisher(const char* newFile="NEW_FILE",const char* refFil //==== efficiencies and fractions STA - const char* plots6 [] = {(baseh + "EffP").Data(), (baseh + "EffEta").Data(), - (baseh + "FractP").Data(), (baseh + "FractEta").Data()}; - const char* plotst6[] = {"StandAloneMuon(STA) #epsilon vs. p", "StandAloneMuon(STA) #epsilon vs. #eta", - "StandAloneMuon(STA) fraction vs. p", "StandAloneMuon(STA) fraction vs. #eta"}; + const char* plots6 [] = {"RecoMuon_MuonAssoc_Sta/EffP", + "RecoMuon_MuonAssoc_Sta/EffEta", + "RecoMuon_MuonAssoc_Sta/FractP", + "RecoMuon_MuonAssoc_Sta/FractEta"}; + const char* plotst6[] = {"StandAloneMuon(STA) #epsilon vs. p", + "StandAloneMuon(STA) #epsilon vs. #eta", + "StandAloneMuon(STA) fraction vs. p", + "StandAloneMuon(STA) fraction vs. #eta"}; Plot4Histograms(newDir + "/muonRecoStaEff.pdf", rdir, sdir, rcollname, scollname, @@ -198,11 +216,15 @@ void RecoMuonValHistoPublisher(const char* newFile="NEW_FILE",const char* refFil //===== reco muon distributions: TRK - baseh = Form("RecoMuon_MuonAssoc_Trk%s/",fastSim); - const char* plots7 [] = {(baseh + "ErrPt").Data(), (baseh + "ErrP").Data(), - (baseh + "ErrPt_vs_Eta_Sigma").Data(), (baseh + "ErrPt_vs_Pt_Sigma").Data()}; - const char* plotst7[] = {"TrackerMuon(TRK) #Delta p_{T}/p_{T}", "TrackerMuon(TRK) #Delta p/p", - "TrackerMuon(TRK) #Delta p_{T}/p_{T} vs #sigma(#eta)", "TrackerMuon(TRK) #Delta p_{T}/p_{T} vs #sigma(p_{T})"}; + //baseh = Form("RecoMuon_MuonAssoc_Trk%s/",fastSim); + const char* plots7 [] = {"RecoMuon_MuonAssoc_Trk/ErrPt", + "RecoMuon_MuonAssoc_Trk/ErrP", + "RecoMuon_MuonAssoc_Trk/ErrPt_vs_Eta_Sigma", + "RecoMuon_MuonAssoc_Trk/ErrPt_vs_Pt_Sigma"}; + const char* plotst7[] = {"TrackerMuon(TRK) #Delta p_{T}/p_{T}", + "TrackerMuon(TRK) #Delta p/p", + "TrackerMuon(TRK) #Delta p_{T}/p_{T} vs #sigma(#eta)", + "TrackerMuon(TRK) #Delta p_{T}/p_{T} vs #sigma(p_{T})"}; Plot4Histograms(newDir + "/muonRecoTrk.pdf", rdir, sdir, rcollname, scollname, @@ -214,10 +236,14 @@ void RecoMuonValHistoPublisher(const char* newFile="NEW_FILE",const char* refFil //==== efficiencies and fractions TRK - const char* plots8 [] = {(baseh + "EffP").Data(), (baseh + "EffEta").Data(), - (baseh + "FractP").Data(), (baseh + "FractEta").Data()}; - const char* plotst8[] = {"TrackerMuon(TRK) #epsilon vs. p", "TrackerMuon(TRK) #epsilon vs. #eta", - "TrackerMuon(TRK) fraction vs. p", "TrackerMuon(TRK) fraction vs. #eta"}; + const char* plots8 [] = {"RecoMuon_MuonAssoc_Trk/EffP", + "RecoMuon_MuonAssoc_Trk/EffEta", + "RecoMuon_MuonAssoc_Trk/FractP", + "RecoMuon_MuonAssoc_Trk/FractEta"}; + const char* plotst8[] = {"TrackerMuon(TRK) #epsilon vs. p", + "TrackerMuon(TRK) #epsilon vs. #eta", + "TrackerMuon(TRK) fraction vs. p", + "TrackerMuon(TRK) fraction vs. #eta"}; Plot4Histograms(newDir + "/muonRecoTrkEff.pdf", rdir, sdir, rcollname, scollname, @@ -230,11 +256,15 @@ void RecoMuonValHistoPublisher(const char* newFile="NEW_FILE",const char* refFil // //===== reco muon distributions: Tight Muons // - baseh = Form("RecoMuon_MuonAssoc_Tgt%s/",fastSim); - const char* plots9 [] = {(baseh + "ErrPt").Data(), (baseh + "ErrP").Data(), - (baseh + "ErrPt_vs_Eta_Sigma").Data(), (baseh + "ErrPt_vs_Pt_Sigma").Data()}; - const char* plotst9[] = {"Tight Muon #Delta p_{T}/p_{T}", "Tight Muon #Delta p/p", - "Tight Muon #Delta p_{T}/p_{T} vs #sigma(#eta)", "Tight Muon #Delta p_{T}/p_{T} vs #sigma(p_{T})"}; + //baseh = Form("RecoMuon_MuonAssoc_Tgt%s/",fastSim); + const char* plots9 [] = {"RecoMuon_MuonAssoc_Tgt/ErrPt", + "RecoMuon_MuonAssoc_Tgt/ErrP", + "RecoMuon_MuonAssoc_Tgt/ErrPt_vs_Eta_Sigma", + "RecoMuon_MuonAssoc_Tgt/ErrPt_vs_Pt_Sigma"}; + const char* plotst9[] = {"Tight Muon #Delta p_{T}/p_{T}", + "Tight Muon #Delta p/p", + "Tight Muon #Delta p_{T}/p_{T} vs #sigma(#eta)", + "Tight Muon #Delta p_{T}/p_{T} vs #sigma(p_{T})"}; Plot4Histograms(newDir + "/muonRecoTgt.pdf", rdir, sdir, rcollname, scollname, @@ -246,10 +276,14 @@ void RecoMuonValHistoPublisher(const char* newFile="NEW_FILE",const char* refFil //==== efficiencies and fractions Tight Muons - const char* plots10 [] = {(baseh + "EffP").Data(), (baseh + "EffEta").Data(), - (baseh + "FractP").Data(), (baseh + "FractEta").Data()}; - const char* plotst10[] = {"Tight Muon #epsilon vs. p", "Tight Muon #epsilon vs. #eta", - "Tight Muon fraction vs. p", "Tight Muon fraction vs. #eta"}; + const char* plots10 [] = {"RecoMuon_MuonAssoc_Tgt/EffP", + "RecoMuon_MuonAssoc_Tgt/EffEta", + "RecoMuon_MuonAssoc_Tgt/FractP", + "RecoMuon_MuonAssoc_Tgt/FractEta"}; + const char* plotst10[] = {"Tight Muon #epsilon vs. p", + "Tight Muon #epsilon vs. #eta", + "Tight Muon fraction vs. p", + "Tight Muon fraction vs. #eta"}; Plot4Histograms(newDir + "/muonRecoTgtEff.pdf", rdir, sdir, rcollname, scollname, diff --git a/Validation/RecoMuon/test/macro/RecoValHistoPublisher.C b/Validation/RecoMuon/test/macro/RecoValHistoPublisher.C index 3c7703a5db6e2..ae98628c0679a 100644 --- a/Validation/RecoMuon/test/macro/RecoValHistoPublisher.C +++ b/Validation/RecoMuon/test/macro/RecoValHistoPublisher.C @@ -1,7 +1,7 @@ #include #include #include "TMath.h" -#include "PlotHelpers.C" +#include "macro/PlotHelpers.C" // Uncomment the following line for some extra debug information // #define DEBUG diff --git a/Validation/RecoMuon/test/macro/SeedValHistoPublisher.C b/Validation/RecoMuon/test/macro/SeedValHistoPublisher.C index 5912a0a5b884e..6ba156da72ce8 100644 --- a/Validation/RecoMuon/test/macro/SeedValHistoPublisher.C +++ b/Validation/RecoMuon/test/macro/SeedValHistoPublisher.C @@ -1,7 +1,7 @@ #include #include #include "TMath.h" -#include "PlotHelpers.C" +#include "macro/PlotHelpers.C" //Uncomment the following line to get some more output diff --git a/Validation/RecoMuon/test/macro/TrackValHistoPublisher.C b/Validation/RecoMuon/test/macro/TrackValHistoPublisher.C index bd840d9e76a67..061295e903563 100644 --- a/Validation/RecoMuon/test/macro/TrackValHistoPublisher.C +++ b/Validation/RecoMuon/test/macro/TrackValHistoPublisher.C @@ -1,7 +1,7 @@ #include #include #include "TMath.h" -#include "PlotHelpers.C" +#include "macro/PlotHelpers.C" //Uncomment the following line to get some more output diff --git a/Validation/RecoMuon/test/macro/new_PlotHelpers.C b/Validation/RecoMuon/test/macro/new_PlotHelpers.C new file mode 100644 index 0000000000000..558bbc62dd54c --- /dev/null +++ b/Validation/RecoMuon/test/macro/new_PlotHelpers.C @@ -0,0 +1,663 @@ +//////////////////////////////////////////////////////////// +// +// A group of helper functions used to compare histograms +// and profiles between two different releases +// +//////////////////////////////////////////////////////////// + +#include "TH1F.h" +#include "TProfile.h" +#include "TCanvas.h" +#include "TMath.h" +#include "TPad.h" +#include "TPaveLabel.h" +#include + +void NormalizeHistogramsToFirst(TH1* h1, TH1* h2); +void NormalizeHistogramsToOne(TH1* h1, TH1* h2); +void NormalizeHistogramsAsDensity(TH1* h1, TH1* h2); + +// debugging printouts +bool DEBUGP = false; + +//////////////////////////////////////////////////////////// +// +// Sets the global style for the whole system. +// +// Note: There might be redundancies in other places so +// things can be further simplified +// +void SetGlobalStyle() { + gROOT->SetStyle("Plain"); + gStyle->SetPadGridX(kTRUE); + gStyle->SetPadGridY(kTRUE); + gStyle->SetPadRightMargin(0.07); + gStyle->SetPadLeftMargin(0.13); + //gStyle->SetTitleXSize(0.07); + //gStyle->SetTitleXOffset(0.6); + //tyle->SetTitleYSize(0.3); + //gStyle->SetLabelSize(0.6) + //gStyle->SetTextSize(0.5); +} +// +//////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +// +// This function sets the style for a given histogram +// +// Note: There might be redundancies in other places so +// things can be further simplified +// +void SetHistogramStyle(TH1* h, Style_t mstyle, Color_t color, Size_t msize = 0.7, Width_t lwidth = 2, + Float_t tsize = 0.05, Float_t toffset = 1.2) { + if (!h) + return; + h->SetMarkerStyle(mstyle); + h->SetMarkerColor(color); + h->SetMarkerSize(msize); + h->SetLineColor(color); + h->SetLineWidth(lwidth); + h->GetYaxis()->SetTitleSize(tsize); + h->GetYaxis()->SetTitleOffset(toffset); +} +// +//////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +// +// This function finds the list of TDirectories in a branch +// that match a given string + +TList* GetListOfDirectories(TDirectory* dir, const char* match = 0) { + TIter nextkey(dir->GetListOfKeys()); + TList* sl = new TList(); + TKey* key = 0; + TKey* oldkey = 0; + + while (( key = (TKey*)nextkey() )) { + TObject *obj = key->ReadObj(); + if ( obj->IsA()->InheritsFrom( "TDirectory" ) ) { + TString theName = obj->GetName(); + if (!match) { + cout << " -> " << theName << endl; + sl->Add(obj); + } + else if (theName.Contains(match)) { + cout << " -> " << theName << endl; + sl->Add(obj); + } + } + } // End of while + + return sl; +} + +//////////////////////////////////////////////////////////// +// +// This function goes to the right branch inside the file +// looking for branches having branchContent. +// It returns a list with all those branches, +// +TList* getListOfBranches(const char* dataType, TFile* file, const char* branchContent) { + + if (TString(dataType) == "RECO") { + if(! file->cd("DQMData/Run 1/Muons/Run summary")) { + cout << "ERROR: Muon Histos for " << dataType << " not found" << endl; + return 0; + } + } + else { + cout << "ERROR: Data type " << dataType << " not allowed: only RECO is considered" << endl; + return 0; + } + + TDirectory * dir=gDirectory; + TList* sl = GetListOfDirectories(dir, branchContent); + + if (sl->GetSize() == 0) { + cout << "ERROR: No DQM muon reco histos found in NEW file " << endl; + delete sl; + return 0; + } + + return sl; +} +// +//////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +// +// This function performs a compatibility test between two +// histogram based on the Kolmogorov-Smirnof algorithm. It +// also prints the value in a TPaveLabel at the upper-right +// corner. +// The return value contains the result of the test +// +double KolmogorovTest(TH1 *h1, TH1 *h2){ + + double mya_array[1300], myb_array[1300]; + vector mya; + vector myb; + + + for (int i=0; iGetNbinsX(); i++){ + mya.push_back(h1->GetBinContent(i+1)); + myb.push_back(h2->GetBinContent(i+1)); + } + + sort(mya.begin(),mya.end()); + sort(myb.begin(),myb.end()); + copy(mya.begin(),mya.end(),mya_array); + copy(myb.begin(),myb.end(),myb_array); + + const int nbinsa = h1->GetNbinsX(); + const int nbinsb = h2->GetNbinsX(); + + double kstest = TMath::KolmogorovTest(nbinsa, mya_array, + nbinsb, myb_array, + "UOX"); + if (DEBUGP) cout << " + KS value = " << kstest << endl; + + // Create text with the value + TString legend = Form("KS=%4.2f", kstest); + + // Create a pave text to put the value inside + + TPaveLabel* pl = new TPaveLabel(0.79,0.91,0.93,0.96, legend.Data(), "NDC"); + + // Tune style + //pl->SetTextSize(0.04); + pl->SetLineColor(41); + pl->SetLineWidth(1); + pl->SetLineStyle(1); + pl->SetFillColor(41); + pl->SetBorderSize(3); + + if (kstest < 0.7) + pl->SetTextColor(kRed); + + pl->Draw(); + + return kstest; +} +// +//////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +// +// This function draws the stat box for the two plots +// +void setStats(TH1* s, TH1* r, double startingY, double startingX = .1, bool fit = false){ + if (startingY<0){ + s->SetStats(0); + r->SetStats(0); + } + else { + //gStyle->SetOptStat(1001); + + if (fit){ + s->Fit("gaus"); + TF1* f1 = (TF1*) s->GetListOfFunctions()->FindObject("gaus"); + if (f1) { + f1->SetLineColor(2); + f1->SetLineWidth(1); + } + } + s->Draw(); + gPad->Update(); + TPaveStats* st1 = (TPaveStats*) s->GetListOfFunctions()->FindObject("stats"); + if (st1) { + if (fit) {st1->SetOptFit(0010); st1->SetOptStat(1001);} + st1->SetX1NDC(startingX); + st1->SetX2NDC(startingX+0.30); + st1->SetY1NDC(startingY+0.20); + st1->SetY2NDC(startingY+0.35); + st1->SetTextColor(2); + } + else s->SetStats(0); + if (fit) { + r->Fit("gaus"); + TF1* f2 = (TF1*) r->GetListOfFunctions()->FindObject("gaus"); + if (f2) { + f2->SetLineColor(4); + f2->SetLineWidth(1); + } + } + r->Draw(); + gPad->Update(); + TPaveStats* st2 = (TPaveStats*) r->GetListOfFunctions()->FindObject("stats"); + if (st2) { + if (fit) {st2->SetOptFit(0010); st2->SetOptStat(1001);} + st2->SetX1NDC(startingX); + st2->SetX2NDC(startingX+0.30); + st2->SetY1NDC(startingY); + st2->SetY2NDC(startingY+0.15); + st2->SetTextColor(4); + } + else r->SetStats(0); + } +} +// +//////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +// +// Plot a page with several histograms +// +void PlotNHistograms(const TString& pdfFile, + TDirectory* rdir, TDirectory* sdir, + const TString& rcollname, const TString& scollname, + const char* canvasName, const char* canvasTitle, + const TString& refLabel, const TString& newLabel, + unsigned int nhistos, const TString* hnames, + const TString* htitles, const char** drawopt, + bool* logy = 0, bool* logx = 0, bool* doKolmo = 0, Double_t* norm = 0, + Double_t* minx = 0, Double_t* maxx = 0, + Double_t* miny = 0, Double_t* maxy = 0) { + + if (DEBUGP) { + cout << " + Plotting histograms for " << canvasTitle << endl; + cerr << " + Plotting histograms for " << canvasTitle << endl; + } + + TH1* rh = 0; + TH1* sh = 0; + + TCanvas* canvas = 0; + if (nhistos >4) + canvas = new TCanvas(canvasName, canvasTitle, 1000, 1400); + else + canvas = new TCanvas(canvasName, canvasTitle, 1000, 1050); + + canvas->Draw(); + canvas->Divide(2,(nhistos+1)/2); //This way we print in 2 columns + + for (unsigned int i = 0; i < nhistos; i++) { + + if (DEBUGP) cout << " [" << i << "] histogram name: " << flush << hnames[i] << endl; + + //draw option for the new histogram + TString drawoption = drawopt[i]; + + // Skip histogram if no name is provided + if (hnames[i] == "") continue; + + // Get Histograms + // + Reference release + rdir->cd(rcollname); + + if (DEBUGP) cout << " Getting object for reference sample " << (rcollname + "/" + hnames[i]) << endl; + + rdir->GetObject(rcollname + "/" + hnames[i], rh); + if (! rh) { + cout << "WARNING: Could not find a reference histogram or profile named " << hnames[i] + << " in " << rdir->GetName() << endl; + cout << " Skipping" << endl; + continue; + } + + //If it is a 2D project it in Y... is this what we always want? + if (TString(rh->IsA()->GetName()) == "TH2F") { + + if (DEBUGP) cout << " It is a TH2F object... project in Y!" << endl; + + TH1* proj = ((TH2F*) rh)->ProjectionY(); + rh = proj; + } + + // + New release + sdir->cd(scollname); + + if (DEBUGP) cout << " Getting object for target sample " << (scollname + "/" + hnames[i]) << endl; + + sdir->GetObject(scollname + "/" + hnames[i], sh); + if (! sh) { + cout << "WARNING: Could not find a signal histogram or profile named " << hnames[i] + << " in " << sdir->GetName() << endl; + cout << " Skipping" << endl; + continue; + } + + //If it is a 2D project it in Y... is this what we always want? + if (TString(sh->IsA()->GetName()) == "TH2F") { + + if (DEBUGP) cout << hnames[i] << " is a TH2F object... project in Y!" << endl; + + TH1* proj = ((TH2F*) sh)->ProjectionY(); + sh = proj; + } + + // Set styles + + if (DEBUGP) cout << " Setting style..." << endl; + + SetHistogramStyle(rh, 21, 4); + SetHistogramStyle(sh, 20, 2); + + //Change titles + if (htitles) { + rh->SetTitle(htitles[i]); + sh->SetTitle(htitles[i]); + rh->GetYaxis()->SetTitle(htitles[i]); + sh->GetYaxis()->SetTitle(htitles[i]); + } + + // SET X AXIS RANGE in plots + Bool_t ChangeXRange = false ; + Double_t Xleft = rh->GetXaxis()->GetXmin(); + Double_t Xright = rh->GetXaxis()->GetXmax(); + + if (DEBUGP) cout << "ref histo Xleft, Xright = "<< Xleft << ", "<< Xright << endl; + + if (sh->GetXaxis()->GetXmin() < rh->GetXaxis()->GetXmin()) { + Xleft = sh->GetXaxis()->GetXmin(); + ChangeXRange = true; + if (DEBUGP) cout << "automatic reset MIN (new < ref) Xleft = "<< Xleft << endl; + } + if (sh->GetXaxis()->GetXmax() > rh->GetXaxis()->GetXmax()) { + Xright = sh->GetXaxis()->GetXmax(); + ChangeXRange = true; + if (DEBUGP) cout << "automatic reset MAX (new > ref) Xright = "<< Xright << endl; + } + + if (minx[i]!=0) { + ChangeXRange = true ; + Xleft = minx[i]; + if (DEBUGP) cout << "user reset Xleft = "<< Xleft << endl; + } + + if (maxx[i]!=0) { + ChangeXRange = true ; + Xright = maxx[i]; + if (DEBUGP) cout << "user reset Xright = "<< Xleft << endl; + } + + if (ChangeXRange) { + if (DEBUGP) { + cout << "Ref histo Xmin, Xmax = "<< rh->GetXaxis()->GetXmin() << ", " << rh->GetXaxis()->GetXmax() <GetXaxis()->GetXmax() <GetXaxis()->SetRangeUser(Xleft,Xright); + sh->GetXaxis()->SetRangeUser(Xleft,Xright); + + if (DEBUGP) { + cout << "reset Ref histo Xmin, Xmax = "<< rh->GetXaxis()->GetXmin() << ", " << rh->GetXaxis()->GetXmax() <GetXaxis()->GetXmax() <GetMinimum(0.); // min value larger than zero + Double_t ymins = sh->GetMinimum(0.); + Ybottom = yminr < ymins ? yminr*0.5 : ymins*0.5; + if (DEBUGP) cout << "LOG scale, yminr, ymins: "<> Ybottom = "<GetMinimum(); // min value larger than zero + Double_t ymins = sh->GetMinimum(); + Ybottom = yminr < ymins ? yminr-0.1*abs(yminr) : ymins-0.1*abs(ymins) ; + // limit the scale to -1,+1 for relative pt bias to avoid failing fits + if ((hnames[i] == "ptres_vs_eta_Mean") && (Ybottom <-1.)) Ybottom = -1.; + if ((hnames[i] == "ptres_vs_pt_Mean") && (Ybottom <-1.)) Ybottom = -1.; + if (DEBUGP) cout << "LIN scale, yminr, ymins: "<> Ybottom = "<GetMaximum(); // max value + Double_t ymaxs = sh->GetMaximum(); + Ytop = ymaxr > ymaxs ? ymaxr : ymaxs ; + // automatic setting for log scale + if (logy[i]) { + Ytop = Ytop*2; + if (DEBUGP) cout << "LOG scale, ymaxr, ymaxs: "<> Ytop = "<1.)) Ytop = 1.; + if ((hnames[i] == "ptres_vs_pt_Mean") && (Ytop >1.)) Ytop = 1.; + if (DEBUGP) cout << "LIN scale, ymaxr, ymaxs: "<> Ytop = "<GetYaxis()->SetRangeUser(Ybottom,Ytop); + sh->GetYaxis()->SetRangeUser(Ybottom,Ytop); + // +++++++++++++++++++++++++++++++++++++++++ + + // Move to subpad + canvas->cd(i+1); + + // Check Logy + if (logy[i]) gPad->SetLogy(); + if (logx[i]) gPad->SetLogx(); + + // Set stat boxes + + if (DEBUGP) cout << " Setting statistics..." << endl; + setStats(sh, rh, -1, 0, false); + + // /////////// DRAW histograms ////////////////////////////////////// + // + // FIRST plot: reference (blue) SECOND plot: new (red) + if (DEBUGP) cout << " Drawing histograms..." << endl; + + if (ChangeXRange) { + sh->Draw(drawoption); + rh->Draw("same"+drawoption); + sh->Draw("same"+drawoption); + } + else { + rh->Draw(drawoption); + sh->Draw("same"+drawoption); + } + + // Perform Kolmogorov test if needed + if (doKolmo) { + if (doKolmo[i]) { + if (DEBUGP) cout << " Performing Kolmogorov test..." << endl; + // TPad* c1_1 = canvas->GetPad(i+1); + double kstest = KolmogorovTest(sh,rh); + if(kstest<0.7) + gPad->SetFillColor(kBlue-10); + } + } + } // End loop + + // Draw Legend + + if (DEBUGP) cout << " Drawing legend..." << endl; + + canvas->cd(); + + TLegend* l = 0; + if (nhistos > 4) + l = new TLegend(0.20,0.665,0.80,0.685); + else + l = new TLegend(0.20,0.50,0.80,0.53); + + l->SetTextSize(0.011); + l->SetLineColor(1); + l->SetLineWidth(1); + l->SetLineStyle(1); + l->SetFillColor(0); + l->SetBorderSize(2); + l->AddEntry(rh,refLabel,"LPF"); + l->AddEntry(sh,newLabel,"LPF"); + l->Draw(); + + // Print Canvas + canvas->Print(pdfFile); + + // Clean memory + // delete l; + delete canvas; + if (DEBUGP) cout << " ... plotted histograms for " << canvasTitle << endl; +} +// +//////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////// +// +// Plot a page with 4 histograms +// +void Plot4Histograms(const TString& pdfFile, + TDirectory* rdir, TDirectory* sdir, + const TString& rcollname, const TString& scollname, + const char* canvasName, const char* canvasTitle, + const TString& refLabel, const TString& newLabel, + const TString* hnames, const TString* htitles, const char** drawopt, + bool* logy = 0, bool* logx = 0, bool* doKolmo = 0, Double_t* norm = 0, + Double_t* minx = 0, Double_t* maxx = 0, + Double_t* miny = 0, Double_t* maxy = 0) { + PlotNHistograms(pdfFile, + rdir, sdir, + rcollname, scollname, + canvasName, canvasTitle, + refLabel, newLabel, + 4, hnames, htitles, drawopt, + logy, logx, doKolmo, norm, minx, maxx, miny, maxy); + +} +// +//////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////// +// +// Plot a page with 6 histograms +// +void Plot6Histograms(const TString& pdfFile, + TDirectory* rdir, TDirectory* sdir, + const TString& rcollname, const TString& scollname, + const char* canvasName, const char* canvasTitle, + const TString& refLabel, const TString& newLabel, + const TString* hnames, const TString* htitles, const char** drawopt, + bool* logy = 0, bool* logx = 0, bool* doKolmo = 0, Double_t* norm = 0, + Double_t* minx = 0, Double_t* maxx = 0, + Double_t* miny = 0, Double_t* maxy = 0) { + + + PlotNHistograms(pdfFile, + rdir, sdir, + rcollname, scollname, + canvasName, canvasTitle, + refLabel, newLabel, + 6, hnames, htitles, drawopt, + logy, logx, doKolmo, norm, + minx, maxx, + miny, maxy); +} +// +//////////////////////////////////////////////////////////// + +void Plot5Histograms(const TString& pdfFile, + TDirectory* rdir, TDirectory* sdir, + const TString& rcollname, const TString& scollname, + const char* canvasName, const char* canvasTitle, + const TString& refLabel, const TString& newLabel, + const TString* hnames, const TString* htitles, const char** drawopt, + bool* logy = 0, bool* logx = 0, bool* doKolmo = 0, Double_t* norm = 0, + Double_t* minx = 0, Double_t* maxx = 0, + Double_t* miny = 0, Double_t* maxy = 0) { + + + PlotNHistograms(pdfFile, + rdir, sdir, + rcollname, scollname, + canvasName, canvasTitle, + refLabel, newLabel, + 5, hnames, htitles, drawopt, + logy, logx, doKolmo, norm, + minx, maxx, + miny, maxy); +} +// +//////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////// +// +// Normalize the two histograms to the entries on the first histogram +// +void NormalizeHistogramsToFirst(TH1* h1, TH1* h2) { + if (h1==0 || h2==0) return; + + if ( h1->Integral() > 0 && h2->Integral() > 0 ){ + Double_t scale2 = h1->Integral()/h2->Integral(); + h2->Scale(scale2); + } +} +// +//////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////// +// +// Normalize the two histograms to unity +// +void NormalizeHistogramsToOne(TH1* h1, TH1* h2) { + if (!h1 || !h2) return; + + if ( h1->Integral() != 0 && h2->Integral() != 0 ) { + Double_t scale1 = 1.0/h1->Integral(); + Double_t scale2 = 1.0/h2->Integral(); + h1->Scale(scale1); + h2->Scale(scale2); + } +} +// +//////////////////////////////////////////////////////////// + +// Normalize the two histograms as probability density functions: +// Normalize areas to unity and consider the bin width +// +void NormalizeHistogramsAsDensity(TH1* h1, TH1* h2) { + if (h1==0 || h2==0) return; + if (h1->Integral() != 0 && h2->Integral() != 0 ) { + Double_t scale1 = 1.0/h1->Integral(); + Double_t scale2 = 1.0/h2->Integral(); + h1->Scale(scale1, "width"); + h2->Scale(scale2, "width"); + } +} diff --git a/Validation/RecoMuon/test/macro/new_TrackValHistoPublisher.C b/Validation/RecoMuon/test/macro/new_TrackValHistoPublisher.C new file mode 100644 index 0000000000000..11b9d44edd9e2 --- /dev/null +++ b/Validation/RecoMuon/test/macro/new_TrackValHistoPublisher.C @@ -0,0 +1,667 @@ +#include +#include +#include "TMath.h" +#include "macro/new_PlotHelpers.C" + +// debugging printouts +bool DEBUG = false; + +TList* GetListOfBranches(const char* dataType, TFile* file) { + if (TString(dataType) == "HLT") { + file->cd("DQMData/Run 1/HLT/Run summary/Muon/MuonTrack"); + } + else if (TString(dataType) == "RECO") { + file->cd("DQMData/Run 1/Muons/Run summary/RecoMuonV/MuonTrack"); + } + else { + cout << "ERROR: Data type " << dataType << " not allowed: only RECO and HLT are considered" << endl; + cerr << "ERROR: Data type " << dataType << " not allowed: only RECO and HLT are considered" << endl; + return 0; + } + + TDirectory * dir=gDirectory; + TList* sl = GetListOfDirectories(dir); + + if (sl->GetSize() == 0) { + cout << "ERROR: No DQM muon reco histos found in NEW file " << endl; + cerr << "ERROR: No DQM muon reco histos found in NEW file " << endl; + delete sl; + return 0; + } + + return sl; +} + +void plotOptReset(bool logx[6], bool logy[6], bool doKolmo[6], Double_t norm[6], + Double_t minx[6], Double_t maxx[6], Double_t miny[6], Double_t maxy[6], const char* drawopt[6], + TString plots[6], TString titles[6]) { + + for(int i=0; i<6; ++i) { + logx[i] = false; + logy[i] = false; + doKolmo[i] = false; + norm[i] = -1; + minx[i] = 0; + maxx[i] = 0; + miny[i] = 0; + maxy[i] = 0; + drawopt[i] = ""; + plots[i] = ""; + titles[i] = ""; + } +} + +void new_TrackValHistoPublisher(const char* newFile="NEW_FILE",const char* refFile="REF_FILE") { + + cout << ">> Starting new_TrackValHistoPublisher(" + << newFile << "," << refFile << ")..." << endl; + + //==== To be replaced from python ==================== + + const char* dataType = "DATATYPE"; + const char* refLabel("REF_LABEL, REF_RELEASE REFSELECTION"); + const char* newLabel("NEW_LABEL, NEW_RELEASE NEWSELECTION"); + + + // ==== Initial settings and loads + gROOT ->SetBatch(); + gErrorIgnoreLevel = kWarning; // Get rid of the info messages + SetGlobalStyle(); + + // ==== Some cleaning... is this needed? + delete gROOT->GetListOfFiles()->FindObject(refFile); + delete gROOT->GetListOfFiles()->FindObject(newFile); + + // ==== Opening files, moving to the right branch and getting the list of sub-branches + cout << ">> Opening files, moving to the right branch and getting the list of sub-branches..." << endl; + + cout << ">> Finding new DQM file ..." << endl; + TFile * sfile = new TFile(newFile); + TList* sl = GetListOfBranches(dataType, sfile); + + if (!sl) { + cout << "ERROR: Could not find keys!!!" << endl; + cerr << "ERROR: Could not find keys!!!" << endl; + return; + } + TDirectory* sdir = gDirectory; + + if (DEBUG) { + for (unsigned int i = 0; i < sl->GetEntries(); i++) + cout << " + " << sl->At(i)->GetName() << endl; + } + + cout << ">> Finding reference DQM file ..." << endl; + TFile * rfile = new TFile(refFile); + TList* rl = GetListOfBranches(dataType, rfile); + + if (!rl) { + cout << "ERROR: Could not find keys!!!" << endl; + cerr << "ERROR: Could not find keys!!!" << endl; + return; + } + TDirectory* rdir = gDirectory; + + if (DEBUG) { + for (unsigned int i = 0; i < rl->GetEntries(); i++) + cout << " + " << rl->At(i)->GetName() << endl; + } + + //==== Iterate now over histograms and collections + cout << ">> Iterating over histograms and collections..." << endl; + + bool logy[6] = {false, false, false, false, false, false }; + bool logx[6] = {false, false, false, false, false, false }; + bool doKolmo[6] = {false, false, false, false, false, false }; + Double_t norm[6] = {-1.,-1.,-1.,-1.,-1.,-1.}; // initial default: do not normalize + Double_t minx[6] = {0, 0, 0, 0, 0, 0}; + Double_t maxx[6] = {0, 0, 0, 0, 0, 0}; + Double_t miny[6] = {0, 0, 0, 0, 0, 0}; + Double_t maxy[6] = {0, 0, 0, 0, 0, 0}; + const char* drawopt[6] = {"", "", "", "", "", ""}; + TString plots[6] = {"", "", "", "", "", ""}; + TString titles[6] = {"", "", "", "", "", ""}; + + TString rcollname; + TString scollname; + TIter iter_r( rl ); + TIter iter_s( sl ); + TString newDirBase("NEW_RELEASE/NEWSELECTION/NEW_LABEL/"); + TKey* rKey = 0; + + // before CMSSW_10_1_0_pre1 a few collection names were different + bool NEWcollNames = false; + TString Ref_CMSSW_Release("REF_RELEASE"); + if (Ref_CMSSW_Release.Contains("CMSSW_9") || Ref_CMSSW_Release.Contains("CMSSW_10_0")) NEWcollNames=true; + + while ( (rKey = (TKey*)iter_r()) ) { + TString myName = rKey->GetName(); + rcollname = myName; + if (DEBUG) { + cout << " Checking collection: " << myName << endl; + cerr << " Checking collection: " << myName << endl; + } + + TString myName2 = myName; + if (NEWcollNames) { + if (myName=="NEWprobeTrks") myName2="probeTrks"; + else if (myName=="NEWprobeTrks_TkAsso") myName2="probeTrks_TkAsso"; + else if (myName=="NEWseedsOfSTAmuons") myName2="seedsOfSTAmuons"; + else if (myName=="NEWseedsOfDisplacedSTAmuons") myName2="seedsOfDisplacedSTAmuons"; + else if (myName=="NEWcutsRecoTrkMuons") myName2="cutsRecoTrkMuons"; + else if (myName=="NEWextractGemMuons") myName2="extractGemMuons"; + else if (myName=="NEWextractMe0Muons") myName2="extractMe0Muons"; + } + scollname = myName2; + + if (DEBUG) { + cout << " Comparing " << rcollname << " and " << scollname << endl; + cerr << " Comparing " << rcollname << " and " << scollname << endl; + } + + // ==== Now let's go for the plotting... + TString newDir = newDirBase+myName2; + cout<<"creating directory: "<mkdir(newDir,kTRUE); + + // efficiency and fake rate Vs eta and phi + plotOptReset(logx,logy,doKolmo,norm,minx,maxx,miny,maxy,drawopt,plots,titles); + plots[0]="effic_vs_eta" ; titles[0]="Efficiency vs #eta"; + plots[1]="fakerate_vs_eta" ; titles[1]="Fake rate vs #eta" ; + plots[2]="effic_vs_phi" ; titles[2]="Efficiency vs #phi" ; + plots[3]="fakerate_vs_phi" ; titles[3]="Fake rate vs #phi" ; + + miny[0]=-0.0001; + miny[1]=-0.0001; + miny[2]=-0.0001; + miny[3]=-0.0001; + + maxy[0]=1.09; + maxy[1]=0.; + maxy[2]=1.09; + maxy[3]=0.; + + Plot4Histograms(newDir + "/eff_eta_phi.pdf", + rdir, sdir, + rcollname, scollname, + "eff_eta_phi", "Efficiency vs eta and Vs phi", + refLabel, newLabel, + plots, titles, drawopt, + logy, logx, doKolmo, norm, minx, maxx, miny, maxy); + + + // efficiency and fake rate Vs pt + plotOptReset(logx,logy,doKolmo,norm,minx,maxx,miny,maxy,drawopt,plots,titles); + plots[0]="effic_vs_pt" ; titles[0]="Efficiency vs pt"; + plots[1]="fakerate_vs_pt" ; titles[1]="Fake rate vs pt" ; + plots[2]="num_simul_pT" ; titles[2]="N of simulated tracks vs pt" ; + plots[3]="num_reco_pT" ; titles[3]="N of reco track vs pt" ; + + logx[0]=true; + logx[1]=true; + logx[2]=true; + logx[3]=true; + + drawopt[0]=""; + drawopt[1]=""; + drawopt[2]="hist"; + drawopt[3]="hist"; + + norm[0]= -1.; + norm[1]= -1.; + norm[2]= 2.; + norm[3]= 2.; + + miny[0]= -0.0001; + miny[1]= -0.0001; + miny[2]= 0.; + miny[3]= 0.; + + maxy[0]= 1.09; + maxy[1]= 0.; + maxy[2]= 0.; + maxy[3]= 0.; + + Plot4Histograms(newDir + "/eff_pt.pdf", + rdir, sdir, + rcollname, scollname, + "eff_pt", "Efficiency vs pt and sim,reco distributions", + refLabel, newLabel, + plots, titles, drawopt, + logy, logx, doKolmo, norm, minx, maxx, miny, maxy); + + + // efficiency and fake rate vs Number of Hits; Hit multiplicity per track; Ave.N.hits vs eta + plotOptReset(logx,logy,doKolmo,norm,minx,maxx,miny,maxy,drawopt,plots,titles); + plots[0]="effic_vs_hit" ; titles[0]="Efficiency vs Number of hits"; + plots[1]="fakerate_vs_hit" ; titles[1]="Fake rate vs Number of hits" ; + plots[2]="nhits" ; titles[2]="number of hits per track" ; + plots[3]="nhits_vs_eta_prof" ; titles[3]="mean number of Hits vs eta" ; + + drawopt[0]=""; + drawopt[1]=""; + drawopt[2]="hist"; + drawopt[3]=""; + + norm[0]= -1.; + norm[1]= -1.; + norm[2]= 0.; + norm[3]= -1.; + + miny[0]= -0.0001; + miny[1]= -0.0001; + miny[2]= 0.; + miny[3]= 0.; + + maxy[0]= 1.09; + maxy[1]= 0.; + maxy[2]= 0.; + maxy[3]= 0.; + + Plot4Histograms(newDir + "/eff_hits.pdf", + rdir, sdir, + rcollname, scollname, + "eff_hits", "Efficiency vs Number of hits and hit multiplicity per track", + refLabel, newLabel, + plots, titles, drawopt, + logy, logx, doKolmo, norm, minx, maxx, miny, maxy); + + // efficiency and fake rate vs PU + plotOptReset(logx,logy,doKolmo,norm,minx,maxx,miny,maxy,drawopt,plots,titles); + plots[0]="effic_vs_pu" ; titles[0]="Efficiency vs n.PU interactions"; + plots[1]="fakerate_vs_pu" ; titles[1]="Fake rate vs n.PU interactions" ; + + maxx[0]= 100.; + maxx[1]= 100.; + + miny[0]= -0.0001; + miny[1]= 0.; + + maxy[0]= 1.09; + maxy[1]= 0.; + + Plot4Histograms(newDir + "/eff_pu.pdf", + rdir, sdir, + rcollname, scollname, + "eff_pu", "Efficiency vs n.PU interactions", + refLabel, newLabel, + plots, titles, drawopt, + logy, logx, doKolmo, norm, minx, maxx, miny, maxy); + + // skip other plots for seeds + if (!scollname.Contains("seeds")) { + + //===== normalized chi2, chi2 probability, ave. norm. chi2 vs eta; ave. pt bias vs eta + plotOptReset(logx,logy,doKolmo,norm,minx,maxx,miny,maxy,drawopt,plots,titles); + plots[0]="chi2" ; titles[0]="Track normalized #chi^{2}"; + plots[1]="chi2prob" ; titles[1]="Probability of track #chi^{2}"; + plots[2]="chi2_vs_eta_prof" ; titles[2]="Mean normalized #chi^{2} vs #eta" ; + + drawopt[0]="hist"; + drawopt[1]="hist"; + drawopt[2]=""; + + norm[0]= 2.; + norm[1]= 2.; + norm[2]= -1.; + + logy[0]=true; + logy[1]=false; + logy[2]=false; + + Plot4Histograms(newDir + "/chi2.pdf", + rdir, sdir, + rcollname, scollname, + "chi2", "chi2 distributions", + refLabel, newLabel, + plots, titles, drawopt, + logy, logx, doKolmo, norm, minx, maxx, miny, maxy); + + //===== pull distributions + plotOptReset(logx,logy,doKolmo,norm,minx,maxx,miny,maxy,drawopt,plots,titles); + plots[0]="ptpull" ; titles[0]="p_{T} Pull"; + plots[1]="qoverppull" ; titles[1]="q/p Pull" ; + plots[2]="phipull" ; titles[2]="#phi Pull" ; + plots[3]="thetapull" ; titles[3]="#theta Pull" ; + plots[4]="dxypull" ; titles[4]="dxy Pull" ; + plots[5]="dzpull" ; titles[5]="dz Pull" ; + + logy[0]=true; + logy[1]=true; + logy[2]=true; + logy[3]=true; + logy[4]=true; + logy[5]=true; + + drawopt[0]="hist"; + drawopt[1]="hist"; + drawopt[2]="hist"; + drawopt[3]="hist"; + drawopt[4]="hist"; + drawopt[5]="hist"; + + norm[0]= 2.; + norm[1]= 2.; + norm[2]= 2.; + norm[3]= 2.; + norm[4]= 2.; + norm[5]= 2.; + + Plot6Histograms(newDir + "/pulls.pdf", + rdir, sdir, + rcollname, scollname, + "pulls", "pull distributions", + refLabel, newLabel, + plots, titles, drawopt, + logy, logx, doKolmo, norm, minx, maxx, miny, maxy); + + + //===== residual distributions (projected on Y-axis from the 2D histos with residuals vs eta) + plotOptReset(logx,logy,doKolmo,norm,minx,maxx,miny,maxy,drawopt,plots,titles); + plots[0]="ptres_vs_eta" ; titles[0]="p_{T} Relative Residual"; + plots[1]="etares_vs_eta" ; titles[1]="#eta Residual" ; + plots[2]="phires_vs_eta" ; titles[2]="#phi Residual" ; + plots[3]="thetaCotres_vs_eta" ; titles[3]="cot(#theta) Residual" ; + plots[4]="dxyres_vs_eta" ; titles[4]="dxy Residual" ; + plots[5]="dzres_vs_eta" ; titles[5]="dz Residual" ; + + logy[0]=true; + logy[1]=true; + logy[2]=true; + logy[3]=true; + logy[4]=true; + logy[5]=true; + + drawopt[0]="hist"; + drawopt[1]="hist"; + drawopt[2]="hist"; + drawopt[3]="hist"; + drawopt[4]="hist"; + drawopt[5]="hist"; + + norm[0]= 2.; + norm[1]= 2.; + norm[2]= 2.; + norm[3]= 2.; + norm[4]= 2.; + norm[5]= 2.; + + Plot6Histograms(newDir + "/residuals.pdf", + rdir, sdir, + rcollname, scollname, + "residuals", "residual distributions", + refLabel, newLabel, + plots, titles, drawopt, + logy, logx, doKolmo, norm, minx, maxx, miny, maxy); + + + //===== resolutions vs eta; pt relative bias vs eta + plotOptReset(logx,logy,doKolmo,norm,minx,maxx,miny,maxy,drawopt,plots,titles); + plots[0]="phires_vs_eta_Sigma" ; titles[0]="width #phi Residual vs #eta"; + plots[1]="thetaCotres_vs_eta_Sigma" ; titles[1]="width cot(#theta) Residual vs #eta" ; + plots[2]="dxyres_vs_eta_Sigma" ; titles[2]="width dxy Residual vs #eta" ; + plots[3]="dzres_vs_eta_Sigma" ; titles[3]="width dz Residual vs #eta" ; + plots[4]="ptres_vs_eta_Sigma" ; titles[4]="width p_{T} Relative Residual vs #eta" ; + plots[5]="ptres_vs_eta_Mean" ; titles[5]="mean p_{T} Relative Residual vs #eta" ; + + logy[0]=true; + logy[1]=true; + logy[2]=true; + logy[3]=true; + logy[4]=true; + logy[5]=false; + + Plot6Histograms(newDir + "/resol_eta.pdf", + rdir, sdir, + rcollname, scollname, + "resol_eta", "resolutions vs eta", + refLabel, newLabel, + plots, titles, drawopt, + logy, logx, doKolmo, norm, minx, maxx, miny, maxy); + + //===== resolutions vs pt; pt relative bias vs eta + plotOptReset(logx,logy,doKolmo,norm,minx,maxx,miny,maxy,drawopt,plots,titles); + plots[0]="phires_vs_pt_Sigma" ; titles[0]="width #phi Residual vs p_{T}"; + plots[1]="thetaCotres_vs_pt_Sigma" ; titles[1]="width cot(#theta) Residual vs p_{T}" ; + plots[2]="dxyres_vs_pt_Sigma" ; titles[2]="width dxy Residual vs p_{T}" ; + plots[3]="dzres_vs_pt_Sigma" ; titles[3]="width dz Residual vs p_{T}" ; + plots[4]="ptres_vs_pt_Sigma" ; titles[4]="width p_{T} Relative Residual vs p_{T}" ; + plots[5]="ptres_vs_pt_Mean" ; titles[5]="mean p_{T} Relative Residual vs p_{T}" ; + + logx[0]=true; + logx[1]=true; + logx[2]=true; + logx[3]=true; + logx[4]=true; + logx[5]=true; + + logy[0]=true; + logy[1]=true; + logy[2]=true; + logy[3]=true; + logy[4]=true; + logy[5]=false; + + Plot6Histograms(newDir + "/resol_pt.pdf", + rdir, sdir, + rcollname, scollname, + "resol_pt", "resolutions vs pt", + refLabel, newLabel, + plots, titles, drawopt, + logy, logx, doKolmo, norm, minx, maxx, miny, maxy); + + + // ================= charge misid rate vs eta, pt, n.hits, PU + plotOptReset(logx,logy,doKolmo,norm,minx,maxx,miny,maxy,drawopt,plots,titles); + plots[0]="chargeMisId_vs_eta" ; titles[0]="Charge MisId rate vs #eta"; + plots[1]="chargeMisId_vs_pt" ; titles[1]="Charge MisID rate vs p_{T}" ; + plots[2]="chargeMisId_vs_hit" ; titles[2]="Charge MisID rate vs number of RecHits" ; + plots[3]="chargeMisId_vs_pu" ; titles[3]="Charge MisID rate vs n.PU interactions" ; + + logx[0]=false; + logx[1]=true; + logx[2]=false; + logx[3]=false; + + maxx[0]= 0.; + maxx[1]= 0.; + maxx[2]= 0.; + maxx[3]= 100.; + + miny[0]= -0.0001; + miny[1]= 0.; + miny[2]= -0.0001; + miny[3]= 0.; + + maxy[0]= 0.; + maxy[1]= 0.; + maxy[2]= 0.; + maxy[3]= 0.; + + Plot4Histograms(newDir + "/chargeMisId.pdf", + rdir, sdir, + rcollname, scollname, + "chargeMisId", "charge misId rate vs eta, pt, nhits, PU", + refLabel, newLabel, + plots, titles, drawopt, + logy, logx, doKolmo, norm, minx, maxx, miny, maxy); + + } // if (!scollname.Contains("seeds")) + + //// Merge pdf files together and rename the merged pdf after the collection name + TString mergefile = "merged_plots.pdf"; // File name where partial pdfs will be merged + TString destfile = newDir + "/../" + myName + ".pdf"; // Destination file name + TString gscommand = "gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile=" + mergefile + " " + + newDir + "/eff_eta_phi.pdf " + + newDir + "/eff_pt.pdf " + + newDir + "/eff_hits.pdf " + + newDir + "/eff_pu.pdf " + + newDir + "/chi2.pdf " + + newDir + "/pulls.pdf " + + newDir + "/residuals.pdf " + + newDir + "/resol_eta.pdf " + + newDir + "/resol_pt.pdf " + + newDir + "/chargeMisId.pdf "; + + if (scollname.Contains("seeds")) + gscommand = "gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile=" + mergefile + " " + + newDir + "/eff_eta_phi.pdf " + + newDir + "/eff_pt.pdf " + + newDir + "/eff_hits.pdf " + + newDir + "/eff_pu.pdf "; + + cout << ">> Merging partial pdfs to " << mergefile << "..." << endl; + if (DEBUG) cout << " ...with command \"" << gscommand << "\"" << endl; + + gSystem->Exec(gscommand); + cout << ">> Moving " << mergefile << " to " << destfile << "..." << endl; + gSystem->Rename(mergefile, destfile); + + cout << ">> Deleting partial pdf files" << endl; + gSystem->Exec("rm -rf "+newDir); + cout << " ... Done" << endl; + + } // end of "while loop" + + /////////////////////////////////////////////////////////////////////////////// + // comparison plots of Muon and Track associators on the probeTracks + + // in case of HLT or HeavyIons skip the following + TString new_Sample_Name("NEW_LABEL"); + + if (TString(dataType) == "HLT" || new_Sample_Name.Contains("_HI")) { + cout << ">> Removing the relval files from ROOT before closing..." << endl; + gROOT->GetListOfFiles()->Remove(sfile); + gROOT->GetListOfFiles()->Remove(rfile); + + if (DEBUG) { + cout << " Exiting!" << endl; + cerr << " Exiting!" << endl; + } + + return; + } + + if (DEBUG) { + cout << " Comparing MuonAssociatorByHits with quickTrackAssociatorByHits on probeTracks (for the new release)" << endl; + cerr << " Comparing MuonAssociatorByHits with quickTrackAssociatorByHits on probeTracks (for the new release)" << endl; + } + + sfile->cd("DQMData/Run 1/Muons/Run summary/RecoMuonV/MuonTrack"); + sdir = gDirectory; + rcollname = "probeTrks_TkAsso"; + scollname = "probeTrks"; + + // for releases before CMSSW_10_1_0_pre1 and New Muon Validation + TString New_CMSSW_Release("NEW_RELEASE"); + bool NEWprobeTrksNames = false; + if (New_CMSSW_Release.Contains("CMSSW_9") || New_CMSSW_Release.Contains("CMSSW_10_0")) NEWprobeTrksNames=true; + if (NEWprobeTrksNames) { + rcollname = "NEWprobeTrks_TkAsso"; + scollname = "NEWprobeTrks"; + } + const char* _refLabel("REF_LABEL, REF_RELEASE REFSELECTION quickTrackAssociatorByHits"); + const char* _newLabel("NEW_LABEL, NEW_RELEASE NEWSELECTION MuonAssociatorByHits"); + + // efficiency and fake rate Vs eta and phi + plotOptReset(logx,logy,doKolmo,norm,minx,maxx,miny,maxy,drawopt,plots,titles); + plots[0]="effic_vs_eta" ; titles[0]="Efficiency vs #eta"; + plots[1]="fakerate_vs_eta" ; titles[1]="Fake rate vs #eta" ; + plots[2]="effic_vs_pt" ; titles[2]="Efficiency vs pt" ; + plots[3]="fakerate_vs_pt" ; titles[3]="Fake rate vs pt" ; + + logx[0]=false; + logx[1]=false; + logx[2]=true; + logx[3]=true; + + miny[0]=-0.0001; + miny[1]=-0.0001; + miny[2]=-0.0001; + miny[3]=-0.0001; + + maxy[0]=1.09; + maxy[1]=0.; + maxy[2]=1.09; + maxy[3]=0.; + + Plot4Histograms("eff_pt_eta.pdf", + sdir, sdir, + rcollname, scollname, + "eff_pt_eta_MABHvsTABH", "Efficiency vs eta and pt - Muon vs Track Associator", + _refLabel, _newLabel, + plots, titles, drawopt, + logy, logx, doKolmo, norm, minx, maxx, miny, maxy); + + // efficiency and fake rate Vs N.hits and phi + plotOptReset(logx,logy,doKolmo,norm,minx,maxx,miny,maxy,drawopt,plots,titles); + plots[0]="effic_vs_hit" ; titles[0]="Efficiency vs Number of hits"; + plots[1]="fakerate_vs_hit" ; titles[1]="Fake rate vs Number of hits" ; + plots[2]="effic_vs_phi" ; titles[2]="Efficiency vs #phi" ; + plots[3]="fakerate_vs_phi" ; titles[3]="Fake rate vs #phi" ; + + miny[0]=-0.0001; + miny[1]=-0.0001; + miny[2]=-0.0001; + miny[3]=-0.0001; + + maxy[0]=1.09; + maxy[1]=0.; + maxy[2]=1.09; + maxy[3]=0.; + + Plot4Histograms("eff_phi_hits.pdf", + sdir, sdir, + rcollname, scollname, + "eff_phi_hits_MABHvsTABH", "Efficiency vs phi and N. hits - Muon vs Track Associator", + _refLabel, _newLabel, + plots, titles, drawopt, + logy, logx, doKolmo, norm, minx, maxx, miny, maxy); + + // efficiency and fake rate Vs PU + plotOptReset(logx,logy,doKolmo,norm,minx,maxx,miny,maxy,drawopt,plots,titles); + plots[0]="effic_vs_pu" ; titles[0]="Efficiency vs n.PU interactions"; + plots[1]="fakerate_vs_pu" ; titles[1]="Fake rate vs n.PU interactions" ; + + maxx[0]= 100.; + maxx[1]= 100.; + + miny[0]= -0.0001; + miny[1]= 0.; + + maxy[0]= 1.09; + maxy[1]= 0.; + + PlotNHistograms("eff_pu.pdf", + sdir, sdir, + rcollname, scollname, + "eff_pu_MABHvsTABH", "Efficiency vs N.PU interactions - Muon vs Track Associator", + _refLabel, _newLabel, + 4, plots, titles, drawopt, + logy, logx, doKolmo, norm, minx, maxx, miny, maxy); + + //// Merge pdf files together and rename the merged pdf after the + TString _destfile = newDirBase + "probeTrks_MABH_vs_TABH" + ".pdf"; // Destination file name + TString _gscommand = "gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile=" + _destfile + " " + + "./eff_pt_eta.pdf " + + "./eff_phi_hits.pdf " + + "./eff_pu.pdf "; + + cout << ">> Merging partial pdfs to " << _destfile << "..." << endl; + if (DEBUG) cout << " ...with command \"" << _gscommand << "\"" << endl; + gSystem->Exec(_gscommand); + + cout << ">> Deleting partial pdf files" << endl; + gSystem->Exec("rm -rf eff_*.pdf"); + cout << " ... Done" << endl; + + cout << ">> Removing the relval files from ROOT before closing..." << endl; + gROOT->GetListOfFiles()->Remove(sfile); + gROOT->GetListOfFiles()->Remove(rfile); + + if (DEBUG) { + cout << " Exiting!" << endl; + cerr << " Exiting!" << endl; + } +} + diff --git a/Validation/RecoMuon/test/new_muonReleaseSummary.py b/Validation/RecoMuon/test/new_muonReleaseSummary.py new file mode 100644 index 0000000000000..d18d22d6687b0 --- /dev/null +++ b/Validation/RecoMuon/test/new_muonReleaseSummary.py @@ -0,0 +1,356 @@ +#! /usr/bin/env python + +import os +import shutil +import sys +import fileinput +import string +import new_userparams + +############################################################## +# Input parameters +# + +print "Reading input parameters" + +# +#specify macros used to plot here +# +macro='macro/new_TrackValHistoPublisher.C' +macroSeed='macro/SeedValHistoPublisher.C' +macroReco='macro/RecoValHistoPublisher.C' +macroIsol='macro/IsoValHistoPublisher.C' +macroMuonReco='macro/RecoMuonValHistoPublisher.C' + + +############################################################## +# Helper functions +# +def GetGuiRepository(param): + splitrelease=param['Release'].split('_') + genericrelease='_'.join(splitrelease[0:3])+'_x/' + dqmguirepository=param['DqmGuiBaseRepo']+genericrelease + return dqmguirepository + +def GetEosRepository(param): + splitrelease=param['Release'].split('_') + genericrelease='_'.join(splitrelease[0:3])+'_x/' + eosRepository=param['EOSBaseRepository']+genericrelease + return eosRepository + +def GetLabel(params): + label = params['Condition'] + if (params['Condition'] == 'STARTUP'): + label = 'START' + elif (params['Condition']=='MC'): + label ='MC_52_V1' + label+=params['Label'] + + if (params['FastSim']): + label += '_FastSim' + + label += '-' + params['Version'] + + if (params['PileUp']!='no'): + label = 'PU' + params['PileUp']+ '_' + label + + return label + + +def GetTag(params): + tag = params['Condition'] + if (params['PileUp']=='no'): + tag += '_noPU' + else: + tag += '_PU'+params['PileUp'] + if (params['FastSim']): + tag +='_FSIM' + return tag + +def GetFastSimSuffix(params): + if (params['FastSim']): + return 'FS' + else: + return '' + +def replace(map, filein, fileout): + replace_items = map.items() + while 1: + line = filein.readline() + if not line: break + for old, new in replace_items: + line = string.replace(line, old, new) + fileout.write(line) + fileout.close() + filein.close() + +def myrootsubmit(cfgfile): + command='root -b -q -l '+ cfgfile + '.C' + '> macro.' + cfgfile +'.log' + print('>> Executing \'' + command + '\'') + os.system(command) + print(' ... executed \'' + command + '\''); + +def downloadfile(url): + print(' + Downloading "' + url + '"...') + #os.system('wget --ca-directory $X509_CERT_DIR/ --certificate=$X509_USER_PROXY --private-key=$X509_USER_PROXY '+url) + stream = os.popen('/usr/bin/curl -k -O -L --capath $X509_CERT_DIR --key $X509_USER_PROXY --cert $X509_USER_PROXY -w "%{http_code}" '+ url) + output=stream.readlines() + if output[0]=='200': + print(' + OK!') + return True + else: + print(' + ERROR! ' + str(output[0])) + print "Skipping " + url + print "Please check the name of the file in the repository: "+GetGuiRepository(new_userparams.NewParams) + sys.exit('Exiting...'); + # return False + +def GetSamplePath(params, sample): + return params['Release']+'/'+GetTag(params)+'/'+sample + +def GetLocalSampleName(params, sample): + return GetSamplePath(params, sample) + '/val.' + sample + '.root' + +def createSampleDirectory(params, sample): + path = GetSamplePath(params, sample) + print('>> Creating directory ' + path + '...') + if(os.path.exists(path)==False): + os.makedirs(path) + else: + print('NOTE: Directory \'' + path + '\' already exists') + + return path + +def getSampleFiles(params, sample): + path = GetSamplePath(params,sample) + print('>> Creating directory ' + path + '...') + if(os.path.exists(path)==False): + os.makedirs(path) + else: + print('NOTE: Directory \'' + path + '\' already exists') + + print('\n') + + # Check if pdfs have already been produced + checkFile = path + '/standAloneMuons.pdf' + print('>> Checking if ' + checkFile + ' already exists...') + if (os.path.isfile(checkFile)==True): + print(' + Files of type ' + checkFile + ' exist already.') + print(' Delete them first, if you really want to overwrite them') + quit() + + print(' + The file does not exist so we continue') + localsample=GetLocalSampleName(params, sample) + sampleOnWeb=new_userparams.WebRepository+'/'+ localsample + + if (os.path.isfile(localsample)==True): + print ' + ' + params['Type'] + ' sample file found at: ' +localsample + '. Using that one' + + elif (new_userparams.NewParams['GetFilesFrom']=='GUI'): + theGuiSample = sample + + guiFileName='DQM_V0001_R000000001__'+theGuiSample+'__'+params['Release']+'-'+GetLabel(params)+'__'+params['Format']+'.root' + guiFullURL=GetGuiRepository(params)+guiFileName + print ">> Downloading file from the GUI: " + guiFullURL + + if (downloadfile(guiFullURL)==True): + print(' + Moving ' + guiFileName + ' to ' + localsample) + shutil.move(guiFileName,localsample) + + elif ((params['GetFilesFrom']=='WEB') & (os.path.isfile(sampleOnWeb))) : + print "NOTE: New file found at: "+newSample+' -> Copy that one' + os.system('cp '+sampleOnWeb+' '+path) + + elif ((params['GetFilesFrom']=='EOS')) : + print "creating a symbolic link to a file from eos: " + eosFileName='DQM_V0001_R000000001__'+sample+'__'+params['Release']+'-'+GetLabel(params)+'__'+params['Format']+'.root' + eosRepository=GetEosRepository(params) + sampleOnEOS=eosRepository+eosFileName + + if (os.path.isfile(sampleOnEOS)) : + print sampleOnEOS + #cp_command = 'cp '+sampleOnEOS+' '+path+'/val.'+ sample+'.root' + #os.system(cp_command) + ln_command = 'ln -s '+sampleOnEOS+' '+path+'/val.'+ sample+'.root' + os.system(ln_command) + else : + print "ERROR: File "+sampleOnEOS+" NOT found." + quit() + + else: + print '*** WARNING: no signal file was found' + +def getReplaceMap(newparams, refparams, sample, datatype, cfgkey, cfgfile): + newLocalSample=GetLocalSampleName(newparams, sample) + refLocalSample=GetLocalSampleName(refparams, sample) + replace_map = { 'DATATYPE': datatype, + 'NEW_FILE':newLocalSample, + 'REF_FILE':refLocalSample, + 'REF_LABEL':sample, + 'NEW_LABEL': sample, + 'REF_RELEASE':refparams['Release'], + 'NEW_RELEASE':newparams['Release'], + 'REFSELECTION':GetTag(refparams), + 'NEWSELECTION':GetTag(newparams), + cfgkey: cfgfile + } + return replace_map + +############################################################## +# Main program +# +# Initial checks +# + Copying missing parameters from New to Ref +print('>> Checking input parameters...') +for i in new_userparams.NewParams: + if i in new_userparams.RefParams: + print(' + ' + i + ' set to:') + print(' -' + str(new_userparams.NewParams[i]) + ' (new)') + print(' -' + str(new_userparams.RefParams[i]) + ' (ref)') + else: + new_userparams.RefParams[i]=new_userparams.NewParams[i] + print(' + ' + i + ' set to ' + str(new_userparams.NewParams[i]) + ' (both)') + +# + Things needed by GUI +if ((new_userparams.NewParams['GetFilesFrom']=='GUI')|(new_userparams.RefParams['GetFilesFrom']=='GUI')): + if os.getenv('X509_USER_PROXY','') == '': + print "ERROR: It seems you did not configure your environment to be able" + print " to download files from the GUI. Your should follow these steps:" + print " > source /cvmfs/cms.cern.ch/crab3/crab.csh" + print " > voms-proxy-init --voms cms" + print " > setenv X509_CERT_DIR $HOME/.globus" + print " > setenv X509_USER_PROXY /tmp/x509up_uVWXYZ (where VWXYZ = your unix Id on lxplus)" + print " > or similarly for bash shell" + quit() + +if (new_userparams.NewParams['FastSim']|new_userparams.RefParams['FastSim']): + new_userparams.ValidateHLT=False + new_userparams.ValidateDQM=False + +if (new_userparams.NewParams['HeavyIons']|new_userparams.RefParams['HeavyIons']): + new_userparams.ValidateHLT=False + new_userparams.ValidateRECO=False + new_userparams.ValidateISO=False + + +# Iterate over new_userparams.samples +print('>> Selected samples:') +for sample in new_userparams.samples: + print(' + ' + sample) + +print('>> Processing new_userparams.samples:') +for sample in new_userparams.samples : + print('###################################################') + print('# ' + sample) + print('###################################################') + print('\n') + + # Create the directories to store the new_userparams.samples and pdfs + newpath=createSampleDirectory(new_userparams.NewParams, sample) + refpath=createSampleDirectory(new_userparams.RefParams, sample) + print('\n') + + getSampleFiles(new_userparams.NewParams, sample) + getSampleFiles(new_userparams.RefParams, sample) + + print(' + Producing macro files...') + # root macro name should not contain "-" + sample_m = sample + if (sample == 'RelValJpsiMuMu_Pt-8'): + sample_m = 'RelValJpsiMuMu_Pt8' + + cfgFileName=sample_m+'_'+new_userparams.NewParams['Release']+'_'+new_userparams.RefParams['Release'] + hltcfgFileName='HLT'+sample_m+'_'+new_userparams.NewParams['Release']+'_'+new_userparams.RefParams['Release'] + seedcfgFileName='DQMSEED'+sample_m+'_'+new_userparams.NewParams['Release']+'_'+new_userparams.RefParams['Release'] + recocfgFileName='DQMRECO'+sample_m+'_'+new_userparams.NewParams['Release']+'_'+new_userparams.RefParams['Release'] + recomuoncfgFileName='RECO'+sample_m+'_'+new_userparams.NewParams['Release']+'_'+new_userparams.RefParams['Release'] + isolcfgFileName='ISOL'+sample_m+'_'+new_userparams.NewParams['Release']+'_'+new_userparams.RefParams['Release'] + + if os.path.isfile(GetLocalSampleName(new_userparams.RefParams,sample)): + replace_map = getReplaceMap(new_userparams.NewParams, new_userparams.RefParams, sample, 'RECO', 'new_TrackValHistoPublisher', cfgFileName) + if (new_userparams.ValidateHLT): + replace_map_HLT = getReplaceMap(new_userparams.NewParams, new_userparams.RefParams, sample, 'HLT', 'new_TrackValHistoPublisher', hltcfgFileName) + if (new_userparams.ValidateDQM): + replace_map_DIST = getReplaceMap(new_userparams.NewParams, new_userparams.RefParams, sample, 'RECO', 'RecoValHistoPublisher', recocfgFileName) + replace_map_SEED = getReplaceMap(new_userparams.NewParams, new_userparams.RefParams, sample, 'RECO', 'SeedValHistoPublisher', seedcfgFileName) + if (new_userparams.ValidateISO): + replace_map_ISOL = getReplaceMap(new_userparams.NewParams, new_userparams.RefParams, sample, 'RECO', 'IsoValHistoPublisher', isolcfgFileName) + if (new_userparams.ValidateRECO): + replace_map_RECO = getReplaceMap(new_userparams.NewParams, new_userparams.RefParams, sample, 'RECO', 'RecoMuonValHistoPublisher', recomuoncfgFileName) + replace_map_RECO['IS_FSIM']='' + else: + print "No reference file found at: ", refpath + replace_map = getReplaceMap(new_userparams.NewParams, new_userparams.NewParams, sample, 'RECO', 'new_TrackValHistoPublisher', cfgFileName) + if (new_userparams.ValidateHLT): + replace_map_HLT = getReplaceMap(new_userparams.NewParams, new_userparams.NewParams, sample, 'HLT', 'new_TrackValHistoPublisher', hltcfgFileName) + if (new_userparams.ValidateDQM): + replace_map_DIST = getReplaceMap(new_userparams.NewParams, new_userparams.NewParams, sample, 'RECO', 'RecoValHistoPublisher', recocfgFileName) + replace_map_SEED = getReplaceMap(new_userparams.NewParams, new_userparams.NewParams, sample, 'RECO', 'SeedValHistoPublisher', seedcfgFileName) + if (new_userparams.ValidateISO): + replace_map_ISOL = getReplaceMap(new_userparams.NewParams, new_userparams.NewParams, sample, 'RECO', 'IsoValHistoPublisher', isolcfgFileName) + if (new_userparams.ValidateRECO): + replace_map_RECO = getReplaceMap(new_userparams.NewParams, new_userparams.NewParams, sample, 'RECO', 'RecoMuonValHistoPublisher', recomuoncfgFileName) + replace_map_RECO['IS_FSIM']='' + + templatemacroFile = open(macro, 'r') + macroFile = open(cfgFileName+'.C' , 'w' ) + replace(replace_map, templatemacroFile, macroFile) + + if (new_userparams.ValidateHLT): + templatemacroFile = open(macro, 'r') + hltmacroFile = open(hltcfgFileName+'.C' , 'w' ) + replace(replace_map_HLT, templatemacroFile, hltmacroFile) + + if (new_userparams.ValidateDQM): + templatemacroFile = open(macroReco, 'r') + recomacroFile = open(recocfgFileName+'.C' , 'w' ) + replace(replace_map_DIST, templatemacroFile, recomacroFile) + templatemacroFile = open(macroSeed, 'r') + seedmacroFile = open(seedcfgFileName+'.C' , 'w' ) + replace(replace_map_SEED, templatemacroFile, seedmacroFile) + + if (new_userparams.ValidateISO): + templatemacroFile = open(macroIsol, 'r') + isolmacroFile = open(isolcfgFileName+'.C' , 'w' ) + replace(replace_map_ISOL, templatemacroFile, isolmacroFile) + + if (new_userparams.ValidateRECO): + templatemacroFile = open(macroMuonReco, 'r') + recomuonmacroFile = open(recomuoncfgFileName+'.C' , 'w' ) + replace(replace_map_RECO, templatemacroFile, recomuonmacroFile) + + if(new_userparams.Submit): + myrootsubmit(cfgFileName) + if (new_userparams.ValidateHLT): + myrootsubmit(hltcfgFileName) + if (new_userparams.ValidateDQM): + myrootsubmit(recocfgFileName) + myrootsubmit(seedcfgFileName) + if (new_userparams.ValidateISO): + myrootsubmit(isolcfgFileName) + if (new_userparams.NewParams['FastSim']&new_userparams.RefParams['FastSim']): + shutil.move(newpath+'/MuonIsolationV_inc.pdf',newpath+'/MuonIsolationV_inc_FS.pdf') + if (new_userparams.ValidateRECO): + myrootsubmit(recomuoncfgFileName) + if (new_userparams.NewParams['FastSim']&new_userparams.RefParams['FastSim']): + if (os.path.isfile(newpath+'/RecoMuonV.pdf') == True): + os.rename(newpath+'/RecoMuonV.pdf',newpath+'/RecoMuonV_FS.pdf') + else: + print('ERROR: Could not find "' + newpath + '/RecoMuonV.pdf') + + if(new_userparams.Publish): + newpath = GetSamplePath(new_userparams.NewParams,sample) + newlocalsample = GetLocalSampleName(new_userparams.NewParams, sample) + newdir=new_userparams.WebRepository + '/' + newpath + print('>> Publishing to ' + newdir + '...') + if(os.path.exists(newdir)==False): + os.system('ssh '+new_userparams.User+'@lxplus.cern.ch mkdir -p ' + newdir) + # os.makedirs(newdir) + # os.system('rm '+ newlocalsample) + # os.system('scp -r '+newpath+'/* ' + newdir) + os.system('scp -r '+newpath+'/*.pdf '+new_userparams.User+'@lxplus.cern.ch:' + newdir) + + if(new_userparams.Publish_rootfile): + os.system('scp -r '+newpath+'/val.*.root '+new_userparams.User+'@lxplus.cern.ch:' + newdir) + + print('New path is ' + newlocalsample + ' and ' + newpath) diff --git a/Validation/RecoMuon/test/new_userparams.py b/Validation/RecoMuon/test/new_userparams.py new file mode 100644 index 0000000000000..0488efa2d5e5c --- /dev/null +++ b/Validation/RecoMuon/test/new_userparams.py @@ -0,0 +1,145 @@ +#! /usr/bin/env python + +import os +import shutil +import sys +import fileinput +import string + +############################################################## +# Input parameters +# +# +# Should we execute the code? +# +Submit=True + +# +# Should we publish the results? +# +Publish=True +Publish_rootfile=False + +# + Location of the AFS place where to put the PDFs +WebRepository = '/afs/cern.ch/cms/Physics/muon/CMSSW/Performance/RecoMuon/Validation/val' + +# User enabled to write in the afs area +User='giovanni' + +# +# Information about the new release +# +NewParams = dict( + # Type of parameters + Type='New', + + # Releases to compare + Release='CMSSW_10_1_0_pre1', + + # Conditions of the sample + # + # FullSim in CMSSW_10_1_0_pre1 + Condition='100X_upgrade2018_realistic_v10', + # + # FastSim in CMSSW_10_1_0_pre1 + #Condition='100X_mcRun2_asymptotic_v2', + + # 'no' if no pileup, otherwise set BX spacing + PileUp='25ns', + #PileUp='', # for HeavyIons + #PileUp='no', + + Version='v1', + + Format='DQMIO', + + # If True use Fastsim, else use Fullsim + FastSim=False, + #FastSim=True, + + # for HeavyIons samples (few folders are not there) + HeavyIons=False, + #HeavyIons=True, + + # needed if you copy any root file from the DQM GUI. + # See GetLabel function for more details + Label='', + + # Where to get the root file from. Possible values + # * WEB: Take root files from the MuonPOG Validation repo on the web + # * GUI: Copy root files from the DQM GUI server + # * EOS: copy root files from Muon POG users area + # By default, if the root files are already in the local area, + # they won't be overwritten + GetFilesFrom='GUI', + #GetFilesFrom='EOS', + + # Base URL of the DQM GUI repository + #DqmGuiBaseRepo='https://cmsweb.cern.ch/dqm/relval/data/browse/ROOT/RelVal/', + DqmGuiBaseRepo='https://cmsweb.cern.ch/dqm/relval/data/browse/ROOT/RelVal/', + + # Base repository on EOS + EOSBaseRepository='/eos/cms/store/group/phys_muon/abbiendi/RelVal/' +) + + +# +# Information about the reference release. +# We only need to set the variables than are different from the new release +# +RefParams = dict( + # Type of parameters + Type='Ref', + + Release='CMSSW_10_0_0', + + # Conditions for Special RelVals in CMSSW_10_0_0 + # + # FullSim NoPU in CMSSW_10_0_0 + #Condition='100X_upgrade2018_realistic_v6_muVal', + #Condition='100X_upgrade2018_realistic_v6_mahiON', #standard RelVals (v1 and v2) + # + # FullSim PU25ns in CMSSW_10_0_0 + Condition='100X_upgrade2018_realistic_v6_muVal_resubwith4cores', + # + # FastSim in CMSSW_10_0_0 + #Condition='100X_mcRun2_asymptotic_v2_muVal', + #Condition='100X_mcRun2_asymptotic_v2', #standard RelVals (v1) + + Version='v1', + #Version='v2', + + Label='' +) + +# +# Optional plots to be made: +# for FastSim HLT,DQM are set automatically to False +# for HeavyIons HLT,RECO are skipped if HeavyIons = True +# +ValidateHLT = True +ValidateRECO = True +ValidateISO = True +ValidateDQM = True + +# Samples for Validation + +# For FullSim No PU +#samples = ['RelValSingleMuPt10','RelValSingleMuPt100','RelValSingleMuPt1000', +# 'RelValZMM_13', 'RelValWM_13', 'RelValJpsiMuMu_Pt-8', 'RelValTTbar_13', +# 'RelValZpMM_13', 'RelValWpM_13', +# 'RelValDisplacedSUSY_stopToBottom_M_300_1000mm_13'] + +# For FullSim PU 25ns +samples = ['RelValZMM_13', 'RelValTTbar_13'] + +# For HeavyIons FullSim +#samples = ['RelValZEEMM_13_HI'] + +# For FastSim No PU +#samples = ['RelValSingleMuPt10_UP15', 'RelValSingleMuPt100_UP15', +# 'RelValZMM_13','RelValTTbar_13'] + +# For FastSim PU 25ns +#samples = ['RelValZMM_13','RelValTTbar_13'] +