Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:12:09

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