Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-10-08 05:11:30

0001 // -*- C++ -*-
0002 //
0003 // Package: DQM/TrackerCommon
0004 //
0005 //
0006 /**
0007   \brief    Performs DQM offline data certification for SiStrip, Pixel and Tracking
0008 
0009    Purpose:
0010 
0011    The procedure of certifying data of a given run range is automated in order to speed up the procedure and to reduce the Tracker Offline Shift Leader's workload.
0012 
0013    Input:
0014 
0015    - RunRegistry
0016    - DQM output files available in AFS
0017 
0018    Output:
0019 
0020    Text file
0021    - [as explained for command line option '-o']
0022    to be sent directly to the CMS DQM team as reply to the weekly certification request.
0023    It contains a list of all flags changed with respect to the RunRegistry, including the reason(s) in case the flag is changed to BAD.
0024 
0025    The verbose ('-v') stdout can provide a complete list of all in-/output flags of all analyzed runs and at its end a summary only with the output flags.
0026    It makes sense to pipe the stdout to another text file.
0027 
0028    Usage:
0029 
0030    $ cmsrel CMSSW_RELEASE
0031    $ cd CMSSW_RELEASE/src
0032    $ cmsenv
0033    $ cvs co -r Vxx-yy-zz DQM/TrackerCommon
0034    $ scram b -j 5
0035    $ rehash
0036    $ cd WORKING_DIRECTORY
0037    $ [create input files]
0038    $ TrackerRunCertification [ARGUMENTOPTION1] [ARGUMENT1] ... [OPTION2] ...
0039 
0040    Valid argument options are:
0041      -d
0042        MANDATORY: dataset as in RunRegistry
0043        no default
0044      -g
0045        MANDATORY: group name as in RunRegistry
0046        no default
0047      -p
0048        path to DQM files
0049        default: /afs/cern.ch/cms/CAF/CMSCOMM/COMM_DQM/data/OfflineData/Run2010/StreamExpress
0050      -P
0051        pattern of DQM file names in the DQM file path
0052        default: *[DATASET from '-d' option with '/' --> '__'].root
0053      -o
0054        path to output log file
0055        default: ./trackerRunCertification[DATASET from '-d' option with '/' --> '__']-[GROUP from '-g'].txt
0056      -L
0057        path to file with DQM input file list
0058        default: ./fileList[DATASET from '-d' option with '/' --> '__'].txt
0059      -l
0060        lower bound of run numbers to consider
0061        default: 0
0062      -u
0063        upper bound of run numbers to consider
0064        default: 1073741824 (2^30)
0065      -R
0066        web address of the RunRegistry
0067        default: http://pccmsdqm04.cern.ch/runregistry
0068      The default is used for any option not explicitely given in the command line.
0069 
0070    Valid options are:
0071      -rr
0072        switch on creation of new RR file
0073      -rronly
0074        only create new RR file, do not run certification
0075      -a
0076        certify all runs, not only those in "SIGNOFF" status
0077      -v
0078        switch on verbose logging to stdout
0079      -h
0080        display this help and exit
0081 
0082   \author   Volker Adler
0083 */
0084 
0085 #include <algorithm>
0086 #include <string>
0087 #include <vector>
0088 #include <map>
0089 #include <fstream>
0090 #include <iostream>
0091 #include <sstream>
0092 
0093 // RooT, needs '<use name="root">' in the BuildFile
0094 #include "TROOT.h"
0095 #include "TSystem.h"
0096 #include "TString.h"
0097 #include "TFile.h"
0098 #include "TKey.h"
0099 #include "TXMLEngine.h"  // needs '<flags LDFLAGS="-lXMLIO">' in the BuildFile
0100 
0101 using namespace std;
0102 
0103 // Functions
0104 Bool_t createInputFileList();
0105 Bool_t createRRFile();
0106 Bool_t readData(const TString& pathFile);
0107 Bool_t readRR(const TString& pathFile);
0108 Bool_t readRRLumis(const TString& pathFile);
0109 Bool_t readRRTracker(const TString& pathFile);
0110 Bool_t readDQM(const TString& pathFile);
0111 void readCertificates(TDirectory* dir);
0112 void certifyRunRange();
0113 void certifyRun();
0114 void writeOutput();
0115 void displayHelp();
0116 TString RunNumber(const TString& pathFile);
0117 Int_t FlagConvert(const TString& flag);
0118 TString FlagConvert(const Int_t flag);
0119 
0120 // Configurables
0121 map<TString, TString> sArguments;
0122 map<TString, Bool_t> sOptions;
0123 TString convertDataset_;
0124 Int_t minRange_;
0125 Int_t maxRange_;
0126 Int_t minRun_;
0127 Int_t maxRun_;
0128 
0129 // Global constants
0130 const TString nameFileRR_("RunRegistry.xml");
0131 const TString nameFileRunsRR_(TString("runs").Append(nameFileRR_));
0132 const TString nameFileLumisRR_(TString("lumis").Append(nameFileRR_));
0133 const TString nameFileTrackerRR_(TString("tracker").Append(nameFileRR_));
0134 const TString nameDirHead_("DQMData");
0135 const TString nameDirBase_("EventInfo");
0136 const TString nameDirCert_("CertificationContents");
0137 const TString nameDirReport_("reportSummaryContents");
0138 const TString nameDirDAQ_("DAQContents");
0139 const TString nameDirDCS_("DCSContents");
0140 const TString pathRunFragment_("/Run /");
0141 const UInt_t nSubSys_(3);
0142 const TString sSubSys_[nSubSys_] = {
0143     // sub-system directory names in DQM files
0144     "SiStrip",
0145     "Pixel",
0146     "Tracking",
0147 };
0148 enum SubSystems {  // according enumeration
0149   SiStrip,
0150   Pixel,
0151   Tracking
0152 };
0153 enum Flags {  // flags' enumeration
0154   MISSING = -100,
0155   NOTSET = -99,
0156   EXCL = -1,
0157   BAD = 0,
0158   GOOD = 1
0159 };
0160 const Double_t minGood_(0.95);
0161 const Double_t maxBad_(0.85);
0162 
0163 // Certificates and flags
0164 vector<TString> sRunNumbers_;
0165 UInt_t nRuns_(0);
0166 UInt_t nRunsNotRR_(0);
0167 UInt_t nRunsNotGroup_(0);
0168 UInt_t nRunsNotDataset_(0);
0169 UInt_t nRunsNotSignoff_(0);
0170 UInt_t nRunsNotRRLumis_(0);
0171 UInt_t nRunsNotDatasetLumis_(0);
0172 UInt_t nRunsSiStripOff_(0);
0173 UInt_t nRunsPixelOff_(0);
0174 UInt_t nRunsNotRRTracker_(0);
0175 UInt_t nRunsNotGroupTracker_(0);
0176 UInt_t nRunsNotDatasetTracker_(0);
0177 UInt_t nRunsExclSiStrip_(0);
0178 UInt_t nRunsMissSiStrip_(0);
0179 UInt_t nRunsBadSiStrip_(0);
0180 UInt_t nRunsChangedSiStrip_(0);
0181 map<TString, TString> sSiStrip_;
0182 map<TString, TString> sRRSiStrip_;
0183 map<TString, TString> sRRTrackerSiStrip_;
0184 map<TString, TString> sDQMSiStrip_;
0185 map<TString, vector<TString> > sRunCommentsSiStrip_;
0186 map<TString, TString> sRRCommentsSiStrip_;
0187 map<TString, TString> sRRTrackerCommentsSiStrip_;
0188 UInt_t nRunsExclPixel_(0);
0189 UInt_t nRunsMissPixel_(0);
0190 UInt_t nRunsBadPixel_(0);
0191 UInt_t nRunsChangedPixel_(0);
0192 map<TString, TString> sPixel_;
0193 map<TString, TString> sRRPixel_;
0194 map<TString, TString> sRRTrackerPixel_;
0195 map<TString, TString> sDQMPixel_;
0196 map<TString, vector<TString> > sRunCommentsPixel_;
0197 map<TString, TString> sRRCommentsPixel_;
0198 map<TString, TString> sRRTrackerCommentsPixel_;
0199 UInt_t nRunsNoTracking_(0);
0200 UInt_t nRunsBadTracking_(0);
0201 UInt_t nRunsChangedTracking_(0);
0202 map<TString, TString> sTracking_;
0203 map<TString, TString> sRRTracking_;
0204 map<TString, TString> sRRTrackerTracking_;
0205 map<TString, TString> sDQMTracking_;
0206 map<TString, vector<TString> > sRunCommentsTracking_;
0207 map<TString, TString> sRRCommentsTracking_;
0208 map<TString, TString> sRRTrackerCommentsTracking_;
0209 // Certificates and flags (run-by-run)
0210 TString sRunNumber_;
0211 TString sVersion_;
0212 map<TString, Double_t> fCertificates_;
0213 map<TString, Int_t> iFlagsRR_;
0214 map<TString, Int_t> iFlagsRRTracker_;
0215 map<TString, Bool_t> bAvailable_;
0216 Bool_t bSiStripOn_;
0217 Bool_t bPixelOn_;
0218 
0219 /// Checks arguments and runs input check/creation and run certification incl. output
0220 int main(int argc, char* argv[]) {
0221   cout << endl;
0222 
0223   // Initialize defaults
0224   sArguments["-d"] = "";  // dataset
0225   sArguments["-g"] = "";  // group
0226   sArguments["-p"] =
0227       "/afs/cern.ch/cms/CAF/CMSCOMM/COMM_DQM/data/OfflineData/Run2010/StreamExpress";  // path to DQM files
0228   sArguments["-P"] = "";            // pattern of DQM file names in the DQM file path
0229   sArguments["-l"] = "0";           // lower bound of run numbers to consider
0230   sArguments["-u"] = "1073741824";  // 2^30                                 // upper bound of run numbers to consider
0231   sArguments["-o"] = "";            // path to main output file
0232   sArguments["-L"] = "";            // path to file with DQM input file list
0233   sArguments["-R"] = "http://pccmsdqm04.cern.ch/runregistry";  // web address of the RunRegistry
0234   minRun_ = sArguments["-u"].Atoi();
0235   maxRun_ = sArguments["-l"].Atoi();
0236   sOptions["-rr"] = kFALSE;
0237   sOptions["-rronly"] = kFALSE;
0238   sOptions["-a"] = kFALSE;
0239   sOptions["-v"] = kFALSE;
0240   sOptions["-h"] = kFALSE;
0241 
0242   // Input arguments (very simple)
0243   if (argc == 1) {
0244     displayHelp();
0245     return 0;
0246   }
0247   for (int iArgument = 1; iArgument < argc; ++iArgument) {
0248     if (sArguments.find(argv[iArgument]) != sArguments.end()) {
0249       if (sArguments.find(argv[iArgument + 1]) == sArguments.end() &&
0250           sOptions.find(argv[iArgument + 1]) == sOptions.end()) {
0251         sArguments[argv[iArgument]] = argv[iArgument + 1];
0252       }
0253     } else if (sOptions.find(argv[iArgument]) != sOptions.end()) {
0254       sOptions[argv[iArgument]] = kTRUE;
0255     }
0256   }
0257   if (sOptions["-h"]) {
0258     displayHelp();
0259     return 0;
0260   }
0261   if (sArguments["-d"] == "") {
0262     cerr << "    ERROR: no dataset given with '-d' option" << endl;
0263     return 1;
0264   }
0265   if (sArguments["-g"] == "" && !sOptions["-rronly"]) {
0266     cerr << "    ERROR: no group name given with '-g' option" << endl;
0267     return 1;
0268   }
0269   convertDataset_ = sArguments["-d"];
0270   convertDataset_.ReplaceAll("/", "__");
0271   if (sArguments["-o"] == "") {
0272     sArguments["-o"] = TString("trackerRunCertification" + convertDataset_ + "-" + sArguments["-g"] + ".txt");
0273   }
0274   if (sArguments["-L"] == "") {
0275     sArguments["-L"] = TString("fileList" + convertDataset_ + ".txt");
0276   }
0277   if (sArguments["-P"] == "") {
0278     sArguments["-P"] = TString("*" + convertDataset_ + ".root");
0279   }
0280   minRange_ = sArguments["-l"].Atoi();
0281   maxRange_ = sArguments["-u"].Atoi();
0282 
0283   // Run
0284   if (!createInputFileList())
0285     return 12;
0286   if (sOptions["-rronly"]) {
0287     if (!createRRFile())
0288       return 13;
0289     return 0;
0290   }
0291   if (sOptions["-rr"] && !createRRFile())
0292     return 13;
0293   certifyRunRange();
0294 
0295   return 0;
0296 }
0297 
0298 /// Checks for DQM RooT files in pre-defined directory, compares to optinally given run range and writes the resulting file list to a file
0299 /// Returns 'kTRUE', if DQM files for the given run range and path have been found, 'kFALSE' otherwise.
0300 Bool_t createInputFileList() {
0301   // Create input file list on the fly
0302   gSystem->Exec(TString("rm -f " + sArguments["-L"]).Data());
0303   gSystem->Exec(TString("ls -1 " + sArguments["-p"] + "/*/" + sArguments["-P"] + " > " + sArguments["-L"]).Data());
0304   ofstream fileListWrite;
0305   fileListWrite.open(sArguments["-L"].Data(), ios_base::app);
0306   fileListWrite << "EOF";
0307   fileListWrite.close();
0308 
0309   // Loop over input file list and recreate it according to run range
0310   ifstream fileListRead;
0311   fileListRead.open(sArguments["-L"].Data());
0312   ofstream fileListNewWrite;
0313   const TString nameFileListNew(sArguments["-L"] + ".new");
0314   fileListNewWrite.open(nameFileListNew, ios_base::app);
0315   UInt_t nFiles(0);
0316   while (fileListRead.good()) {
0317     TString pathFile;
0318     fileListRead >> pathFile;
0319     if (pathFile.Length() == 0)
0320       continue;
0321     sRunNumber_ = RunNumber(pathFile);
0322     if (!RunNumber(pathFile).IsDigit())
0323       continue;
0324     ++nFiles;
0325     const Int_t iRun(RunNumber(pathFile).Atoi());
0326     if (minRange_ > iRun || iRun > maxRange_)
0327       continue;
0328     fileListNewWrite << pathFile << endl;
0329     if (iRun < minRun_)
0330       minRun_ = iRun;
0331     if (iRun > maxRun_)
0332       maxRun_ = iRun;
0333   }
0334 
0335   fileListRead.close();
0336   fileListNewWrite.close();
0337   gSystem->Exec(TString("mv ").Append(nameFileListNew).Append(" ").Append(sArguments["-L"]));
0338 
0339   if (nFiles == 0 || maxRun_ < minRun_) {
0340     cerr << "  ERROR: no files to certify" << endl;
0341     cerr << "  no files found in " << sArguments["-p"] << " between the run numbers " << minRange_ << " and "
0342          << maxRange_ << endl;
0343     return kFALSE;
0344   }
0345   return kTRUE;
0346 }
0347 
0348 /// Gets XML file with complete RunRegistry information from the web server
0349 /// Returns 'kTRUE', if XML file is present and not empty, 'kFALSE' otherwise.
0350 Bool_t createRRFile() {
0351   ostringstream minRun;
0352   minRun << minRun_;
0353   ostringstream maxRun;
0354   maxRun << maxRun_;
0355   cerr << "  Extracting RunRegistry output for runs " << minRun.str() << " - " << maxRun.str() << " ...";
0356   TString commandBase(TString(gSystem->Getenv("CMSSW_BASE"))
0357                           .Append("/src/DQM/TrackerCommon/bin/getRunRegistry.py")
0358                           .Append(" -s ")
0359                           .Append(sArguments["-R"])
0360                           .Append("/xmlrpc")
0361                           .Append(" ")
0362                           .Append(" -l ")
0363                           .Append(minRun.str())
0364                           .Append(" -u ")
0365                           .Append(maxRun.str()));
0366   TString commandRuns(commandBase);
0367   commandRuns.Append(" -f ").Append(nameFileRunsRR_).Append(" -T RUN -t xml_all");
0368   if (sOptions["-v"])
0369     cerr << endl << endl << "    " << commandRuns.Data() << endl;
0370   gSystem->Exec(commandRuns);
0371   TString commandLumis(commandBase);
0372   commandLumis.Append(" -f ").Append(nameFileLumisRR_).Append(" -T RUNLUMISECTION -t xml");
0373   if (sOptions["-v"])
0374     cerr << "    " << commandLumis.Data() << endl;
0375   gSystem->Exec(commandLumis);
0376   TString commandTracker(commandBase);
0377   commandTracker.Append(" -f ").Append(nameFileTrackerRR_).Append(" -T RUN -t xml_all -w TRACKER");
0378   if (sOptions["-v"])
0379     cerr << "    " << commandTracker.Data() << endl << endl << "  ...";
0380   gSystem->Exec(commandTracker);
0381   cerr << " done!" << endl << endl;
0382 
0383   const UInt_t maxLength(131071);  // FIXME hard-coding for what?
0384   char xmlLine[maxLength];
0385   UInt_t lines(0);
0386   ifstream fileRunsRR;
0387   fileRunsRR.open(nameFileRunsRR_.Data());
0388   if (!fileRunsRR) {
0389     cerr << "  ERROR: RR file " << nameFileRunsRR_.Data() << " does not exist" << endl;
0390     cerr << "  Please, check access to RR" << endl;
0391     return kFALSE;
0392   }
0393   while (lines <= 1 && fileRunsRR.getline(xmlLine, maxLength))
0394     ++lines;
0395   if (lines <= 1) {
0396     cerr << "  ERROR: empty RR file " << nameFileRunsRR_.Data() << endl;
0397     cerr << "  Please, check access to RR:" << endl;
0398     cerr << "  - DQM/TrackerCommon/bin/getRunRegistry.py" << endl;
0399     cerr << "  - https://twiki.cern.ch/twiki/bin/view/CMS/DqmRrApi" << endl;
0400     return kFALSE;
0401   }
0402   fileRunsRR.close();
0403   ifstream fileLumisRR;
0404   fileLumisRR.open(nameFileLumisRR_.Data());
0405   if (!fileLumisRR) {
0406     cerr << "  ERROR: RR file " << nameFileLumisRR_.Data() << " does not exist" << endl;
0407     cerr << "  Please, check access to RR" << endl;
0408     return kFALSE;
0409   }
0410   while (lines <= 1 && fileLumisRR.getline(xmlLine, maxLength))
0411     ++lines;
0412   if (lines <= 1) {
0413     cerr << "  ERROR: empty RR file " << nameFileLumisRR_.Data() << endl;
0414     cerr << "  Please, check access to RR:" << endl;
0415     cerr << "  - DQM/TrackerCommon/bin/getRunRegistry.py" << endl;
0416     cerr << "  - https://twiki.cern.ch/twiki/bin/view/CMS/DqmRrApi" << endl;
0417     return kFALSE;
0418   }
0419   fileLumisRR.close();
0420   ifstream fileTrackerRR;
0421   fileTrackerRR.open(nameFileTrackerRR_.Data());
0422   if (!fileTrackerRR) {
0423     cerr << "  ERROR: RR file " << nameFileTrackerRR_.Data() << " does not exist" << endl;
0424     cerr << "  Please, check access to RR" << endl;
0425     return kFALSE;
0426   }
0427   while (lines <= 1 && fileTrackerRR.getline(xmlLine, maxLength))
0428     ++lines;
0429   if (lines <= 1) {
0430     cerr << "  ERROR: empty RR file " << nameFileTrackerRR_.Data() << endl;
0431     cerr << "  Please, check access to RR:" << endl;
0432     cerr << "  - DQM/TrackerCommon/bin/getRunRegistry.py" << endl;
0433     cerr << "  - https://twiki.cern.ch/twiki/bin/view/CMS/DqmRrApi" << endl;
0434     return kFALSE;
0435   }
0436   fileTrackerRR.close();
0437 
0438   return kTRUE;
0439 }
0440 
0441 /// Loops over runs
0442 void certifyRunRange() {
0443   // Loop over runs
0444   ifstream fileListRead;
0445   fileListRead.open(sArguments["-L"].Data());
0446   while (fileListRead.good()) {
0447     TString pathFile;
0448     fileListRead >> pathFile;
0449     if (pathFile.Length() == 0)
0450       continue;
0451     ++nRuns_;
0452     sRunNumber_ = RunNumber(pathFile);
0453     cout << "  Processing RUN " << sRunNumber_.Data() << endl;
0454     if (readData(pathFile)) {
0455       sRunNumbers_.push_back(sRunNumber_);
0456       certifyRun();
0457     }
0458   }
0459   fileListRead.close();
0460   writeOutput();
0461 
0462   return;
0463 }
0464 
0465 /// Reads input data for a given run
0466 /// Returns 'kTRUE', if RR and DQM information have been read successfully, 'kFALSE' otherwise.
0467 Bool_t readData(const TString& pathFile) {
0468   if (!readRR(pathFile))
0469     return kFALSE;
0470   //   if ( ! readRRLumis( pathFile ) )   return kFALSE; // LS currently not used
0471   if (!readRRTracker(pathFile))
0472     return kFALSE;
0473   if (!readDQM(pathFile))
0474     return kFALSE;
0475   return kTRUE;
0476 }
0477 
0478 /// Reads manually set RR certification flags for a given run
0479 /// Returns 'kTRUE', if a given run is present in RR, 'kFALSE' otherwise.
0480 Bool_t readRR(const TString& pathFile) {
0481   // Initialize
0482   map<TString, TString> sFlagsRR;
0483   map<TString, TString> sCommentsRR;
0484   iFlagsRR_.clear();
0485   Bool_t foundRun(kFALSE);
0486   Bool_t foundGroup(kFALSE);
0487   Bool_t foundDataset(kFALSE);
0488   Bool_t foundSignoff(kFALSE);
0489   vector<TString> nameCmpNode;
0490   nameCmpNode.push_back("STRIP");
0491   nameCmpNode.push_back("PIX");
0492   nameCmpNode.push_back("TRACK");
0493 
0494   // Read RR file corresponding to output format type 'xml_all'
0495   TXMLEngine* xmlRR(new TXMLEngine);
0496   XMLDocPointer_t xmlRRDoc(xmlRR->ParseFile(nameFileRunsRR_.Data()));
0497   XMLNodePointer_t nodeMain(xmlRR->DocGetRootElement(xmlRRDoc));
0498   XMLNodePointer_t nodeRun(xmlRR->GetChild(nodeMain));
0499   while (nodeRun) {
0500     XMLNodePointer_t nodeRunChild(xmlRR->GetChild(nodeRun));
0501     while (nodeRunChild && TString(xmlRR->GetNodeName(nodeRunChild)) != "NUMBER")
0502       nodeRunChild = xmlRR->GetNext(nodeRunChild);
0503     if (nodeRunChild && xmlRR->GetNodeContent(nodeRunChild) == sRunNumber_) {
0504       foundRun = kTRUE;
0505       nodeRunChild = xmlRR->GetChild(nodeRun);
0506       while (nodeRunChild && TString(xmlRR->GetNodeName(nodeRunChild)) != "GROUP_NAME")
0507         nodeRunChild = xmlRR->GetNext(nodeRunChild);
0508       if (nodeRunChild && xmlRR->GetNodeContent(nodeRunChild) == sArguments["-g"]) {
0509         foundGroup = kTRUE;
0510         nodeRunChild = xmlRR->GetChild(nodeRun);
0511         while (nodeRunChild && TString(xmlRR->GetNodeName(nodeRunChild)) != "DATASETS")
0512           nodeRunChild = xmlRR->GetNext(nodeRunChild);
0513         if (nodeRunChild) {
0514           XMLNodePointer_t nodeDataset(xmlRR->GetChild(nodeRunChild));
0515           while (nodeDataset) {
0516             XMLNodePointer_t nodeDatasetChild(xmlRR->GetChild(nodeDataset));
0517             while (nodeDatasetChild && TString(xmlRR->GetNodeName(nodeDatasetChild)) != "NAME")
0518               nodeDatasetChild = xmlRR->GetNext(nodeDatasetChild);
0519             if (nodeDatasetChild && TString(xmlRR->GetNodeContent(nodeDatasetChild)) == sArguments["-d"]) {
0520               foundDataset = kTRUE;
0521               nodeDatasetChild = xmlRR->GetChild(nodeDataset);
0522               while (nodeDatasetChild && xmlRR->GetNodeName(nodeDatasetChild) != TString("STATE"))
0523                 nodeDatasetChild = xmlRR->GetNext(nodeDatasetChild);
0524               if (sOptions["-a"] ||
0525                   (nodeDatasetChild && TString(xmlRR->GetNodeContent(nodeDatasetChild)) == "SIGNOFF")) {
0526                 foundSignoff = kTRUE;
0527                 nodeDatasetChild = xmlRR->GetChild(nodeDataset);
0528                 while (nodeDatasetChild && TString(xmlRR->GetNodeName(nodeDatasetChild)) != "CMPS")
0529                   nodeDatasetChild = xmlRR->GetNext(nodeDatasetChild);
0530                 if (nodeDatasetChild) {
0531                   XMLNodePointer_t nodeCmp(xmlRR->GetChild(nodeDatasetChild));
0532                   while (nodeCmp) {
0533                     XMLNodePointer_t nodeCmpChild(xmlRR->GetChild(nodeCmp));
0534                     while (nodeCmpChild && TString(xmlRR->GetNodeName(nodeCmpChild)) != "NAME")
0535                       nodeCmpChild = xmlRR->GetNext(nodeCmpChild);
0536                     if (nodeCmpChild) {
0537                       for (UInt_t iNameNode = 0; iNameNode < nameCmpNode.size(); ++iNameNode) {
0538                         if (xmlRR->GetNodeContent(nodeCmpChild) == nameCmpNode.at(iNameNode)) {
0539                           TString nameNode("RR_" + nameCmpNode.at(iNameNode));
0540                           XMLNodePointer_t nodeCmpChildNew = xmlRR->GetChild(nodeCmp);
0541                           while (nodeCmpChildNew && TString(xmlRR->GetNodeName(nodeCmpChildNew)) != "VALUE")
0542                             nodeCmpChildNew = xmlRR->GetNext(nodeCmpChildNew);
0543                           if (nodeCmpChildNew) {
0544                             sFlagsRR[nameNode] = TString(xmlRR->GetNodeContent(nodeCmpChildNew));
0545                             if (sFlagsRR[nameNode] == "BAD") {
0546                               nodeCmpChildNew = xmlRR->GetChild(nodeCmp);
0547                               while (nodeCmpChildNew && TString(xmlRR->GetNodeName(nodeCmpChildNew)) != "COMMENT")
0548                                 nodeCmpChildNew = xmlRR->GetNext(nodeCmpChildNew);
0549                               if (nodeCmpChildNew) {
0550                                 sCommentsRR[nameNode] = TString(xmlRR->GetNodeContent(nodeCmpChildNew));
0551                               }
0552                             }
0553                           }
0554                         }
0555                       }
0556                     }
0557                     nodeCmp = xmlRR->GetNext(nodeCmp);
0558                   }
0559                 }
0560                 break;
0561               }
0562               break;
0563             }
0564             nodeDataset = xmlRR->GetNext(nodeDataset);
0565           }
0566         }
0567       }
0568       break;
0569     }
0570     nodeRun = xmlRR->GetNext(nodeRun);
0571   }
0572 
0573   if (!foundRun) {
0574     ++nRunsNotRR_;
0575     cout << "    Run not found in RR" << endl;
0576     return kFALSE;
0577   }
0578   if (!foundGroup) {
0579     ++nRunsNotGroup_;
0580     cout << "    Group " << sArguments["-g"] << " not found in RR" << endl;
0581     return kFALSE;
0582   }
0583   if (!foundDataset) {
0584     ++nRunsNotDataset_;
0585     cout << "    Dataset " << sArguments["-d"] << " not found in RR" << endl;
0586     return kFALSE;
0587   }
0588   if (!foundSignoff) {
0589     ++nRunsNotSignoff_;
0590     cout << "    Dataset not in SIGNOFF in RR" << endl;
0591     return kFALSE;
0592   }
0593 
0594   if (sOptions["-v"])
0595     for (map<TString, TString>::const_iterator flag = sFlagsRR.begin(); flag != sFlagsRR.end(); ++flag)
0596       cout << "    " << flag->first << ": " << flag->second << endl;
0597   for (UInt_t iNameNode = 0; iNameNode < nameCmpNode.size(); ++iNameNode) {
0598     TString nameNode("RR_" + nameCmpNode.at(iNameNode));
0599     if (sFlagsRR.find(nameNode) == sFlagsRR.end()) {
0600       cout << "    WARNING: component " << nameCmpNode.at(iNameNode).Data() << " not found in RR" << endl;
0601       cout << "    Automatically set to MISSING" << endl;
0602       sFlagsRR[nameNode] = "MISSING";
0603     }
0604   }
0605 
0606   sRRCommentsSiStrip_[sRunNumber_] = sCommentsRR["RR_STRIP"];
0607   sRRCommentsPixel_[sRunNumber_] = sCommentsRR["RR_PIX"];
0608   sRRCommentsTracking_[sRunNumber_] = sCommentsRR["RR_TRACK"];
0609   iFlagsRR_[sSubSys_[SiStrip]] = FlagConvert(sFlagsRR["RR_STRIP"]);
0610   iFlagsRR_[sSubSys_[Pixel]] = FlagConvert(sFlagsRR["RR_PIX"]);
0611   iFlagsRR_[sSubSys_[Tracking]] = FlagConvert(sFlagsRR["RR_TRACK"]);
0612   if (iFlagsRR_[sSubSys_[SiStrip]] == EXCL)
0613     ++nRunsExclSiStrip_;
0614   if (iFlagsRR_[sSubSys_[Pixel]] == EXCL)
0615     ++nRunsExclPixel_;
0616   if (iFlagsRR_[sSubSys_[SiStrip]] == MISSING)
0617     ++nRunsMissSiStrip_;
0618   if (iFlagsRR_[sSubSys_[Pixel]] == MISSING)
0619     ++nRunsMissPixel_;
0620   if ((iFlagsRR_[sSubSys_[SiStrip]] == EXCL || iFlagsRR_[sSubSys_[SiStrip]] == MISSING) &&
0621       (iFlagsRR_[sSubSys_[Pixel]] == EXCL || iFlagsRR_[sSubSys_[Pixel]] == MISSING))
0622     ++nRunsNoTracking_;
0623 
0624   return kTRUE;
0625 }
0626 
0627 /// Reads RR HV states for lumi ranges in a given run
0628 /// Returns 'kFALSE', if Tracker was in STANDBY during the run, 'kTRUE' otherwise.
0629 Bool_t readRRLumis(const TString& pathFile) {
0630   bSiStripOn_ = false;
0631   bPixelOn_ = false;
0632   map<TString, Bool_t> bLumiSiStripOn_;
0633   map<TString, Bool_t> bLumiPixelOn_;
0634   Bool_t foundRun(kFALSE);
0635   Bool_t foundDataset(kFALSE);
0636 
0637   // Read RR file corresponding to output format type 'xml'
0638   TXMLEngine* xmlRR(new TXMLEngine);
0639   XMLDocPointer_t xmlRRDoc(xmlRR->ParseFile(nameFileLumisRR_.Data()));
0640   XMLNodePointer_t nodeMain(xmlRR->DocGetRootElement(xmlRRDoc));
0641   XMLNodePointer_t nodeRun(xmlRR->GetChild(nodeMain));
0642   while (nodeRun) {
0643     XMLNodePointer_t nodeRunChild(xmlRR->GetChild(nodeRun));
0644     while (nodeRunChild && TString(xmlRR->GetNodeName(nodeRunChild)) != "NUMBER")
0645       nodeRunChild = xmlRR->GetNext(nodeRunChild);
0646     if (nodeRunChild && xmlRR->GetNodeContent(nodeRunChild) == sRunNumber_) {
0647       foundRun = kTRUE;
0648       nodeRunChild = xmlRR->GetChild(nodeRun);
0649       while (nodeRunChild && TString(xmlRR->GetNodeName(nodeRunChild)) != "DATASET")
0650         nodeRunChild = xmlRR->GetNext(nodeRunChild);
0651       if (nodeRunChild) {
0652         XMLNodePointer_t nodeDatasetChild(xmlRR->GetChild(nodeRunChild));
0653         while (nodeDatasetChild && TString(xmlRR->GetNodeName(nodeDatasetChild)) != "NAME")
0654           nodeDatasetChild = xmlRR->GetNext(nodeDatasetChild);
0655         if (nodeDatasetChild && xmlRR->GetNodeContent(nodeDatasetChild) == sArguments["-d"]) {
0656           foundDataset = kTRUE;
0657           XMLNodePointer_t nodeLumiRange(xmlRR->GetChild(nodeRunChild));
0658           while (nodeLumiRange) {
0659             bLumiSiStripOn_["DCSTIBTID"] = kFALSE;
0660             bLumiSiStripOn_["DCSTOB"] = kFALSE;
0661             bLumiSiStripOn_["DCSTECM"] = kFALSE;
0662             bLumiSiStripOn_["DCSTECP"] = kFALSE;
0663             bLumiPixelOn_["DCSFPIX"] = kFALSE;
0664             bLumiPixelOn_["DCSBPIX"] = kFALSE;
0665             if (TString(xmlRR->GetNodeName(nodeLumiRange)) == "LUMI_SECTION_RANGE") {
0666               XMLNodePointer_t nodeLumiRangeChild(xmlRR->GetChild(nodeLumiRange));
0667               while (nodeLumiRangeChild && TString(xmlRR->GetNodeName(nodeLumiRangeChild)) != "PARAMETERS")
0668                 nodeLumiRangeChild = xmlRR->GetNext(nodeLumiRangeChild);
0669               if (nodeLumiRangeChild) {
0670                 XMLNodePointer_t nodeParameter(xmlRR->GetChild(nodeLumiRangeChild));
0671                 while (nodeParameter) {
0672                   if (xmlRR->GetNodeContent(nodeParameter) && xmlRR->GetNodeContent(nodeParameter) == TString("true")) {
0673                     const TString nodeName(xmlRR->GetNodeName(nodeParameter));
0674                     if (bLumiSiStripOn_.find(nodeName) != bLumiSiStripOn_.end()) {
0675                       bLumiSiStripOn_[nodeName] = kTRUE;
0676                     } else if (bLumiPixelOn_.find(nodeName) != bLumiPixelOn_.end()) {
0677                       bLumiPixelOn_[nodeName] = kTRUE;
0678                     }
0679                   }
0680                   nodeParameter = xmlRR->GetNext(nodeParameter);
0681                 }
0682               }
0683             }
0684             Bool_t siStripOn(kTRUE);
0685             Bool_t pixelOn(kTRUE);
0686             for (map<TString, Bool_t>::const_iterator iMap = bLumiSiStripOn_.begin(); iMap != bLumiSiStripOn_.end();
0687                  ++iMap) {
0688               if (!iMap->second)
0689                 siStripOn = kFALSE;
0690               break;
0691             }
0692             for (map<TString, Bool_t>::const_iterator iMap = bLumiPixelOn_.begin(); iMap != bLumiPixelOn_.end();
0693                  ++iMap) {
0694               if (!iMap->second)
0695                 pixelOn = kFALSE;
0696               break;
0697             }
0698             if (siStripOn)
0699               bSiStripOn_ = kTRUE;
0700             if (pixelOn)
0701               bPixelOn_ = kTRUE;
0702             if (bSiStripOn_ && bPixelOn_)
0703               break;
0704             nodeLumiRange = xmlRR->GetNext(nodeLumiRange);
0705           }
0706           break;
0707         }
0708       }
0709       break;
0710     }
0711     nodeRun = xmlRR->GetNext(nodeRun);
0712   }
0713 
0714   if (!foundRun) {
0715     ++nRunsNotRRLumis_;
0716     cout << "    Run " << sRunNumber_ << " not found in RR lumis" << endl;
0717     return kFALSE;
0718   }
0719   if (!foundDataset) {
0720     ++nRunsNotDatasetLumis_;
0721     cout << "    Dataset " << sArguments["-d"] << " not found in RR lumis" << endl;
0722     return kFALSE;
0723   }
0724   if (!bSiStripOn_) {
0725     ++nRunsSiStripOff_;
0726     cout << "    SiStrip (partially) OFF during the whole run" << endl;
0727   }
0728   if (!bPixelOn_) {
0729     ++nRunsPixelOff_;
0730     cout << "    Pixel (partially) OFF during the whole run" << endl;
0731   }
0732 
0733   return kTRUE;
0734 }
0735 
0736 /// Reads RR certification flags for lumi ranges in a given run
0737 /// Returns 'kTRUE', if a given run is present in RR, 'kFALSE' otherwise.
0738 Bool_t readRRTracker(const TString& pathFile) {
0739   map<TString, TString> sFlagsRRTracker;
0740   map<TString, TString> sCommentsRRTracker;
0741   iFlagsRRTracker_.clear();
0742   Bool_t foundRun(kFALSE);
0743   Bool_t foundGroup(kFALSE);
0744   Bool_t foundDataset(kFALSE);
0745   vector<TString> nameCmpNode;
0746   nameCmpNode.push_back("STRIP");
0747   nameCmpNode.push_back("PIXEL");
0748   nameCmpNode.push_back("TRACKING");
0749 
0750   // Read RR file corresponding to output format type 'xml'
0751   TXMLEngine* xmlRR(new TXMLEngine);
0752   XMLDocPointer_t xmlRRDoc(xmlRR->ParseFile(nameFileTrackerRR_.Data()));
0753   XMLNodePointer_t nodeMain(xmlRR->DocGetRootElement(xmlRRDoc));
0754   XMLNodePointer_t nodeRun(xmlRR->GetChild(nodeMain));
0755   while (nodeRun) {
0756     XMLNodePointer_t nodeRunChild(xmlRR->GetChild(nodeRun));
0757     while (nodeRunChild && TString(xmlRR->GetNodeName(nodeRunChild)) != "NUMBER")
0758       nodeRunChild = xmlRR->GetNext(nodeRunChild);
0759     if (nodeRunChild && xmlRR->GetNodeContent(nodeRunChild) == sRunNumber_) {
0760       foundRun = kTRUE;
0761       nodeRunChild = xmlRR->GetChild(nodeRun);
0762       while (nodeRunChild && TString(xmlRR->GetNodeName(nodeRunChild)) != "GROUP_NAME")
0763         nodeRunChild = xmlRR->GetNext(nodeRunChild);
0764       if (nodeRunChild && xmlRR->GetNodeContent(nodeRunChild) == sArguments["-g"]) {
0765         foundGroup = kTRUE;
0766         nodeRunChild = xmlRR->GetChild(nodeRun);
0767         while (nodeRunChild && TString(xmlRR->GetNodeName(nodeRunChild)) != "DATASETS")
0768           nodeRunChild = xmlRR->GetNext(nodeRunChild);
0769         if (nodeRunChild) {
0770           XMLNodePointer_t nodeDataset(xmlRR->GetChild(nodeRunChild));
0771           while (nodeDataset) {
0772             XMLNodePointer_t nodeDatasetChild(xmlRR->GetChild(nodeDataset));
0773             while (nodeDatasetChild && TString(xmlRR->GetNodeName(nodeDatasetChild)) != "NAME")
0774               nodeDatasetChild = xmlRR->GetNext(nodeDatasetChild);
0775             //             if ( nodeDatasetChild && TString( xmlRR->GetNodeContent( nodeDatasetChild ) ) == sArguments[ "-d" ] ) {
0776             if (nodeDatasetChild &&
0777                 TString(xmlRR->GetNodeContent(nodeDatasetChild)) ==
0778                     TString("/Global/Online/ALL")) {  // currently cretaed under this dataset name in RR TRACKER
0779               foundDataset = kTRUE;
0780               nodeDatasetChild = xmlRR->GetChild(nodeDataset);
0781               while (nodeDatasetChild && TString(xmlRR->GetNodeName(nodeDatasetChild)) != "CMPS")
0782                 nodeDatasetChild = xmlRR->GetNext(nodeDatasetChild);
0783               if (nodeDatasetChild) {
0784                 XMLNodePointer_t nodeCmp(xmlRR->GetChild(nodeDatasetChild));
0785                 while (nodeCmp) {
0786                   XMLNodePointer_t nodeCmpChild(xmlRR->GetChild(nodeCmp));
0787                   while (nodeCmpChild && TString(xmlRR->GetNodeName(nodeCmpChild)) != "NAME")
0788                     nodeCmpChild = xmlRR->GetNext(nodeCmpChild);
0789                   if (nodeCmpChild) {
0790                     for (UInt_t iNameNode = 0; iNameNode < nameCmpNode.size(); ++iNameNode) {
0791                       if (xmlRR->GetNodeContent(nodeCmpChild) == nameCmpNode.at(iNameNode)) {
0792                         TString nameNode("RRTracker_" + nameCmpNode.at(iNameNode));
0793                         XMLNodePointer_t nodeCmpChildNew(xmlRR->GetChild(nodeCmp));
0794                         while (nodeCmpChildNew && TString(xmlRR->GetNodeName(nodeCmpChildNew)) != "VALUE")
0795                           nodeCmpChildNew = xmlRR->GetNext(nodeCmpChildNew);
0796                         if (nodeCmpChildNew) {
0797                           sFlagsRRTracker[nameNode] = TString(xmlRR->GetNodeContent(nodeCmpChildNew));
0798                           if (sFlagsRRTracker[nameNode] == "BAD") {
0799                             nodeCmpChildNew = xmlRR->GetChild(nodeCmp);
0800                             while (nodeCmpChildNew && TString(xmlRR->GetNodeName(nodeCmpChildNew)) != "COMMENT")
0801                               nodeCmpChildNew = xmlRR->GetNext(nodeCmpChildNew);  // FIXME Segmentation violation???
0802                             if (nodeCmpChildNew) {
0803                               sCommentsRRTracker[nameNode] = TString(xmlRR->GetNodeContent(nodeCmpChildNew));
0804                             }
0805                           }
0806                         }
0807                       }
0808                     }
0809                   }
0810                   nodeCmp = xmlRR->GetNext(nodeCmp);
0811                 }
0812               }
0813               break;
0814             }
0815             nodeDataset = xmlRR->GetNext(nodeDataset);
0816           }
0817         }
0818       }
0819       break;
0820     }
0821     nodeRun = xmlRR->GetNext(nodeRun);
0822   }
0823 
0824   if (!foundRun) {
0825     ++nRunsNotRRTracker_;
0826     cout << "    Run " << sRunNumber_ << " not found in RR Tracker" << endl;
0827     return kFALSE;
0828   }
0829   if (!foundGroup) {
0830     ++nRunsNotGroupTracker_;
0831     cout << "    Group " << sArguments["-g"] << " not found in RR" << endl;
0832     return kFALSE;
0833   }
0834   if (!foundDataset) {
0835     ++nRunsNotDatasetTracker_;
0836     cout << "    Dataset " << sArguments["-d"] << " not found in RR Tracker" << endl;
0837     return kFALSE;
0838   }
0839 
0840   sRRTrackerCommentsSiStrip_[sRunNumber_] = sCommentsRRTracker["RRTracker_STRIP"];
0841   sRRTrackerCommentsPixel_[sRunNumber_] = sCommentsRRTracker["RRTracker_PIXEL"];
0842   sRRTrackerCommentsTracking_[sRunNumber_] = sCommentsRRTracker["RRTracker_TRACKING"];
0843   iFlagsRRTracker_[sSubSys_[SiStrip]] = FlagConvert(sFlagsRRTracker["RRTracker_STRIP"]);
0844   iFlagsRRTracker_[sSubSys_[Pixel]] = FlagConvert(sFlagsRRTracker["RRTracker_PIXEL"]);
0845   iFlagsRRTracker_[sSubSys_[Tracking]] = FlagConvert(sFlagsRRTracker["RRTracker_TRACKING"]);
0846 
0847   return kTRUE;
0848 }
0849 
0850 /// Reads automatically created certification flags/values from the DQM file for a given run
0851 /// Returns 'kTRUE', if the DQM file is readable, 'kFALSE' otherwise.
0852 Bool_t readDQM(const TString& pathFile) {
0853   // Initialize
0854   fCertificates_.clear();
0855   bAvailable_.clear();
0856 
0857   // Open DQM file
0858   TFile* fileDQM(TFile::Open(pathFile.Data()));
0859   if (!fileDQM) {
0860     cerr << "    ERROR: DQM file not found" << endl;
0861     cerr << "    Please, check path to DQM files" << endl;
0862     return kFALSE;
0863   }
0864 
0865   // Browse certification folders
0866   vector<TString> nameCertDir;
0867   nameCertDir.push_back(nameDirHead_);
0868   for (UInt_t iSys = 0; iSys < nSubSys_; ++iSys) {
0869     bAvailable_[sSubSys_[iSys]] = (iFlagsRR_[sSubSys_[iSys]] != EXCL);
0870     if (bAvailable_[sSubSys_[iSys]]) {
0871       const TString baseDir(nameDirHead_ + pathRunFragment_ + sSubSys_[iSys] + "/Run summary/" + nameDirBase_);
0872       nameCertDir.push_back(baseDir);
0873       nameCertDir.push_back(baseDir + "/" + nameDirCert_);
0874       nameCertDir.push_back(baseDir + "/" + nameDirReport_);
0875       if (iSys != Tracking) {
0876         nameCertDir.push_back(baseDir + "/" + nameDirDAQ_);
0877         nameCertDir.push_back(baseDir + "/" + nameDirDCS_);
0878       }
0879     }
0880   }
0881   for (UInt_t iDir = 0; iDir < nameCertDir.size(); ++iDir) {
0882     const TString nameCurDir(nameCertDir.at(iDir).Contains(pathRunFragment_)
0883                                  ? nameCertDir.at(iDir).Insert(nameCertDir.at(iDir).Index("Run ") + 4, sRunNumber_)
0884                                  : nameCertDir.at(iDir));
0885     TDirectory* dirSub((TDirectory*)fileDQM->Get(nameCurDir.Data()));
0886     if (!dirSub) {
0887       cout << "    WARNING: " << nameCurDir.Data() << " does not exist" << endl;
0888       continue;
0889     }
0890     readCertificates(dirSub);
0891   }
0892 
0893   fileDQM->Close();
0894 
0895   if (sOptions["-v"]) {
0896     cout << "    " << sVersion_ << endl;
0897     for (map<TString, Double_t>::const_iterator cert = fCertificates_.begin(); cert != fCertificates_.end(); ++cert)
0898       cout << "    " << cert->first << ": " << cert->second << endl;
0899   }
0900 
0901   return kTRUE;
0902 }
0903 
0904 /// Extract run certificates from DQM file
0905 void readCertificates(TDirectory* dir) {
0906   TIter nextKey(dir->GetListOfKeys());
0907   TKey* key;
0908   while ((key = (TKey*)nextKey())) {
0909     const TString nameKey(key->GetName());
0910     const Int_t index1(nameKey.Index(">"));
0911     if (index1 == kNPOS)
0912       continue;
0913     TString nameCert(nameKey(1, index1 - 1));
0914     if (TString(dir->GetName()) == nameDirHead_) {
0915       if (nameCert.CompareTo("ReleaseTag") == 0) {
0916         const Ssiz_t indexKey(nameKey.Index("s=") + 2);
0917         const TString nameKeyBrake(nameKey(indexKey, nameKey.Length() - indexKey));
0918         sVersion_ = nameKeyBrake(0, nameKeyBrake.Index("<"));
0919       }
0920       continue;
0921     }
0922     TString nameCertFirst(nameCert(0, 1));
0923     nameCertFirst.ToUpper();
0924     nameCert.Replace(0, 1, nameCertFirst);
0925     if (TString(dir->GetName()) == nameDirBase_) {  // indicates summaries
0926       if (!nameCert.Contains("Summary"))
0927         continue;
0928       const TString nameDir(dir->GetPath());
0929       const UInt_t index2(nameDir.Index("/", nameDir.Index(":") + 10));
0930       const TString nameSub(nameDir(index2 + 1, nameDir.Index("/", index2 + 1) - index2 - 1));
0931       nameCert.Prepend(nameSub);
0932     } else if (TString(dir->GetName()) == nameDirCert_) {
0933       nameCert.Prepend("Cert");
0934     } else if (TString(dir->GetName()) == nameDirDAQ_) {
0935       nameCert.Prepend("DAQ");
0936     } else if (TString(dir->GetName()) == nameDirDCS_) {
0937       nameCert.Prepend("DCS");
0938     } else {
0939       nameCert.Prepend("Report");
0940     }
0941     const Ssiz_t indexKey(nameKey.Index("f=") + 2);
0942     const TString nameKeyBrake(nameKey(indexKey, nameKey.Length() - indexKey));
0943     const TString nameKeyBrakeAll(nameKeyBrake(0, nameKeyBrake.Index("<")));
0944     fCertificates_[nameCert] = atof(nameKeyBrakeAll.Data());
0945   }
0946 
0947   return;
0948 }
0949 
0950 /// Determine actual certification flags per run and sub-system
0951 void certifyRun() {
0952   // FIXME Currently, LS-wise HV information from the RR is not determined correctly
0953   //       So, it is not used for the certification yet.
0954 
0955   // Initialize
0956   map<TString, Int_t> iFlags;
0957 
0958   // SiStrip
0959   sRRSiStrip_[sRunNumber_] = FlagConvert(iFlagsRR_[sSubSys_[SiStrip]]);
0960   sRRTrackerSiStrip_[sRunNumber_] = FlagConvert(iFlagsRRTracker_[sSubSys_[SiStrip]]);
0961   if (bAvailable_[sSubSys_[SiStrip]]) {
0962     Bool_t flagDet(fCertificates_["SiStripReportSummary"] > minGood_);
0963     Bool_t flagDAQ(fCertificates_["SiStripDAQSummary"] == (Double_t)EXCL ||
0964                    fCertificates_["SiStripDAQSummary"] > minGood_);
0965     Bool_t flagDCS(fCertificates_["SiStripDCSSummary"] == (Double_t)EXCL ||
0966                    fCertificates_["SiStripDCSSummary"] == (Double_t)GOOD);
0967     Bool_t flagDQM((flagDet * flagDAQ * flagDCS) != 0);
0968     Bool_t flagCert(iFlagsRRTracker_[sSubSys_[SiStrip]]);
0969     //     iFlags[ sSubSys_[ SiStrip ] ] = ( Int_t )( flagDQM * bSiStripOn_ * flagCert );
0970     iFlags[sSubSys_[SiStrip]] = (Int_t)(flagDQM * flagCert);
0971     sDQMSiStrip_[sRunNumber_] = FlagConvert((Int_t)(flagDQM));
0972     sSiStrip_[sRunNumber_] = FlagConvert(iFlags[sSubSys_[SiStrip]]);
0973     vector<TString> comments;
0974     if (!flagDet)
0975       comments.push_back("too low overall fraction of good modules");
0976     if (!flagDAQ)
0977       comments.push_back("DAQSummary BAD");
0978     if (!flagDCS)
0979       comments.push_back("DCSSummary BAD");
0980     //     if ( ! bSiStripOn_ ) comments.push_back( "HV off" );
0981     if (!flagCert)
0982       comments.push_back(TString("Tracker shifter: " + sRRTrackerCommentsSiStrip_[sRunNumber_]));
0983     if (iFlags[sSubSys_[SiStrip]] == BAD) {
0984       ++nRunsBadSiStrip_;
0985       if (flagCert)
0986         comments.push_back(TString("Tracker shifter differs (GOOD): " + sRRTrackerCommentsSiStrip_[sRunNumber_]));
0987       sRunCommentsSiStrip_[sRunNumber_] = comments;
0988     }
0989   } else {
0990     sDQMSiStrip_[sRunNumber_] = sRRSiStrip_[sRunNumber_];
0991     sSiStrip_[sRunNumber_] = sRRSiStrip_[sRunNumber_];
0992   }
0993 
0994   // Pixel
0995   sRRPixel_[sRunNumber_] = FlagConvert(iFlagsRR_[sSubSys_[Pixel]]);
0996   sRRTrackerPixel_[sRunNumber_] = FlagConvert(iFlagsRRTracker_[sSubSys_[Pixel]]);
0997   if (bAvailable_[sSubSys_[Pixel]]) {
0998     Bool_t flagReportSummary(fCertificates_["PixelReportSummary"] > maxBad_);
0999     Bool_t flagDAQ(
1000         (fCertificates_["DAQPixelBarrelFraction"] == (Double_t)EXCL || fCertificates_["DAQPixelBarrelFraction"] > 0.) &&
1001         (fCertificates_["DAQPixelEndcapFraction"] == (Double_t)EXCL ||
1002          fCertificates_["DAQPixelEndcapFraction"] > 0.));  // unidentified bug in Pixel DAQ fraction determination
1003     Bool_t flagDCS(fCertificates_["PixelDCSSummary"] == (Double_t)EXCL || fCertificates_["PixelDCSSummary"] > maxBad_);
1004     //     Bool_t flagDQM( flagReportSummary * flagDAQ * flagDCS );
1005     Bool_t flagDQM(flagDCS);  // bugs in DAQ fraction and report summary
1006     Bool_t flagCert(iFlagsRRTracker_[sSubSys_[Pixel]]);
1007     //     iFlags[ sSubSys_[ Pixel ] ] = ( Int_t )( flagDQM * bPixelOn_ * flagCert );
1008     iFlags[sSubSys_[Pixel]] = (Int_t)(flagDQM * flagCert);
1009     sDQMPixel_[sRunNumber_] = FlagConvert((Int_t)(flagDQM));
1010     sPixel_[sRunNumber_] = FlagConvert(iFlags[sSubSys_[Pixel]]);
1011     vector<TString> comments;
1012     if (!flagReportSummary)
1013       comments.push_back("ReportSummary BAD");
1014     if (!flagDAQ)
1015       comments.push_back("DAQSummary BAD");
1016     if (!flagDCS)
1017       comments.push_back("DCSSummary BAD");
1018     //     if ( ! bPixelOn_ )         comments.push_back( "HV off" );
1019     if (!flagCert)
1020       comments.push_back(TString("Tracker shifter: " + sRRTrackerCommentsPixel_[sRunNumber_]));
1021     if (iFlags[sSubSys_[Pixel]] == BAD) {
1022       ++nRunsBadPixel_;
1023       if (flagCert)
1024         comments.push_back(TString("Tracker shifter differs (GOOD): " + sRRTrackerCommentsPixel_[sRunNumber_]));
1025       sRunCommentsPixel_[sRunNumber_] = comments;
1026     }
1027   } else {
1028     sDQMPixel_[sRunNumber_] = sRRPixel_[sRunNumber_];
1029     sPixel_[sRunNumber_] = sRRPixel_[sRunNumber_];
1030   }
1031 
1032   // Tracking
1033   sRRTracking_[sRunNumber_] = FlagConvert(iFlagsRR_[sSubSys_[Tracking]]);
1034   sRRTrackerTracking_[sRunNumber_] = FlagConvert(iFlagsRRTracker_[sSubSys_[Tracking]]);
1035   if (bAvailable_[sSubSys_[Tracking]]) {
1036     Bool_t flagCert(iFlagsRRTracker_[sSubSys_[Pixel]]);
1037     Bool_t flagDQM(kFALSE);
1038     vector<TString> comments;
1039     if (iFlagsRR_[sSubSys_[SiStrip]] == EXCL && iFlagsRR_[sSubSys_[Pixel]] == EXCL) {
1040       comments.push_back("SiStrip and Pixel EXCL: no reasonable Tracking");
1041     } else {
1042       Bool_t flagChi2(fCertificates_["ReportTrackChi2"] > maxBad_);
1043       Bool_t flagRate(fCertificates_["ReportTrackRate"] > maxBad_);
1044       Bool_t flagRecHits(fCertificates_["ReportTrackRecHits"] > maxBad_);
1045       flagDQM = (flagChi2 * flagRate * flagRecHits) != 0;
1046       if (!flagChi2)
1047         comments.push_back("Chi2/DoF too low");
1048       if (!flagRate)
1049         comments.push_back("Track rate too low");
1050       if (!flagRecHits)
1051         comments.push_back("Too few RecHits");
1052       //       if ( ! bSiStripOn_ ) comments.push_back( "HV SiStrip off" );
1053       if (!flagCert)
1054         comments.push_back(TString("Tracker shifter: " + sRRTrackerCommentsTracking_[sRunNumber_]));
1055     }
1056     //     iFlags[ sSubSys_[ Tracking ] ] = ( Int_t )( flagDQM * bSiStripOn_ * flagCert );
1057     iFlags[sSubSys_[Tracking]] = (Int_t)(flagDQM * flagCert);
1058     sDQMTracking_[sRunNumber_] = FlagConvert((Int_t)(flagDQM));
1059     sTracking_[sRunNumber_] = FlagConvert(iFlags[sSubSys_[Tracking]]);
1060     if (iFlags[sSubSys_[Tracking]] == BAD) {
1061       ++nRunsBadTracking_;
1062       if (flagCert)
1063         comments.push_back(TString("Tracker shifter differs (GOOD): " + sRRTrackerCommentsTracking_[sRunNumber_]));
1064       sRunCommentsTracking_[sRunNumber_] = comments;
1065     }
1066   } else {
1067     sDQMTracking_[sRunNumber_] = sRRTracking_[sRunNumber_];
1068     sTracking_[sRunNumber_] = sRRTracking_[sRunNumber_];
1069   }
1070 
1071   for (map<TString, Int_t>::const_iterator iSys = iFlags.begin(); iSys != iFlags.end(); ++iSys) {
1072     cout << "    " << iSys->first << ": ";
1073     if (iSys->second != iFlagsRR_[iSys->first]) {
1074       if (iSys->first == sSubSys_[SiStrip])
1075         ++nRunsChangedSiStrip_;
1076       if (iSys->first == sSubSys_[Pixel])
1077         ++nRunsChangedPixel_;
1078       if (iSys->first == sSubSys_[Tracking])
1079         ++nRunsChangedTracking_;
1080       cout << FlagConvert(iFlagsRR_[iSys->first]) << " --> ";
1081     }
1082     cout << FlagConvert(iSys->second) << endl;
1083     if (sOptions["-v"]) {
1084       if (iSys->first == sSubSys_[SiStrip]) {
1085         for (UInt_t iCom = 0; iCom < sRunCommentsSiStrip_[sRunNumber_].size(); ++iCom) {
1086           cout << "      " << sRunCommentsSiStrip_[sRunNumber_].at(iCom).Data() << endl;
1087         }
1088       }
1089       if (iSys->first == sSubSys_[Pixel]) {
1090         for (UInt_t iCom = 0; iCom < sRunCommentsPixel_[sRunNumber_].size(); ++iCom) {
1091           cout << "      " << sRunCommentsPixel_[sRunNumber_].at(iCom).Data() << endl;
1092         }
1093       }
1094       if (iSys->first == sSubSys_[Tracking]) {
1095         for (UInt_t iCom = 0; iCom < sRunCommentsTracking_[sRunNumber_].size(); ++iCom) {
1096           cout << "      " << sRunCommentsTracking_[sRunNumber_].at(iCom).Data() << endl;
1097         }
1098       }
1099     }
1100   }
1101 
1102   return;
1103 }
1104 
1105 /// Print summary
1106 void writeOutput() {
1107   // Initialize
1108   ofstream fileLog;
1109   fileLog.open(sArguments["-o"].Data());
1110   fileLog << "Tracker Certification runs " << minRun_ << " - " << maxRun_ << endl
1111           << "==========================================" << endl
1112           << endl
1113           << "Used DQM files found in " << sArguments["-p"] << endl
1114           << "for dataset             " << sArguments["-d"] << endl
1115           << "and group name          " << sArguments["-g"] << endl
1116           << endl
1117           << "# of runs total                          : " << nRuns_ << endl
1118           << "------------------------------------------ " << endl
1119           << "# of runs certified                      : " << sRunNumbers_.size() << endl
1120           << "# of runs not found in RR                : " << nRunsNotRR_ << endl
1121           << "# of runs group not found in RR          : " << nRunsNotGroup_ << endl
1122           << "# of runs dataset not found in RR        : " << nRunsNotDataset_ << endl;
1123   if (!sOptions["-a"])
1124     fileLog << "# of runs not in SIGNOFF in RR           : " << nRunsNotSignoff_ << endl;
1125   fileLog << "# of runs not found in RR Tracker        : " << nRunsNotRRTracker_ << endl
1126           << "# of runs group not found in RR Tracker  : " << nRunsNotGroupTracker_
1127           << endl
1128           //           << "# of runs dataset not found in RR Tracker: " << nRunsNotDatasetTracker_ << endl
1129           << "# of runs not found in RR lumis          : " << nRunsNotRRLumis_ << endl
1130           << "# of runs dataset not found in RR lumis  : " << nRunsNotDatasetLumis_ << endl
1131           << endl
1132           << "# of runs w/o SiStrip       : " << nRunsExclSiStrip_ << endl
1133           << "# of bad runs SiStrip       : " << nRunsBadSiStrip_ << endl
1134           << "# of changed runs SiStrip   : " << nRunsChangedSiStrip_ << endl
1135           << "# of runs w/o Pixel         : " << nRunsExclPixel_ << endl
1136           << "# of bad runs Pixel         : " << nRunsBadPixel_ << endl
1137           << "# of changed runs Pixel     : " << nRunsChangedPixel_ << endl
1138           << "# of runs w/o Tracking (BAD): " << nRunsNoTracking_ << endl
1139           << "# of bad runs Tracking      : " << nRunsBadTracking_ << endl
1140           << "# of changed runs Tracking  : " << nRunsChangedTracking_ << endl;
1141 
1142   // SiStrip
1143   fileLog << endl << sSubSys_[0] << ":" << endl << endl;
1144   for (UInt_t iRun = 0; iRun < sRunNumbers_.size(); ++iRun) {
1145     if (sRRSiStrip_[sRunNumbers_.at(iRun)] != sSiStrip_[sRunNumbers_.at(iRun)]) {
1146       fileLog << "  " << sRunNumbers_.at(iRun) << ": " << sRRSiStrip_[sRunNumbers_.at(iRun)] << " --> "
1147               << sSiStrip_[sRunNumbers_.at(iRun)] << endl;
1148       if (sRRSiStrip_[sRunNumbers_.at(iRun)] == TString("BAD")) {
1149         fileLog << "    RR was: " << sRRCommentsSiStrip_[sRunNumbers_.at(iRun)] << endl;
1150       }
1151       for (UInt_t iCom = 0; iCom < sRunCommentsSiStrip_[sRunNumbers_.at(iRun)].size(); ++iCom) {
1152         fileLog << "    " << sRunCommentsSiStrip_[sRunNumbers_.at(iRun)].at(iCom).Data() << endl;
1153       }
1154     }
1155   }
1156 
1157   // Pixel
1158   fileLog << endl << sSubSys_[1] << ":" << endl << endl;
1159   for (UInt_t iRun = 0; iRun < sRunNumbers_.size(); ++iRun) {
1160     if (sRRPixel_[sRunNumbers_.at(iRun)] != sPixel_[sRunNumbers_.at(iRun)]) {
1161       fileLog << "  " << sRunNumbers_.at(iRun) << ": " << sRRPixel_[sRunNumbers_.at(iRun)] << " --> "
1162               << sPixel_[sRunNumbers_.at(iRun)] << endl;
1163       if (sRRPixel_[sRunNumbers_.at(iRun)] == TString("BAD")) {
1164         fileLog << "    RR was: " << sRRCommentsPixel_[sRunNumbers_.at(iRun)] << endl;
1165       }
1166       for (UInt_t iCom = 0; iCom < sRunCommentsPixel_[sRunNumbers_.at(iRun)].size(); ++iCom) {
1167         fileLog << "    " << sRunCommentsPixel_[sRunNumbers_.at(iRun)].at(iCom).Data() << endl;
1168       }
1169     }
1170   }
1171 
1172   // Tracking
1173   fileLog << endl << sSubSys_[2] << ":" << endl << endl;
1174   for (UInt_t iRun = 0; iRun < sRunNumbers_.size(); ++iRun) {
1175     if (sRRTracking_[sRunNumbers_.at(iRun)] != sTracking_[sRunNumbers_.at(iRun)]) {
1176       fileLog << "  " << sRunNumbers_.at(iRun) << ": " << sRRTracking_[sRunNumbers_.at(iRun)] << " --> "
1177               << sTracking_[sRunNumbers_.at(iRun)] << endl;
1178       if (sRRTracking_[sRunNumbers_.at(iRun)] == TString("BAD")) {
1179         fileLog << "    RR was: " << sRRCommentsTracking_[sRunNumbers_.at(iRun)] << endl;
1180       }
1181       for (UInt_t iCom = 0; iCom < sRunCommentsTracking_[sRunNumbers_.at(iRun)].size(); ++iCom) {
1182         fileLog << "    " << sRunCommentsTracking_[sRunNumbers_.at(iRun)].at(iCom).Data() << endl;
1183       }
1184     }
1185   }
1186 
1187   fileLog.close();
1188 
1189   cout << endl << "SUMMARY:" << endl << endl;
1190   for (UInt_t iRun = 0; iRun < sRunNumbers_.size(); ++iRun) {
1191     cout << "  " << sRunNumbers_.at(iRun) << ":" << endl;
1192     cout << "    " << sSubSys_[0] << ": " << sSiStrip_[sRunNumbers_.at(iRun)] << endl;
1193     for (UInt_t iCom = 0; iCom < sRunCommentsSiStrip_[sRunNumbers_.at(iRun)].size(); ++iCom) {
1194       cout << "      " << sRunCommentsSiStrip_[sRunNumbers_.at(iRun)].at(iCom).Data() << endl;
1195     }
1196     cout << "    " << sSubSys_[1] << ": " << sPixel_[sRunNumbers_.at(iRun)] << endl;
1197     for (UInt_t iCom = 0; iCom < sRunCommentsPixel_[sRunNumbers_.at(iRun)].size(); ++iCom) {
1198       cout << "      " << sRunCommentsPixel_[sRunNumbers_.at(iRun)].at(iCom).Data() << endl;
1199     }
1200     cout << "    " << sSubSys_[2] << ": " << sTracking_[sRunNumbers_.at(iRun)] << endl;
1201     for (UInt_t iCom = 0; iCom < sRunCommentsTracking_[sRunNumbers_.at(iRun)].size(); ++iCom) {
1202       cout << "      " << sRunCommentsTracking_[sRunNumbers_.at(iRun)].at(iCom).Data() << endl;
1203     }
1204   }
1205 
1206   cout << endl
1207        << "Certification SUMMARY to be sent to CMS DQM team available in ./" << sArguments["-o"].Data() << endl
1208        << endl;
1209 
1210   return;
1211 }
1212 
1213 /// Print help
1214 void displayHelp() {
1215   cerr << "  TrackerRunCertification" << endl
1216        << endl
1217        << "  CMSSW package: DQM/TrackerCommon" << endl
1218        << endl
1219        << "  Purpose:" << endl
1220        << endl
1221        << "  The procedure of certifying data of a given run range is automated in order to speed up the procedure and "
1222           "to reduce the Tracker Offline Shift Leader's workload."
1223        << endl
1224        << endl
1225        << "  Input:" << endl
1226        << endl
1227        << "  - RunRegistry" << endl
1228        << "  - DQM output files available in AFS" << endl
1229        << endl
1230        << "  Output:" << endl
1231        << endl
1232        << "  Text file" << endl
1233        << "  - [as explained for command line option '-o']" << endl
1234        << "  to be sent directly to the CMS DQM team as reply to the weekly certification request." << endl
1235        << "  It contains a list of all flags changed with respect to the RunRegistry, including the reason(s) in case "
1236           "the flag is changed to BAD."
1237        << endl
1238        << endl
1239        << "  The verbose ('-v') stdout can provide a complete list of all in-/output flags of all analyzed runs and at "
1240           "its end a summary only with the output flags."
1241        << endl
1242        << "  It makes sense to pipe the stdout to another text file." << endl
1243        << endl
1244        << "  Usage:" << endl
1245        << endl
1246        << "  $ cmsrel CMSSW_RELEASE" << endl
1247        << "  $ cd CMSSW_RELEASE/src" << endl
1248        << "  $ cmsenv" << endl
1249        << "  $ cvs co -r Vxx-yy-zz DQM/TrackerCommon" << endl
1250        << "  $ scram b -j 5" << endl
1251        << "  $ rehash" << endl
1252        << "  $ cd WORKING_DIRECTORY" << endl
1253        << "  $ [create input files]" << endl
1254        << "  $ TrackerRunCertification [ARGUMENTOPTION1] [ARGUMENT1] ... [OPTION2] ..." << endl
1255        << endl
1256        << "  Valid argument options are:" << endl
1257        << "    -d" << endl
1258        << "      MANDATORY: dataset as in RunRegistry" << endl
1259        << "      no default" << endl
1260        << "    -g" << endl
1261        << "      MANDATORY: group name as in RunRegistry" << endl
1262        << "      no default" << endl
1263        << "    -p" << endl
1264        << "      path to DQM files" << endl
1265        << "      default: /afs/cern.ch/cms/CAF/CMSCOMM/COMM_DQM/data/OfflineData/Run2010/StreamExpress" << endl
1266        << "    -P" << endl
1267        << "      pattern of DQM file names in the DQM file path" << endl
1268        << "      default: *[DATASET from '-d' option with '/' --> '__'].root" << endl
1269        << "    -o" << endl
1270        << "      path to output log file" << endl
1271        << "      default: trackerRunCertification[DATASET from '-d' option with '/' --> '__']-[GROUP from '-g'].txt"
1272        << endl
1273        << "    -l" << endl
1274        << "      lower bound of run numbers to consider" << endl
1275        << "      default: 0" << endl
1276        << "    -u" << endl
1277        << "      upper bound of run numbers to consider" << endl
1278        << "      default: 1073741824 (2^30)" << endl
1279        << "    -R" << endl
1280        << "      web address of the RunRegistry" << endl
1281        << "      default: http://pccmsdqm04.cern.ch/runregistry" << endl
1282        << "    The default is used for any option not explicitely given in the command line." << endl
1283        << endl
1284        << "  Valid options are:" << endl
1285        << "    -rr" << endl
1286        << "      switch on creation of new RR file" << endl
1287        << "    -rronly" << endl
1288        << "      only create new RR file, do not run certification" << endl
1289        << "    -a" << endl
1290        << "      certify all runs, not only those in \"SIGNOFF\" status" << endl
1291        << "    -v" << endl
1292        << "      switch on verbose logging to stdout" << endl
1293        << "    -h" << endl
1294        << "      display this help and exit" << endl
1295        << endl;
1296   return;
1297 }
1298 
1299 /// Little helper to determine run number (TString) from file name/path
1300 TString RunNumber(const TString& pathFile) {
1301   const TString sPrefix("DQM_V");
1302   const TString sNumber(pathFile(pathFile.Index(sPrefix) + sPrefix.Length() + 6, 9));
1303   UInt_t index((string(sNumber.Data())).find_first_not_of('0'));
1304   return sNumber(index, sNumber.Length() - index);
1305 }
1306 
1307 /// Little helper to convert RR flags from TString into Int_t
1308 Int_t FlagConvert(const TString& flag) {
1309   map<TString, Int_t> flagSToI;
1310   flagSToI["MISSING"] = MISSING;
1311   flagSToI["NOTSET"] = NOTSET;
1312   flagSToI["EXCL"] = EXCL;
1313   flagSToI["BAD"] = BAD;
1314   flagSToI["GOOD"] = GOOD;
1315   return flagSToI[flag];
1316 }
1317 /// Little helper to convert RR flags from Int_t into TString
1318 TString FlagConvert(const Int_t flag) {
1319   map<Int_t, TString> flagIToS;
1320   flagIToS[MISSING] = "MISSING";
1321   flagIToS[NOTSET] = "NOTSET";
1322   flagIToS[EXCL] = "EXCL";
1323   flagIToS[BAD] = "BAD";
1324   flagIToS[GOOD] = "GOOD";
1325   return flagIToS[flag];
1326 }