CMS 3D CMS Logo

DQMFileSaver.cc

Go to the documentation of this file.
00001 #include "DQMServices/Components/src/DQMFileSaver.h"
00002 #include "DQMServices/Core/interface/DQMStore.h"
00003 #include "DQMServices/Core/interface/MonitorElement.h"
00004 #include "FWCore/Framework/interface/Event.h"
00005 #include "FWCore/Framework/interface/Run.h"
00006 #include "FWCore/Framework/interface/LuminosityBlock.h"
00007 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00008 #include "FWCore/Utilities/interface/GetReleaseVersion.h"
00009 #include "FWCore/ServiceRegistry/interface/Service.h"
00010 #include <sys/stat.h>
00011 #include <unistd.h>
00012 #include <iostream>
00013 #include <vector>
00014 
00015 //--------------------------------------------------------
00016 static void
00017 getAnInt(const edm::ParameterSet &ps, int &value, const std::string &name)
00018 {
00019   value = ps.getUntrackedParameter<int>(name, value);
00020   if (value < 1 && value != -1)
00021     throw cms::Exception("DQMFileSaver")
00022       << "Invalid '" << name << "' parameter '" << value
00023       << "'.  Must be -1 or >= 1.";
00024 }
00025 
00026 void
00027 DQMFileSaver::saveForOffline(const std::string &workflow, int run)
00028 {
00029   char suffix[64];
00030   sprintf(suffix, "R%09d", run);
00031 
00032   char rewrite[64];
00033   sprintf(rewrite, "\\1Run %d/\\2/Run summary", run);
00034 
00035   size_t pos = 0;
00036   std::string wflow;
00037   wflow.reserve(workflow.size() + 3);
00038   wflow = workflow;
00039   while ((pos = wflow.find('/', pos)) != std::string::npos)
00040     wflow.replace(pos++, 1, "__");
00041 
00042   dbe_->save(fileBaseName_ + suffix + wflow + ".root",
00043              "", "^(Reference/)?([^/]+)", rewrite,
00044              (DQMStore::SaveReferenceTag) saveReference_,
00045              saveReferenceQMin_);
00046 }
00047 
00048 void
00049 DQMFileSaver::saveForOnline(const std::string &suffix, const std::string &rewrite)
00050 {
00051    std::vector<std::string> systems = (dbe_->cd(), dbe_->getSubdirs());
00052 
00053    for (size_t i = 0, e = systems.size(); i != e; ++i) {
00054      if (systems[i] != "Reference") {
00055        dbe_->cd();
00056        if (MonitorElement* me = dbe_->get(systems[i] + "/EventInfo/processName")){
00057          dbe_->save(fileBaseName_ + me->getStringValue() + suffix + ".root",
00058                  "" , "^(Reference/)?([^/]+)", rewrite,
00059                  (DQMStore::SaveReferenceTag) saveReference_,
00060                  saveReferenceQMin_);
00061          return;
00062        }
00063      }
00064    }
00065 
00066    // if no EventInfo Folder is found, then store subsystem wise
00067    for (size_t i = 0, e = systems.size(); i != e; ++i)
00068      if (systems[i] != "Reference")
00069          dbe_->save(fileBaseName_ + systems[i] + suffix + ".root",
00070                  systems[i] , "^(Reference/)?([^/]+)", rewrite,
00071                  (DQMStore::SaveReferenceTag) saveReference_,
00072                  saveReferenceQMin_);
00073 
00074 }
00075 
00076 //--------------------------------------------------------
00077 DQMFileSaver::DQMFileSaver(const edm::ParameterSet &ps)
00078   : convention_ (Offline),
00079     workflow_ (""),
00080     producer_ ("DQM"),
00081     dirName_ ("."),
00082     saveByLumiSection_ (-1),
00083     saveByEvent_ (-1),
00084     saveByMinute_ (-1),
00085     saveByTime_ (-1),
00086     saveByRun_ (1),
00087     saveAtJobEnd_ (false),
00088     saveReference_ (DQMStore::SaveWithReferenceForQTest),
00089     saveReferenceQMin_ (dqm::qstatus::STATUS_OK),
00090     forceRunNumber_ (-1),
00091     fileBaseName_ (""),
00092     dbe_ (&*edm::Service<DQMStore>()),
00093     irun_ (-1),
00094     ilumi_ (-1),
00095     ilumiprev_ (-1),
00096     ievent_ (-1),
00097     nrun_ (0),
00098     nlumi_ (0),
00099     nevent_ (0)
00100 {
00101   // Determine the file saving convention, and adjust defaults accordingly.
00102   std::string convention = ps.getUntrackedParameter<std::string>("convention", "Offline");
00103   if (convention == "Offline")
00104     convention_ = Offline;
00105   else if (convention == "Online")
00106     convention_ = Online;
00107   else if (convention == "RelVal")
00108   {
00109     convention_ = RelVal;
00110     saveByRun_ = -1;
00111     saveAtJobEnd_ = true;
00112     forceRunNumber_ = 1;
00113   }
00114   else
00115     throw cms::Exception("DQMFileSaver")
00116       << "Invalid 'convention' parameter '" << convention << "'."
00117       << "  Expected one of 'Online', 'Offline' or 'RelVal'.";
00118 
00119   // If this isn't online convention, check workflow.
00120   if (convention_ != Online)
00121   {
00122     workflow_ = ps.getUntrackedParameter<std::string>("workflow", workflow_);
00123     if (workflow_.empty()
00124         || workflow_[0] != '/'
00125         || *workflow_.rbegin() == '/'
00126         || std::count(workflow_.begin(), workflow_.end(), '/') != 3
00127         || workflow_.find_first_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZ"
00128                                        "abcdefghijklmnopqrstuvwxyz"
00129                                        "0123456789"
00130                                        "-_/") != std::string::npos)
00131       throw cms::Exception("DQMFileSaver")
00132         << "Invalid 'workflow' parameter '" << workflow_
00133         << "'.  Expected '/A/B/C'.";
00134   }
00135   else if (! ps.getUntrackedParameter<std::string>("workflow", "").empty())
00136     throw cms::Exception("DQMFileSaver")
00137       << "The 'workflow' parameter must be empty in 'Online' convention.";
00138 
00139   // Allow file producer to be set to specific values in certain conditions.
00140   producer_ = ps.getUntrackedParameter<std::string>("producer", producer_);
00141   if (convention_ == Online
00142       && producer_ != "DQM"
00143       && producer_ != "HLTDQM"
00144       && producer_ != "Playback")
00145   {
00146     throw cms::Exception("DQMFileSaver")
00147       << "Invalid 'producer' parameter '" << producer_
00148       << "'.  Expected 'DQM', 'HLTDQM' or 'Playback'.";
00149   }
00150   else if (convention_ != Online && producer_ != "DQM")
00151   {
00152     throw cms::Exception("DQMFileSaver")
00153       << "Invalid 'producer' parameter '" << producer_
00154       << "'.  Expected 'DQM'.";
00155   }
00156 
00157   // In RelVal mode use workflow "stream" name instead of producer label.
00158   if (convention_ == RelVal)
00159     producer_ = workflow_.substr(1, workflow_.find('/', 1)-1);
00160 
00161   // Check how we should save the references.
00162   std::string refsave = ps.getUntrackedParameter<std::string>("referenceHandling", "default");
00163   if (refsave == "default")
00164     ;
00165   else if (refsave == "skip")
00166     saveReference_ = DQMStore::SaveWithoutReference;
00167   else if (refsave == "all")
00168     saveReference_ = DQMStore::SaveWithReference;
00169   else if (refsave == "qtests")
00170     saveReference_ = DQMStore::SaveWithReferenceForQTest;
00171   else
00172     throw cms::Exception("DQMFileSaver")
00173       << "Invalid 'referenceHandling' parameter '" << refsave
00174       << "'.  Expected 'default', 'skip', 'all' or 'qtests'.";
00175 
00176   // Check minimum required quality test result for which reference is saved.
00177   saveReferenceQMin_ = ps.getUntrackedParameter<int>("referenceRequireStatus", saveReferenceQMin_);
00178 
00179   // Get and check the output directory.
00180   struct stat s;
00181   dirName_ = ps.getUntrackedParameter<std::string>("dirName", dirName_);
00182   if (dirName_.empty() || stat(dirName_.c_str(), &s) == -1)
00183     throw cms::Exception("DQMFileSaver")
00184       << "Invalid 'dirName' parameter '" << dirName_ << "'.";
00185 
00186   // Find out when and how to save files.  The following contraints apply:
00187   // - For online, allow files to be saved at lumi, event and time intervals.
00188   // - For online and offline, allow files to be saved per run.
00189   // - For offline and relval, allow files to be saved at job end
00190   //   and run number to be overridden (for mc data).
00191   if (convention_ == Online)
00192   {
00193     getAnInt(ps, saveByLumiSection_, "saveByLumiSection");
00194     getAnInt(ps, saveByEvent_, "saveByEvent");
00195     getAnInt(ps, saveByMinute_, "saveByMinute");
00196     getAnInt(ps, saveByTime_, "saveByTime");
00197   }
00198 
00199   if (convention_ == Online || convention_ == Offline)
00200     getAnInt(ps, saveByRun_, "saveByRun");
00201 
00202   if (convention_ != Online)
00203   {
00204     getAnInt(ps, forceRunNumber_, "forceRunNumber");
00205     saveAtJobEnd_ = ps.getUntrackedParameter<bool>("saveAtJobEnd", saveAtJobEnd_);
00206     if (convention_ == RelVal && ! saveAtJobEnd_)
00207       saveAtJobEnd_ = true;
00208     if (convention_ == RelVal && forceRunNumber_ == -1)
00209       forceRunNumber_ = 1;
00210   }
00211 
00212   if (saveAtJobEnd_ && forceRunNumber_ < 1)
00213     throw cms::Exception("DQMFileSaver")
00214       << "If saving at the end of the job, the run number must be"
00215       << " overridden to a specific value using 'forceRunNumber'.";
00216 
00217   // Set up base file name and determine the start time.
00218   fileBaseName_ = dirName_ + "/" + producer_ + "_V0001_";
00219   gettimeofday(&start_, 0);
00220   saved_ = start_;
00221 
00222   // Log some information what we will do.
00223   edm::LogInfo("DQMFileSaver")
00224     << "DQM file saving settings:\n"
00225     << " using base file name '" << fileBaseName_ << "'\n"
00226     << " forcing run number " << forceRunNumber_ << "\n"
00227     << " saving every " << saveByLumiSection_ << " lumi section(s)\n"
00228     << " saving every " << saveByEvent_ << " event(s)\n"
00229     << " saving every " << saveByMinute_ << " minute(s)\n"
00230     << " saving every 2^n*" << saveByTime_ << " minutes \n"
00231     << " saving every " << saveByRun_ << " run(s)\n"
00232     << " saving at job end: " << (saveAtJobEnd_ ? "yes" : "no") << "\n";
00233 }
00234 
00235 //--------------------------------------------------------
00236 void
00237 DQMFileSaver::beginJob(const edm::EventSetup &)
00238 {
00239   irun_ = ilumi_ = ilumiprev_ = ievent_ = -1;
00240   nrun_ = nlumi_ = nevent_ = 0;
00241 }
00242 
00243 void
00244 DQMFileSaver::beginRun(const edm::Run &r, const edm::EventSetup &)
00245 {
00246   irun_     = (forceRunNumber_ == -1 ? r.id().run() : forceRunNumber_);
00247   ++nrun_;
00248 }
00249 
00250 void
00251 DQMFileSaver::beginLuminosityBlock(const edm::LuminosityBlock &l, const edm::EventSetup &)
00252 {
00253   ilumi_    = l.id().luminosityBlock();
00254   if (ilumiprev_ == -1) ilumiprev_ = ilumi_;
00255   ++nlumi_;
00256 }
00257 
00258 void DQMFileSaver::analyze(const edm::Event &e, const edm::EventSetup &)
00259 {
00260   ++nevent_;
00261 
00262   ievent_   = e.id().event();
00263 
00264   // Check if we should save for this event.
00265   char suffix[64];
00266   if (ievent_ > 0 && saveByEvent_ > 0 && nevent_ == saveByEvent_)
00267   {
00268     if (convention_ != Online)
00269       throw cms::Exception("DQMFileSaver")
00270         << "Internal error, can save files by event"
00271         << " only in Online mode.";
00272 
00273     sprintf(suffix, "_R%09d_E%08d", irun_, ievent_);
00274     saveForOnline(suffix, "\\1\\2");
00275     nevent_ = 0;
00276   }
00277 
00278   // Check if we should save due to elapsed time.
00279   if ( ievent_ > 0 && ( saveByMinute_ > 0 || saveByTime_ > 0 ) )
00280   {
00281     if (convention_ != Online)
00282       throw cms::Exception("DQMFileSaver")
00283         << "Internal error, can save files by time"
00284         << " only in Online mode.";
00285 
00286     // Compute elapsed time in minutes.
00287     struct timeval tv;
00288     gettimeofday(&tv, 0);
00289 
00290     double totalelapsed = ((tv.tv_sec + tv.tv_usec*1e-6)
00291                  - (start_.tv_sec + start_.tv_usec*1e-6)) / 60;
00292     double elapsed = ((tv.tv_sec + tv.tv_usec*1e-6)
00293                       - (saved_.tv_sec + saved_.tv_usec*1e-6)) / 60;
00294 
00295     // Save if enough time has elapsed since the last save.
00296     if ( (saveByMinute_ > 0 && elapsed > saveByMinute_ ) ||
00297          (saveByTime_ > 0   && totalelapsed > saveByTime_ ) )
00298     {
00299       if ( saveByTime_ > 0 ) saveByTime_ *= 2;
00300       saved_ = tv;
00301       sprintf(suffix, "_R%09d_T%08d", irun_, int(totalelapsed));
00302       char rewrite[64]; sprintf(rewrite, "\\1Run %d/\\2/Run summary", irun_);
00303       saveForOnline(suffix, rewrite);
00304     }
00305   }
00306 }
00307 
00308 void
00309 DQMFileSaver::endLuminosityBlock(const edm::LuminosityBlock &, const edm::EventSetup &)
00310 {
00311   if (ilumi_ > 0 && saveByLumiSection_ > 0 && nlumi_ == saveByLumiSection_)
00312   {
00313     if (convention_ != Online)
00314       throw cms::Exception("DQMFileSaver")
00315         << "Internal error, can save files at end of lumi block"
00316         << " only in Online mode.";
00317 
00318     char suffix[64];
00319     char rewrite[128];
00320     sprintf(suffix, "_R%09d_L%06d", irun_, ilumi_);
00321     sprintf(rewrite, "\\1Run %d/\\2/By Lumi Section %d-%d", irun_, ilumiprev_, ilumi_);
00322     saveForOnline(suffix, rewrite);
00323     ilumiprev_ = -1;
00324     nlumi_ = 0;
00325   }
00326 }
00327 
00328 void
00329 DQMFileSaver::endRun(const edm::Run &, const edm::EventSetup &)
00330 {
00331   if (irun_ > 0 && saveByRun_ > 0 && nrun_ == saveByRun_)
00332   {
00333     if (convention_ == Online)
00334     {
00335       char suffix[64]; sprintf(suffix, "_R%09d", irun_);
00336       char rewrite[64]; sprintf(rewrite, "\\1Run %d/\\2/Run summary", irun_);
00337       saveForOnline(suffix, rewrite);
00338     }
00339     else if (convention_ == Offline)
00340       saveForOffline(workflow_, irun_);
00341     else
00342       throw cms::Exception("DQMFileSaver")
00343         << "Internal error.  Can only save files in endRun()"
00344         << " in Online and Offline modes.";
00345 
00346     nrun_ = 0;
00347   }
00348 }
00349 
00350 void
00351 DQMFileSaver::endJob(void)
00352 { 
00353   if (saveAtJobEnd_)
00354   {
00355     if (convention_ == RelVal)
00356     {
00357       size_t pos;
00358       std::string release = edm::getReleaseVersion();
00359       while ((pos = release.find('"')) != std::string::npos)
00360         release.erase(pos, 1);
00361 
00362       pos = fileBaseName_.rfind('/');
00363       std::string stream = fileBaseName_.substr(pos+1, fileBaseName_.size()-pos-2);
00364       dbe_->save(fileBaseName_ + release + ".root",
00365                  "", "^(Reference/)?([^/]+)", "\\1" + stream + "/\\2",
00366                  (DQMStore::SaveReferenceTag) saveReference_,
00367                  saveReferenceQMin_);
00368     }
00369     else if (convention_ == Offline && forceRunNumber_ > 0)
00370       saveForOffline(workflow_, forceRunNumber_);
00371     else
00372       throw cms::Exception("DQMFileSaver")
00373         << "Internal error.  Can only save files at the end of the"
00374         << " job in RelVal and Offline modes with run number overridden.";
00375   }
00376 }

Generated on Tue Jun 9 17:34:11 2009 for CMSSW by  doxygen 1.5.4