Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:13:22

0001 #include "FWCore/Framework/interface/Frameworkfwd.h"
0002 #include "FWCore/Framework/interface/EDAnalyzer.h"
0003 #include "FWCore/Framework/interface/Event.h"
0004 #include "FWCore/Framework/interface/MakerMacros.h"
0005 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0006 #include "FWCore/ServiceRegistry/interface/Service.h"
0007 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0008 #include "FWCore/Utilities/interface/InputTag.h"
0009 #include "DQMServices/Core/interface/DQMStore.h"
0010 
0011 #include "DQMOffline/Trigger/plugins/GenericTnPFitter.h"
0012 
0013 #include <TString.h>
0014 #include <TPRegexp.h>
0015 
0016 using namespace edm;
0017 using namespace dqmTnP;
0018 using namespace std;
0019 
0020 using vstring = std::vector<std::string>;
0021 
0022 class DQMGenericTnPClient : public edm::EDAnalyzer {
0023 public:
0024   typedef dqm::legacy::MonitorElement MonitorElement;
0025   typedef dqm::legacy::DQMStore DQMStore;
0026 
0027   DQMGenericTnPClient(const edm::ParameterSet& pset);
0028   ~DQMGenericTnPClient() override;
0029   void analyze(const edm::Event& event, const edm::EventSetup& eventSetup) override{};
0030   void endRun(const edm::Run& run, const edm::EventSetup& setup) override;
0031   void calculateEfficiency(const std::string& dirName, const ParameterSet& pset);
0032   void findAllSubdirectories(const std::string& dir, std::set<std::string>* myList, TString pattern);
0033 
0034 private:
0035   DQMStore* dqmStore;
0036   TFile* plots;
0037   vstring subDirs;
0038   std::string myDQMrootFolder;
0039   bool verbose;
0040   const VParameterSet efficiencies;
0041   GaussianPlusLinearFitter* GPLfitter;
0042   VoigtianPlusExponentialFitter* VPEfitter;
0043 };
0044 
0045 DQMGenericTnPClient::DQMGenericTnPClient(const edm::ParameterSet& pset)
0046     : subDirs(pset.getUntrackedParameter<vstring>("subDirs", vstring())),
0047       myDQMrootFolder(pset.getUntrackedParameter<std::string>("MyDQMrootFolder", "")),
0048       verbose(pset.getUntrackedParameter<bool>("Verbose", false)),
0049       efficiencies(pset.getUntrackedParameter<VParameterSet>("Efficiencies")) {
0050   TString savePlotsInRootFileName = pset.getUntrackedParameter<string>("SavePlotsInRootFileName", "");
0051   plots = savePlotsInRootFileName != "" ? new TFile(savePlotsInRootFileName, "recreate") : nullptr;
0052   GPLfitter = new GaussianPlusLinearFitter(verbose);
0053   VPEfitter = new VoigtianPlusExponentialFitter(verbose);
0054 }
0055 
0056 void DQMGenericTnPClient::endRun(const edm::Run& run, const edm::EventSetup& setup) {
0057   TPRegexp metacharacters("[\\^\\$\\.\\*\\+\\?\\|\\(\\)\\{\\}\\[\\]]");
0058 
0059   dqmStore = Service<DQMStore>().operator->();
0060   if (!dqmStore) {
0061     LogError("DQMGenericTnPClient") << "Could not find DQMStore service\n";
0062     return;
0063   }
0064   dqmStore->setCurrentFolder(myDQMrootFolder);
0065 
0066   set<std::string> subDirSet;
0067 
0068   if (!myDQMrootFolder.empty())
0069     subDirSet.insert(myDQMrootFolder);
0070   else {
0071     for (auto iSubDir = subDirs.begin(); iSubDir != subDirs.end(); ++iSubDir) {
0072       std::string subDir = *iSubDir;
0073       if (subDir[subDir.size() - 1] == '/')
0074         subDir.erase(subDir.size() - 1);
0075       if (TString(subDir).Contains(metacharacters)) {
0076         const string::size_type shiftPos = subDir.rfind('/');
0077         const string searchPath = subDir.substr(0, shiftPos);
0078         const string pattern = subDir.substr(shiftPos + 1, subDir.length());
0079         findAllSubdirectories(searchPath, &subDirSet, pattern);
0080       } else {
0081         subDirSet.insert(subDir);
0082       }
0083     }
0084   }
0085 
0086   for (auto const& dirName : subDirSet) {
0087     for (auto const& efficiencie : efficiencies) {
0088       calculateEfficiency(dirName, efficiencie);
0089     }
0090   }
0091 }
0092 
0093 void DQMGenericTnPClient::calculateEfficiency(const std::string& dirName, const ParameterSet& pset) {
0094   //get hold of numerator and denominator histograms
0095   string allMEname = dirName + "/" + pset.getUntrackedParameter<string>("DenominatorMEname");
0096   string passMEname = dirName + "/" + pset.getUntrackedParameter<string>("NumeratorMEname");
0097   MonitorElement* allME = dqmStore->get(allMEname);
0098   MonitorElement* passME = dqmStore->get(passMEname);
0099   if (allME == nullptr || passME == nullptr) {
0100     LogDebug("DQMGenericTnPClient") << "Could not find MEs: " << allMEname << " or " << passMEname << endl;
0101     return;
0102   }
0103   TH1* all = allME->getTH1();
0104   TH1* pass = passME->getTH1();
0105   //setup the fitter
0106   string fitFunction = pset.getUntrackedParameter<string>("FitFunction");
0107   AbstractFitter* fitter = nullptr;
0108   if (fitFunction == "GaussianPlusLinear") {
0109     GPLfitter->setup(pset.getUntrackedParameter<double>("ExpectedMean"),
0110                      pset.getUntrackedParameter<double>("FitRangeLow"),
0111                      pset.getUntrackedParameter<double>("FitRangeHigh"),
0112                      pset.getUntrackedParameter<double>("ExpectedSigma"));
0113     fitter = GPLfitter;
0114   } else if (fitFunction == "VoigtianPlusExponential") {
0115     VPEfitter->setup(pset.getUntrackedParameter<double>("ExpectedMean"),
0116                      pset.getUntrackedParameter<double>("FitRangeLow"),
0117                      pset.getUntrackedParameter<double>("FitRangeHigh"),
0118                      pset.getUntrackedParameter<double>("ExpectedSigma"),
0119                      pset.getUntrackedParameter<double>("FixedWidth"));
0120     fitter = VPEfitter;
0121   } else {
0122     LogError("DQMGenericTnPClient") << "Fit function: " << fitFunction << " does not exist" << endl;
0123     return;
0124   }
0125   //check dimensions
0126   int dimensions = all->GetDimension();
0127   int massDimension = pset.getUntrackedParameter<int>("MassDimension");
0128   if (massDimension > dimensions) {
0129     LogError("DQMGenericTnPClient") << "Monitoring Element " << allMEname << " has smaller dimension than "
0130                                     << massDimension << endl;
0131     return;
0132   }
0133   //figure out directory and efficiency names
0134   string effName = pset.getUntrackedParameter<string>("EfficiencyMEname");
0135   string effDir = dirName;
0136   string::size_type slashPos = effName.rfind('/');
0137   if (string::npos != slashPos) {
0138     effDir += "/" + effName.substr(0, slashPos);
0139     effName.erase(0, slashPos + 1);
0140   }
0141   dqmStore->setCurrentFolder(effDir);
0142   TString prefix(effDir.c_str());
0143   prefix.ReplaceAll('/', '_');
0144   //calculate and book efficiency
0145   if (dimensions == 2) {
0146     TProfile* eff = nullptr;
0147     TProfile* effChi2 = nullptr;
0148     TString error = fitter->calculateEfficiency(
0149         (TH2*)pass, (TH2*)all, massDimension, eff, effChi2, plots ? prefix + effName.c_str() : "");
0150     if (error != "") {
0151       LogError("DQMGenericTnPClient") << error << endl;
0152       return;
0153     }
0154     dqmStore->bookProfile(effName, eff);
0155     dqmStore->bookProfile(effName + "Chi2", effChi2);
0156     delete eff;
0157     delete effChi2;
0158   } else if (dimensions == 3) {
0159     TProfile2D* eff = nullptr;
0160     TProfile2D* effChi2 = nullptr;
0161     TString error = fitter->calculateEfficiency(
0162         (TH3*)pass, (TH3*)all, massDimension, eff, effChi2, plots ? prefix + effName.c_str() : "");
0163     if (error != "") {
0164       LogError("DQMGenericTnPClient") << error << endl;
0165       return;
0166     }
0167     dqmStore->bookProfile2D(effName, eff);
0168     dqmStore->bookProfile2D(effName + "Chi2", effChi2);
0169     delete eff;
0170     delete effChi2;
0171   }
0172 }
0173 
0174 DQMGenericTnPClient::~DQMGenericTnPClient() {
0175   delete GPLfitter;
0176   if (plots) {
0177     plots->Close();
0178   }
0179 }
0180 
0181 void DQMGenericTnPClient::findAllSubdirectories(const std::string& dir,
0182                                                 std::set<std::string>* myList,
0183                                                 TString pattern = "") {
0184   if (!dqmStore->dirExists(dir)) {
0185     LogError("DQMGenericTnPClient") << " DQMGenericTnPClient::findAllSubdirectories ==> Missing folder " << dir
0186                                     << " !!!";
0187     return;
0188   }
0189   TPRegexp nonPerlWildcard("\\w\\*|^\\*");
0190   if (pattern != "") {
0191     if (pattern.Contains(nonPerlWildcard))
0192       pattern.ReplaceAll("*", ".*");
0193     TPRegexp regexp(pattern);
0194     dqmStore->cd(dir);
0195     vector<string> foundDirs = dqmStore->getSubdirs();
0196     for (auto iDir = foundDirs.begin(); iDir != foundDirs.end(); ++iDir) {
0197       TString dirName = iDir->substr(iDir->rfind('/') + 1, iDir->length());
0198       if (dirName.Contains(regexp))
0199         findAllSubdirectories(*iDir, myList);
0200     }
0201   } else if (dqmStore->dirExists(dir)) {
0202     myList->insert(dir);
0203     dqmStore->cd(dir);
0204     findAllSubdirectories(dir, myList, "*");
0205   } else {
0206     LogInfo("DQMGenericClient") << "Trying to find sub-directories of " << dir << " failed because " << dir
0207                                 << " does not exist";
0208   }
0209   return;
0210 }
0211 
0212 //define this as a plug-in
0213 DEFINE_FWK_MODULE(DQMGenericTnPClient);