Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:11:51

0001 #include <cstdlib>
0002 #include <ctime>
0003 #include <iostream>
0004 #include <fstream>
0005 #include <sstream>
0006 #include <iomanip>
0007 #include <vector>
0008 #include <map>
0009 #include <string>
0010 
0011 #include "TSystem.h"
0012 #include "TStyle.h"
0013 #include "TXMLEngine.h"
0014 #include "TFile.h"
0015 #include "TH1D.h"
0016 #include "TCanvas.h"
0017 #include "TKey.h"
0018 
0019 
0020 using namespace std;
0021 
0022 
0023 // macro parameters
0024 const Bool_t createNewData( kFALSE );               // extract information from harvest files (again)?
0025 const Bool_t closeCanvas( kTRUE );                  // close created canvases again at end of processing?
0026 const string drawFormat( "gif" );
0027 const string nameFileIn( "certDqmHarvestFiles.txt" ); // name of file containing harvesting file list
0028 const string pathHarvestFiles( "/afs/cern.ch/cms/CAF/CMSCOMM/COMM_DQM/data/Cosmics__Commissioning08_CRAFT_ALL_V9_225-v2__RECO" );
0029 const string nameFileRR( "certRunRegistry.xml" );     // name of file containing run registry information
0030 const string xmlRRAddress( "http://pccmsdqm04.cern.ch/runregistry/runregisterdata?format=xml&intpl=xml&mime=text/xml&qtype=RUN_NUMBER&sortname=RUN_NUMBER" );
0031 const string nameFileCache( "getData.txt" );      // name of file containing extracted harvesting data
0032 const string nameFileOut( "certRunFlags" );           // base name of files containing final flags
0033 const string nameFileHistos( "certHistos.root" );     // name of RooT file containing history histogramms
0034 const Int_t    minNEvt( 1 );                                  // min. number of events
0035 const Int_t    minNTrk( 1 );                                  // min. number of tracks (each tracking algo)
0036 const Double_t minRate( 0.01 );                               // min. rate of tracks/event (each tracking algo)
0037 const Double_t maxOffTrkCl( 10000. );                         // max. number of off-track clusters in CKF
0038 const Double_t minSToN[] = { 25., 25., 30., 27. };            // min. corr. S/N of clusters in the order TIB, TID, TOB, TEC
0039 // const Double_t minFractSubDet( 0.95 );                        // min. fraction of modules/sub-detector passing quality tests (each sub-detector)
0040 const Double_t minFractSubDet( 0.85 );                        // min. fraction of modules/sub-detector passing quality tests (each sub-detector)
0041 const Bool_t   avForwBackw( kTRUE );                          // use average values for forward/backward sub-detector pairs?
0042 const Bool_t   useTEC( kTRUE );                               // consider TEC quality?
0043 const Bool_t   useTID( kFALSE );                              // consider TID quality?
0044 
0045 // derived parameters
0046 const string nameFileOutTxt( nameFileOut + ".txt" );          // name of file containing final flags in ASCII
0047 const string nameFileInTwiki( nameFileOut + "Old.txt" );        // name of file containing old flags in ASCII
0048 const string nameFileCacheTwiki( nameFileOut + "Cache.txt" ); // name of temporary file containing final flags for Twiki in ASCII format
0049 const string nameFileOutTwiki( nameFileOut + ".twiki" );      // name of final file containing old and final flags in Twiki format
0050 const string nameFileOutXml( nameFileOut + ".xml" );          // name of file containing final flags in XML
0051 const string nameFileRRTmp( nameFileRR + ".tmp" );
0052 
0053 // global constants  
0054 const string BAD( "Bad" );
0055 const string GOOD( "Good" );
0056 const string EXCL( "Excl" );
0057 const string NO( "No" );
0058 const string YES( "Yes" );
0059 
0060 
0061 string coloredFlag( const string & flag )
0062 {
0063   string color;
0064   if      ( flag == BAD  || flag == YES ) color = "RED";
0065   else if ( flag == GOOD                ) color = "GREEN";
0066   else if ( flag == EXCL                ) color = "ORANGE";
0067   else                                    color = "BLACK";
0068   string formated( "%" + color + "%" + flag + "%ENDCOLOR%" );
0069   if ( flag != NO ) {
0070     const string bold( "*" );
0071     formated.insert( 0,  bold );
0072     formated.append(     bold );
0073   }
0074   return formated;
0075 }
0076 
0077 
0078 void certification()
0079 {
0080   // definitions of constants
0081   vector< string > namesDet;
0082   namesDet.push_back( "TIB" );
0083   namesDet.push_back( "TID" );
0084   namesDet.push_back( "TOB" );
0085   namesDet.push_back( "TEC" );
0086   vector< string > namesSubDet;
0087   namesSubDet.push_back( "SiStrip_TECB" );
0088   namesSubDet.push_back( "SiStrip_TECF" );
0089   namesSubDet.push_back( "SiStrip_TIB" );
0090   namesSubDet.push_back( "SiStrip_TIDB" );
0091   namesSubDet.push_back( "SiStrip_TIDF" );
0092   namesSubDet.push_back( "SiStrip_TOB" );
0093   vector< string > namesAlgo;
0094   namesAlgo.push_back( "CKF" );
0095   namesAlgo.push_back( "Cosmic" );
0096   namesAlgo.push_back( "RS" );
0097     
0098   string                  sRun;
0099   Int_t                   iRun;
0100   Int_t                   nEvt;
0101   map< string, Int_t >    nTrk;
0102   map< string, Double_t > rate;
0103   map< string, Double_t > chi2;
0104   Double_t                offTrkCl;
0105   map< string, Double_t > sToN;
0106   map< string, Double_t > fractSubDet;
0107 
0108   gSystem->Exec( string( "ls -1 " + pathHarvestFiles + "/*/*.root > " + nameFileIn ).c_str() );
0109   ofstream fileInCorrect;
0110   fileInCorrect.open( nameFileIn.c_str(), ios_base::app );
0111   fileInCorrect << "EOF";
0112   fileInCorrect.close();
0113   gSystem->Exec( string( "wget -q -O " + nameFileRRTmp + " " + xmlRRAddress ).c_str() ); // FIXME correct first line of XML file (spaces, quotes)
0114   clock_t sleep( 2 * CLOCKS_PER_SEC + clock() ); // minimum 2 seconds delay to have the file completely downloaded (evaluated before first use of the file)
0115 
0116   ifstream fileIn;
0117   ofstream fileCacheOut;
0118   fileIn.open( nameFileIn.c_str() );
0119   if ( ! fileIn ) {
0120     cout << "  ERROR: no input file list " << nameFileIn << " found" << endl;
0121     return;
0122   }
0123   if ( createNewData ) fileCacheOut.open( nameFileCache.c_str() );
0124   
0125   Int_t minRun( 1000000 );
0126   Int_t maxRun(       0 );
0127   Int_t nFile( 0 );
0128   while ( fileIn.good() ) {
0129   
0130     string nameFile;
0131     fileIn >> nameFile;
0132     if ( nameFile == "EOF" ) break;
0133     sRun = nameFile.substr( nameFile.find( "_R0000" ) + 6, 5);
0134     iRun = atoi( sRun.c_str() );
0135     if ( iRun < minRun ) minRun = iRun;
0136     if ( iRun > maxRun ) maxRun = iRun;
0137     Bool_t goodRead( kTRUE );
0138     nEvt     = 0;
0139     offTrkCl = 0.;
0140     nTrk.clear();
0141     rate.clear();
0142     chi2.clear();
0143     sToN.clear();
0144     fractSubDet.clear();
0145     
0146     if ( createNewData ) {
0147       TFile * fileRoot( TFile::Open( nameFile.c_str() ) );
0148       if ( fileRoot ) {
0149         const string nameDir( "/DQMData/Run " + sRun + "/SiStrip/Run summary/" );
0150         const string nameDirTrk( nameDir + "Tracks" );
0151         const string nameDirMech( nameDir + "MechanicalView" );
0152         const string nameDirEvt( nameDir + "EventInfo/reportSummaryContents" );
0153         TDirectory * dirTrk = (TDirectory*)fileRoot->Get( nameDirTrk.c_str() );
0154         if ( dirTrk ) {
0155           for ( size_t iAlgo = 0; iAlgo < namesAlgo.size(); ++iAlgo ) {
0156             const string nameTrk( "NumberOfTracks_" + namesAlgo.at( iAlgo ) + "Tk" );
0157             const string nameHits( "NumberOfRecHitsPerTrack_" + namesAlgo.at( iAlgo ) + "Tk" );
0158             const string nameChi2( "Chi2_" + namesAlgo.at( iAlgo ) + "Tk" );
0159             TH1 * h1Trk  = (TH1*)dirTrk->Get( nameTrk.c_str() );
0160             TH1 * h1Hits = (TH1*)dirTrk->Get( nameHits.c_str() );
0161             TH1 * h1Chi2 = (TH1*)dirTrk->Get( nameChi2.c_str() );
0162             if ( iAlgo == 0 ) {
0163               if ( h1Trk ) nEvt = ( Int_t )h1Trk->GetEntries();
0164               else         nEvt = -1;
0165             }
0166             if ( h1Hits ) nTrk[ namesAlgo.at( iAlgo ) ] = ( Int_t )h1Hits->GetEntries();
0167             else          nTrk[ namesAlgo.at( iAlgo ) ] = -1;
0168             if ( h1Trk ) rate[ namesAlgo.at( iAlgo ) ] = h1Trk->GetMean();
0169             else         rate[ namesAlgo.at( iAlgo ) ] = -1.;
0170             if ( h1Chi2 ) chi2[ namesAlgo.at( iAlgo ) ] = h1Chi2->GetMean();
0171             else          chi2[ namesAlgo.at( iAlgo ) ] = -1.;
0172           }
0173           TH1 * h1Clus = (TH1*)dirTrk->Get( "OffTrack_TotalNumberOfClusters" );
0174           if (h1Clus  ) offTrkCl = h1Clus->GetMean();
0175           else          offTrkCl = -1.;
0176         } else {
0177           cout << "  ERROR: no track info from run " << iRun << endl;
0178           goodRead = kFALSE;
0179         }
0180         TDirectory * dirMech = (TDirectory*)fileRoot->Get( nameDirMech.c_str() );
0181         if ( dirMech ) {
0182           for ( size_t iDet = 0; iDet < namesDet.size(); ++iDet ) {
0183             const string nameSToN( namesDet.at( iDet ) + "/Summary_ClusterStoNCorr_OnTrack_in_" + namesDet.at( iDet ) );
0184             TH1 * h1StoN = (TH1*)dirMech->Get( nameSToN.c_str() );
0185             if ( h1StoN ) sToN[ namesDet.at( iDet ) ] = h1StoN->GetMean();
0186             else          sToN[ namesDet.at( iDet ) ] = -1.;
0187           }
0188         } else {
0189           cout << "  ERROR: no sub-detector info from run " << iRun << endl;
0190           goodRead = kFALSE;
0191         }
0192         TDirectory * dirEvt = (TDirectory*)fileRoot->Get( nameDirEvt.c_str() );
0193         if ( dirEvt ) {
0194           TIter nextKey( dirEvt->GetListOfKeys() );
0195           TKey * key;
0196           while ( key = (TKey*)nextKey() ) {
0197             const string nameKey( key->GetName() );
0198             const string nameSubDet( nameKey.substr( 1, nameKey.find_first_of( ">" ) - 1 ) );
0199             Bool_t found( false );
0200             for ( size_t iSubDet = 0; iSubDet < namesSubDet.size(); ++iSubDet ) {
0201               if ( nameSubDet == namesSubDet.at( iSubDet ) ) {
0202                 fractSubDet[ nameSubDet ] = atof( ( nameKey.substr( nameKey.find( "f=" ) + 2 ) ).c_str() );
0203                 found = true;
0204                 break;
0205               }
0206             }
0207             if ( ! found ) cout << "  ERROR: did not find SubDet" << nameSubDet << endl;
0208           }
0209         } else {
0210           cout << "  ERROR: no event info from run " << iRun << endl;
0211           goodRead = kFALSE;
0212         }
0213         fileRoot->Close();
0214         
0215         if ( nFile > 0 ) fileCacheOut << endl;
0216         fileCacheOut << iRun << " " << nEvt;
0217         for ( size_t iAlgo = 0; iAlgo < namesAlgo.size(); ++iAlgo ) fileCacheOut << " " << nTrk[ namesAlgo.at( iAlgo ) ];
0218         for ( size_t iAlgo = 0; iAlgo < namesAlgo.size(); ++iAlgo ) fileCacheOut << " " << rate[ namesAlgo.at( iAlgo ) ];
0219         for ( size_t iAlgo = 0; iAlgo < namesAlgo.size(); ++iAlgo ) fileCacheOut << " " << chi2[ namesAlgo.at( iAlgo ) ];
0220         fileCacheOut << " " << offTrkCl;
0221         for ( size_t iDet    = 0; iDet    < namesDet.size()   ; ++iDet    ) fileCacheOut << " " << sToN[ namesDet.at( iDet ) ];
0222         for ( size_t iSubDet = 0; iSubDet < namesSubDet.size(); ++iSubDet ) fileCacheOut << " " << fractSubDet[ namesSubDet.at( iSubDet ) ];
0223         if ( ! goodRead ) fileCacheOut << " \tERROR in file reading" << endl;
0224       } else {
0225         cout << "  ERROR: file " << nameFile << " cannot be opened" << endl;
0226       }
0227     }
0228     ++nFile;
0229   }
0230   
0231   if ( createNewData ) fileCacheOut.close();
0232   fileIn.close();
0233   
0234   TFile * fileHistos = new TFile( nameFileHistos.c_str(), "RECREATE" );
0235   const Int_t    nBins( maxRun - minRun + 1 );
0236   const Double_t low( (Double_t)minRun - 0.5 );
0237   const Double_t high( (Double_t)maxRun + 0.5 );
0238   TH1D * gFracTrkCKF =    new TH1D( "gFracTrkCKF"   , "Average fraction of tracks in event", nBins, low, high );
0239   TH1D * gFracTrkCosmic = new TH1D( "gFracTrkCosmic", "Average fraction of tracks in event", nBins, low, high );
0240   TH1D * gFracTrkRS =     new TH1D( "gFracTrkRS"    , "Average fraction of tracks in event", nBins, low, high );
0241   TH1D * gChi2CKF =       new TH1D( "gChi2CKF"      , "Mean of #chi^{2}"                   , nBins, low, high );
0242   TH1D * gChi2Cosmic =    new TH1D( "gChi2Cosmic"   , "Mean of #chi^{2}"                   , nBins, low, high );
0243   TH1D * gChi2RS =        new TH1D( "gChi2RS"       , "Mean of #chi^{2}"                   , nBins, low, high );
0244   TH1D * gSnTIB =         new TH1D( "gSnTIB"        , "S/N clusters"                       , nBins, low, high );
0245   TH1D * gSnTID =         new TH1D( "gSnTID"        , "S/N clusters"                       , nBins, low, high );
0246   TH1D * gSnTOB =         new TH1D( "gSnTOB"        , "S/N clusters"                       , nBins, low, high );
0247   TH1D * gSnTEC =         new TH1D( "gSnTEC"        , "S/N clusters"                       , nBins, low, high );
0248   TH1D * gClstOff =       new TH1D( "gClstOff"      , "Mean of off-track clusters"         , nBins, low, high );
0249   gFracTrkCKF->SetXTitle( "run number" );
0250   gFracTrkCKF->SetMarkerStyle( 20 );
0251   gFracTrkCKF->SetMarkerSize( 1. );
0252   gFracTrkCKF->SetMarkerColor( kRed );
0253   gFracTrkCKF->SetLineColor( kRed );
0254   gFracTrkCosmic->SetXTitle( "run number" );
0255   gFracTrkCosmic->SetMarkerStyle( 21 );
0256   gFracTrkCosmic->SetMarkerSize( 1. );
0257   gFracTrkCosmic->SetMarkerColor( kBlack );
0258   gFracTrkCosmic->SetLineColor( kBlack );
0259   gFracTrkRS->SetXTitle( "run number" );
0260   gFracTrkRS->SetMarkerStyle( 22 );
0261   gFracTrkRS->SetMarkerSize( 1. );
0262   gFracTrkRS->SetMarkerColor( kBlue );
0263   gFracTrkRS->SetLineColor( kBlue );
0264   gChi2CKF->SetXTitle( "run number" );
0265   gChi2CKF->SetMarkerStyle( 20 );
0266   gChi2CKF->SetMarkerSize( 1. );
0267   gChi2CKF->SetMarkerColor( kRed );
0268   gChi2CKF->SetLineColor( kRed );
0269   gChi2Cosmic->SetXTitle( "run number" );
0270   gChi2Cosmic->SetMarkerStyle( 21 );
0271   gChi2Cosmic->SetMarkerSize( 1. );
0272   gChi2Cosmic->SetMarkerColor( kBlack );
0273   gChi2Cosmic->SetLineColor( kBlack );
0274   gChi2RS->SetXTitle( "run number" );
0275   gChi2RS->SetMarkerStyle( 22 );
0276   gChi2RS->SetMarkerSize( 1. );
0277   gChi2RS->SetMarkerColor( kBlue );
0278   gChi2RS->SetLineColor( kBlue );
0279   gSnTIB->SetXTitle( "run number" );
0280   gSnTIB->SetMarkerStyle( 20 );
0281   gSnTIB->SetMarkerSize( 1. );
0282   gSnTIB->SetMarkerColor( kRed );
0283   gSnTIB->SetLineColor( kRed );
0284   gSnTID->SetXTitle( "run number" );
0285   gSnTID->SetMarkerStyle( 21 );
0286   gSnTID->SetMarkerSize( 1. );
0287   gSnTID->SetMarkerColor( kBlack );
0288   gSnTID->SetLineColor( kBlack );
0289   gSnTOB->SetXTitle( "run number" );
0290   gSnTOB->SetMarkerStyle( 22 );
0291   gSnTOB->SetMarkerSize( 1. );
0292   gSnTOB->SetMarkerColor( kBlue );
0293   gSnTOB->SetLineColor( kBlue );
0294   gSnTEC->SetXTitle( "run number" );
0295   gSnTEC->SetMarkerStyle( 23 );
0296   gSnTEC->SetMarkerSize( 1. );
0297   gSnTEC->SetMarkerColor( kOrange );
0298   gSnTEC->SetLineColor( kOrange );
0299   gClstOff->SetXTitle( "run number" );
0300   gClstOff->SetMarkerStyle( 20 );
0301   gClstOff->SetMarkerSize( 1. );
0302   gClstOff->SetMarkerColor( kRed );
0303   gClstOff->SetLineColor( kRed );
0304   TH1D * aFracTrkCKF =    new TH1D( *( (TH1D*)gFracTrkCKF->Clone( "aFracTrkCKF" ) ) );
0305   TH1D * aFracTrkCosmic = new TH1D( *( (TH1D*)gFracTrkCosmic->Clone( "aFracTrkCosmic" ) ) );
0306   TH1D * aFracTrkRS =     new TH1D( *( (TH1D*)gFracTrkRS->Clone( "aFracTrkRS" ) ) );
0307   TH1D * aChi2CKF =       new TH1D( *( (TH1D*)gChi2CKF->Clone( "aChi2CKF" ) ) );
0308   TH1D * aChi2Cosmic =    new TH1D( *( (TH1D*)gChi2Cosmic->Clone( "aChi2Cosmic" ) ) );
0309   TH1D * aChi2RS =        new TH1D( *( (TH1D*)gChi2RS->Clone( "aChi2RS" ) ) );
0310   TH1D * aSnTIB =         new TH1D( *( (TH1D*)gSnTIB->Clone( "aSnTIB" ) ) );
0311   TH1D * aSnTID =         new TH1D( *( (TH1D*)gSnTID->Clone( "aSnTID" ) ) );
0312   TH1D * aSnTOB =         new TH1D( *( (TH1D*)gSnTOB->Clone( "aSnTOB" ) ) );
0313   TH1D * aSnTEC =         new TH1D( *( (TH1D*)gSnTEC->Clone( "aSnTEC" ) ) );
0314   TH1D * aClstOff =       new TH1D( *( (TH1D*)gClstOff->Clone( "aClstOff" ) ) );
0315   
0316   ifstream fileCacheIn;
0317   ofstream fileOut;
0318   ofstream fileCacheOutTwiki;
0319   fileCacheIn.open( nameFileCache.c_str() );
0320   fileOut.open( nameFileOutTxt.c_str() );
0321   fileCacheOutTwiki.open( nameFileCacheTwiki.c_str() );
0322   TXMLEngine * xml = new TXMLEngine;
0323   XMLNodePointer_t nodeMain( xml->NewChild( 0, 0, "CERTIFICATION" ) );
0324   XMLNodePointer_t nodeCriteria( xml->NewChild( nodeMain, 0, "CRITERIA" ) );
0325   XMLNodePointer_t nodeCriterion( xml->NewChild( nodeCriteria, 0, "CRITERION", "Minimum number of events" ) );
0326   xml->NewAttr( nodeCriterion, 0, "name", "minNEvt" );
0327   ostringstream sMinNEvt;
0328   sMinNEvt << minNEvt;
0329   xml->NewAttr( nodeCriterion, 0, "value", sMinNEvt.str().c_str() );
0330   nodeCriterion = xml->NewChild( nodeCriteria, 0, "CRITERION", "Minimum number of reconstructed tracks" );
0331   xml->NewAttr( nodeCriterion, 0, "name", "minNTrk" );
0332   ostringstream sMinNTrk;
0333   sMinNTrk << minNTrk;
0334   xml->NewAttr( nodeCriterion, 0, "value", sMinNTrk.str().c_str() );
0335   nodeCriterion = xml->NewChild( nodeCriteria, 0, "CRITERION", "Minimum average number of reconstructed tracks per event" );
0336   xml->NewAttr( nodeCriterion, 0, "name", "minRate" );
0337   ostringstream sMinRate;
0338   sMinRate << minRate;
0339   xml->NewAttr( nodeCriterion, 0, "value", sMinRate.str().c_str() );
0340   nodeCriterion = xml->NewChild( nodeCriteria, 0, "CRITERION", "Maximum average number of off-track clusters" );
0341   xml->NewAttr( nodeCriterion, 0, "name", "maxOffTrkCl" );
0342   ostringstream sMaxOffTrkCl;
0343   sMaxOffTrkCl << maxOffTrkCl;
0344   xml->NewAttr( nodeCriterion, 0, "value", sMaxOffTrkCl.str().c_str() );
0345   nodeCriterion = xml->NewChild( nodeCriteria, 0, "CRITERION", "Minimum corr. S/N of clusters per sub-detector" );
0346   xml->NewAttr( nodeCriterion, 0, "name", "minSToN" );
0347   XMLNodePointer_t nodeSubCriterion;
0348   for ( size_t iDet = 0; iDet < namesDet.size(); ++iDet ) {
0349     nodeSubCriterion = xml->NewChild( nodeCriterion, 0, "SUBCRITERION" );
0350     xml->NewAttr( nodeSubCriterion, 0, "subdet", namesDet.at( iDet ).c_str() );
0351     ostringstream sMinSToN;
0352     sMinSToN << minSToN[ iDet ];
0353     xml->NewAttr( nodeSubCriterion, 0, "value", sMinSToN.str().c_str() );
0354   }
0355   nodeCriterion = xml->NewChild( nodeCriteria, 0, "CRITERION", "Minimum fraction of good modules in sub-detectors" );
0356   xml->NewAttr( nodeCriterion, 0, "name", "minFractSubDet" );
0357   ostringstream sMinFractSubDet;
0358   sMinFractSubDet << minFractSubDet;
0359   xml->NewAttr( nodeCriterion, 0, "value", sMinFractSubDet.str().c_str() );
0360   XMLNodePointer_t nodeRuns( xml->NewChild( nodeMain, 0, "RUNS" ) );
0361   
0362   Int_t nRuns( 0 );
0363   Int_t nRunsGood( 0 );
0364   Int_t nRunsBad( 0 );
0365   Int_t nRunsNoEvents( 0 );
0366   Int_t nRunsNoTracks( 0 );
0367   Int_t nEvents( 0 );
0368   Int_t nEventsGood( 0 );
0369   while ( fileCacheIn.good() ) {
0370   
0371     string lineTxt( "" );
0372     string lineTwiki( " " );
0373     string sFlag( " run is" );
0374     string flagList( "" );
0375     nEvt = 0;
0376     offTrkCl = 0.;
0377     nTrk.clear();
0378     rate.clear();
0379     chi2.clear();
0380     sToN.clear();
0381     fractSubDet.clear();
0382     fileCacheIn >> iRun >> nEvt;
0383     for ( size_t iAlgo = 0; iAlgo < namesAlgo.size(); ++iAlgo ) fileCacheIn >> nTrk[ namesAlgo.at( iAlgo ) ];
0384     for ( size_t iAlgo = 0; iAlgo < namesAlgo.size(); ++iAlgo ) fileCacheIn >> rate[ namesAlgo.at( iAlgo ) ];
0385     for ( size_t iAlgo = 0; iAlgo < namesAlgo.size(); ++iAlgo ) fileCacheIn >> chi2[ namesAlgo.at( iAlgo ) ];
0386     fileCacheIn >> offTrkCl;
0387     for ( size_t iDet    = 0; iDet    < namesDet.size()   ; ++iDet    ) fileCacheIn >> sToN[ namesDet.at( iDet ) ];
0388     for ( size_t iSubDet = 0; iSubDet < namesSubDet.size(); ++iSubDet ) fileCacheIn >> fractSubDet[ namesSubDet.at( iSubDet ) ];
0389     
0390     XMLNodePointer_t nodeRun( xml->NewChild( nodeRuns, 0, "RUN" ) );
0391     ostringstream sRun;
0392     sRun << iRun;
0393     xml->NewAttr( nodeRun, 0, "number", sRun.str().c_str() );
0394 
0395     Bool_t goodRun( kTRUE );
0396     UInt_t bitFlags( 0 );
0397     UInt_t bitNumber( 1 );
0398     XMLNodePointer_t nodeFlag( xml->NewChild( nodeRun, 0, "FLAG" ) );
0399     xml->NewAttr( nodeFlag, 0, "name", "minNEvt" );
0400     if ( nRuns == 0 ) flagList = "minNEvt, " + flagList;
0401     if ( nEvt < minNEvt ) {
0402       const string lineFlag( "no events" );
0403       lineTxt += " " + lineFlag;
0404       if ( goodRun ) lineTwiki += lineFlag;
0405       goodRun = kFALSE;
0406       ++nRunsNoEvents;
0407       xml->NewAttr( nodeFlag, 0, "value", "0" );
0408     } else {
0409       xml->NewAttr( nodeFlag, 0, "value", "1" );
0410       bitFlags |= ( 1 << bitNumber );
0411     }
0412     bool failedTracks( false );
0413     for ( size_t iAlgo = 0; iAlgo < namesAlgo.size(); ++iAlgo ) {
0414       ++bitNumber;
0415       if ( iAlgo == 0 ) nodeFlag = xml->NewChild( nodeRun, 0, "FLAG" );
0416       else              nodeFlag = xml->NewChild( nodeRun, 0, "FLAG", "Not included in global flag" );
0417       xml->NewAttr( nodeFlag, 0, "name", "minNTrk" );
0418       xml->NewAttr( nodeFlag, 0, "algo", namesAlgo.at( iAlgo ).c_str() );
0419       if ( nRuns == 0 ) flagList = "minNTrk (" + namesAlgo.at( iAlgo ) + "), " + flagList;
0420       if ( nTrk[ namesAlgo.at( iAlgo ) ] < minNTrk ) {
0421         const string lineFlag( "no " + namesAlgo.at( iAlgo ) + " tracks" );
0422         lineTxt += " " + lineFlag;
0423         xml->NewAttr( nodeFlag, 0, "value", "0" );
0424         if ( goodRun ) {
0425           if ( failedTracks ) lineTwiki += ", ";
0426           lineTwiki += lineFlag;
0427           failedTracks = true;
0428         }
0429         if ( iAlgo == 0 ) {
0430           goodRun = kFALSE;
0431           ++nRunsNoTracks;
0432         }
0433       } else {
0434         xml->NewAttr( nodeFlag, 0, "value", "1" );
0435         bitFlags |= ( 1 << bitNumber );
0436       }
0437     }
0438     for ( size_t iAlgo = 0; iAlgo < namesAlgo.size(); ++iAlgo ) {
0439       ++bitNumber;
0440       if ( iAlgo == 0 ) nodeFlag = xml->NewChild( nodeRun, 0, "FLAG" );
0441       else              nodeFlag = xml->NewChild( nodeRun, 0, "FLAG", "Not included in global flag" );
0442       xml->NewAttr( nodeFlag, 0, "name", "minRate" );
0443       xml->NewAttr( nodeFlag, 0, "algo", namesAlgo.at( iAlgo ).c_str() );
0444       if ( nRuns == 0 ) flagList = "minRate (" + namesAlgo.at( iAlgo ) + "), " + flagList;
0445       if ( rate[ namesAlgo.at( iAlgo ) ] < minRate ) {
0446         const string lineFlag( "too few " + namesAlgo.at( iAlgo ) + " tracks" );
0447         lineTxt += " " + lineFlag;
0448         xml->NewAttr( nodeFlag, 0, "value", "0" );
0449         if ( goodRun ) {
0450           if ( failedTracks ) lineTwiki += ", ";
0451           lineTwiki +=  lineFlag;
0452           failedTracks = true;
0453         }
0454         if ( iAlgo == 0 ) {
0455           goodRun = kFALSE;
0456         }
0457       } else {
0458         xml->NewAttr( nodeFlag, 0, "value", "1" );
0459         bitFlags |= ( 1 << bitNumber );
0460       }
0461     }
0462     nodeFlag = xml->NewChild( nodeRun, 0, "FLAG" );
0463     xml->NewAttr( nodeFlag, 0, "name", "maxOffTrkCl" );
0464     if ( nRuns == 0 ) flagList = "maxOffTrkCl, " + flagList;
0465     ++bitNumber;
0466     if ( offTrkCl > maxOffTrkCl ) {
0467       const string lineFlag( "too many offTrk clusters" );
0468       lineTxt += " " + lineFlag;
0469       if ( goodRun ) lineTwiki += lineFlag;
0470       goodRun = kFALSE;
0471       xml->NewAttr( nodeFlag, 0, "value", "0" );
0472     } else {
0473       xml->NewAttr( nodeFlag, 0, "value", "1" );
0474       bitFlags |= ( 1 << bitNumber );
0475     }
0476     for ( size_t iDet = 0; iDet < namesDet.size(); ++iDet ) {
0477       ++bitNumber;
0478       nodeFlag = xml->NewChild( nodeRun, 0, "FLAG" );
0479       xml->NewAttr( nodeFlag, 0, "name", "minSToN" );
0480       xml->NewAttr( nodeFlag, 0, "subdet", namesDet.at( iDet ).c_str() );
0481       if ( nRuns == 0 ) flagList = "minSToN (" + namesDet.at( iDet ) + "), " + flagList;
0482       if ( sToN[ namesDet.at( iDet ) ] < minSToN[ iDet ] ) {
0483         const string lineFlag( "too low S/N in " + namesDet.at( iDet ) );
0484         lineTxt += " " + lineFlag;
0485         if ( goodRun ) lineTwiki += lineFlag;
0486         goodRun = kFALSE;
0487         xml->NewAttr( nodeFlag, 0, "value", "0" );
0488       } else {
0489         xml->NewAttr( nodeFlag, 0, "value", "1" );
0490         bitFlags |= ( 1 << bitNumber );
0491       }
0492     }
0493     nodeFlag = xml->NewChild( nodeRun, 0, "FLAG" );
0494     xml->NewAttr( nodeFlag, 0, "name", "minFractSubDet" );
0495     xml->NewAttr( nodeFlag, 0, "subdet", "TIB" );
0496     if ( nRuns == 0 ) flagList = "minFractSubDet (TIB), " + flagList;
0497     ++bitNumber;
0498     if ( fractSubDet[ "SiStrip_TIB" ] < minFractSubDet && fractSubDet[ "SiStrip_TIB" ] != -1. ) {
0499       const string lineFlag( "too few modules good in TIB" );
0500       lineTxt += " " + lineFlag;
0501       if ( goodRun ) lineTwiki += lineFlag;
0502       goodRun = kFALSE;
0503       xml->NewAttr( nodeFlag, 0, "value", "0" );
0504     } else {
0505       xml->NewAttr( nodeFlag, 0, "value", "1" );
0506       bitFlags |= ( 1 << bitNumber );
0507     }
0508     nodeFlag = xml->NewChild( nodeRun, 0, "FLAG" );
0509     xml->NewAttr( nodeFlag, 0, "name", "minFractSubDet" );
0510     xml->NewAttr( nodeFlag, 0, "subdet", "TOB" );
0511     if ( nRuns == 0 ) flagList = "minFractSubDet (TOB), " + flagList;
0512     ++bitNumber;
0513     if ( fractSubDet[ "SiStrip_TOB" ] < minFractSubDet && fractSubDet[ "SiStrip_TOB" ] != -1. ) {
0514       const string lineFlag( "too few modules good in TOB" );
0515       lineTxt += " " + lineFlag;
0516       if ( goodRun ) lineTwiki += lineFlag;
0517       goodRun = kFALSE;
0518       xml->NewAttr( nodeFlag, 0, "value", "0" );
0519     } else {
0520       xml->NewAttr( nodeFlag, 0, "value", "1" );
0521       bitFlags |= ( 1 << bitNumber );
0522     }
0523     if ( avForwBackw ) { // FIXME Remove all this hardcoding
0524       ++bitNumber;
0525       if ( useTEC ) {
0526         nodeFlag = xml->NewChild( nodeRun, 0, "FLAG" );
0527         xml->NewAttr( nodeFlag, 0, "name", "minFractSubDet" );
0528         xml->NewAttr( nodeFlag, 0, "subdet", "TEC" );
0529         if ( nRuns == 0 ) flagList = "minFractSubDet (TEC), " + flagList;
0530         if ( fractSubDet[ "SiStrip_TECF" ] == -1. && fractSubDet[ "SiStrip_TECB" ] >= 0. ) {
0531           if ( fractSubDet[ "SiStrip_TECB" ] < minFractSubDet ) {
0532             const string lineFlag( "too few modules good in TECB (TECF off)" );
0533             lineTxt += " " + lineFlag;
0534             if ( goodRun ) lineTwiki += lineFlag;
0535             goodRun = kFALSE;
0536             xml->NewAttr( nodeFlag, 0, "value", "0" );
0537           } else {
0538             xml->NewAttr( nodeFlag, 0, "value", "1" );
0539             bitFlags |= ( 1 << bitNumber );
0540           }
0541         } else if ( fractSubDet[ "SiStrip_TECF" ] >= 0. && fractSubDet[ "SiStrip_TECB" ] == -1. ) {
0542           if ( fractSubDet[ "SiStrip_TECF" ] < minFractSubDet ) {
0543             const string lineFlag( "too few modules good in TECF (TECB off)" );
0544             lineTxt += " " + lineFlag;
0545             if ( goodRun ) lineTwiki += lineFlag;
0546             goodRun = kFALSE;
0547             xml->NewAttr( nodeFlag, 0, "value", "0" );
0548           } else {
0549             xml->NewAttr( nodeFlag, 0, "value", "1" );
0550             bitFlags |= ( 1 << bitNumber );
0551           }
0552         } else {
0553           if ( ( fractSubDet[ "SiStrip_TECF" ] + fractSubDet[ "SiStrip_TECB" ] ) / 2. < minFractSubDet && ( fractSubDet[ "SiStrip_TECF" ] + fractSubDet[ "SiStrip_TECB" ] ) / 2. != -1. ) {
0554             const string lineFlag( "too few modules good in TEC" );
0555             lineTxt += " " + lineFlag;
0556             if ( goodRun ) lineTwiki += lineFlag;
0557             goodRun = kFALSE;
0558             xml->NewAttr( nodeFlag, 0, "value", "0" );
0559           } else {
0560             xml->NewAttr( nodeFlag, 0, "value", "1" );
0561             bitFlags |= ( 1 << bitNumber );
0562           }
0563         }
0564       } else {
0565         nodeFlag = xml->NewChild( nodeRun, 0, "FLAG", "Not evaluated, bit set to \"true\"" );
0566         xml->NewAttr( nodeFlag, 0, "name", "minFractSubDet" );
0567         xml->NewAttr( nodeFlag, 0, "subdet", "TEC" );
0568         xml->NewAttr( nodeFlag, 0, "value", "-1" );
0569         if ( nRuns == 0 ) flagList = "minFractSubDet (TEC), " + flagList;
0570         bitFlags |= ( 1 << bitNumber );
0571       }
0572       ++bitNumber;
0573       if ( useTID ) {
0574         nodeFlag = xml->NewChild( nodeRun, 0, "FLAG" );
0575         xml->NewAttr( nodeFlag, 0, "name", "minFractSubDet" );
0576         xml->NewAttr( nodeFlag, 0, "subdet", "TID" );
0577         if ( nRuns == 0 ) flagList = "minFractSubDet (TID), " + flagList;
0578         if ( fractSubDet[ "SiStrip_TIDF" ] == -1. && fractSubDet[ "SiStrip_TIDB" ] >= 0. ) {
0579           if ( fractSubDet[ "SiStrip_TIDB" ] < minFractSubDet ) {
0580             const string lineFlag( "too few modules good in TIDB (TIDF off)" );
0581             lineTxt += " " + lineFlag;
0582             if ( goodRun ) lineTwiki += lineFlag;
0583             goodRun = kFALSE;
0584             xml->NewAttr( nodeFlag, 0, "value", "0" );
0585           } else {
0586             xml->NewAttr( nodeFlag, 0, "value", "1" );
0587             bitFlags |= ( 1 << bitNumber );
0588           }
0589         } else if ( fractSubDet[ "SiStrip_TIDF" ] >= 0. && fractSubDet[ "SiStrip_TIDB" ] == -1. ) {
0590           if ( fractSubDet[ "SiStrip_TIDF" ] < minFractSubDet ) {
0591             const string lineFlag( "too few modules good in TIDF (TIDB off)" );
0592             lineTxt += " " + lineFlag;
0593             if ( goodRun ) lineTwiki += lineFlag;
0594             goodRun = kFALSE;
0595             xml->NewAttr( nodeFlag, 0, "value", "0" );
0596           } else {
0597             xml->NewAttr( nodeFlag, 0, "value", "1" );
0598             bitFlags |= ( 1 << bitNumber );
0599           }
0600         } else {
0601           if ( ( fractSubDet[ "SiStrip_TIDF" ] + fractSubDet[ "SiStrip_TIDB" ] ) / 2. < minFractSubDet && ( fractSubDet[ "TIDF" ] + fractSubDet[ "TIDB" ] ) / 2. != -1. ) {
0602             const string lineFlag( "too few modules good in TID" );
0603             lineTxt += " " + lineFlag;
0604             if ( goodRun ) lineTwiki += lineFlag;
0605             goodRun = kFALSE;
0606             xml->NewAttr( nodeFlag, 0, "value", "0" );
0607           } else {
0608             xml->NewAttr( nodeFlag, 0, "value", "1" );
0609             bitFlags |= ( 1 << bitNumber );
0610           }
0611         }
0612       } else {
0613         nodeFlag = xml->NewChild( nodeRun, 0, "FLAG", "Not evaluated, bit set to \"true\"" );
0614         xml->NewAttr( nodeFlag, 0, "name", "minFractSubDet" );
0615         xml->NewAttr( nodeFlag, 0, "subdet", "TID" );
0616         xml->NewAttr( nodeFlag, 0, "value", "-1" );
0617         if ( nRuns == 0 ) flagList = "minFractSubDet (TID), " + flagList;
0618         bitFlags |= ( 1 << bitNumber );
0619       }
0620 //     } else {
0621 //       for ( size_t iSubDet = 0; iSubDet < namesSubDet.size(); ++iSubDet ) { // FIXME add 'useTEC' and 'useTID' here
0622 //         if ( fractSubDet[ namesSubDet.at( iSubDet ) ] < minFractSubDet && fractSubDet[ namesSubDet.at( iSubDet ) ] != -1. ) {
0623 //           if ( namesSubDet.at( iSubDet ) != "SiStrip_TECF" && namesSubDet.at( iSubDet ) != "SiStrip_TECB" && namesSubDet.at( iSubDet ) != "SiStrip_TIDF" && namesSubDet.at( iSubDet ) != "SiStrip_TIDB" ) { // don't care for TEC and TID
0624 //             lineTxt += " too few modules good in " + namesSubDet.at( iSubDet );
0625 //             goodRun = kFALSE;
0626 //             break;
0627 //           }
0628 //         }
0629 //       }
0630     }
0631 
0632     nodeFlag = xml->NewChild( nodeRun, 0, "GLOBAL_FLAG" );
0633     if ( goodRun ) {
0634       xml->NewAttr( nodeFlag, 0, "value", "1" );
0635       bitFlags |= ( 1 << 0 );
0636     } else {
0637       xml->NewAttr( nodeFlag, 0, "value", "0" );
0638     }
0639     if ( nRuns == 0 ) {
0640       flagList += "global";
0641       XMLNodePointer_t nodeFlagList( xml->NewChild( nodeCriteria, 0, "FLAG_LIST", flagList.c_str() ) );
0642     }
0643     ostringstream sBitFlags;
0644     sBitFlags << "0x" << hex << setfill( '0' ) << setw(8) << bitFlags<< dec << setfill( ' ' );
0645     nodeFlag = xml->NewChild( nodeRun, 0, "FLAG_BITS" );
0646     xml->NewAttr( nodeFlag, 0, "value", sBitFlags.str().c_str() );
0647     
0648     string flag( " " );
0649     if ( goodRun ) {
0650       flag += GOOD;    
0651       ++nRunsGood;
0652       nEventsGood += nEvt;
0653       gFracTrkCKF->Fill( iRun, rate[ namesAlgo.at( 0 ) ] );
0654       gFracTrkCosmic->Fill( iRun, rate[ namesAlgo.at( 1 ) ] );
0655       gFracTrkRS->Fill( iRun, rate[ namesAlgo.at( 2 ) ] );
0656       gChi2CKF->Fill( iRun, chi2[ namesAlgo.at( 0 ) ] );
0657       gChi2Cosmic->Fill( iRun, chi2[ namesAlgo.at( 1 ) ] );
0658       gChi2RS->Fill( iRun, chi2[ namesAlgo.at( 2 ) ] );
0659       gSnTIB->Fill( iRun, sToN[ namesDet.at( 0 ) ] );
0660       gSnTID->Fill( iRun, sToN[ namesDet.at( 1 ) ] );
0661       gSnTOB->Fill( iRun, sToN[ namesDet.at( 2 ) ] );
0662       gSnTEC->Fill( iRun, sToN[ namesDet.at( 3 ) ] );
0663       gClstOff->Fill( iRun, offTrkCl );   
0664     } else {
0665       flag += BAD;    
0666       ++nRunsBad;
0667     }
0668     sFlag += flag + " ";
0669     aFracTrkCKF->Fill( iRun, rate[ namesAlgo.at( 0 ) ] );
0670     aFracTrkCosmic->Fill( iRun, rate[ namesAlgo.at( 1 ) ] );
0671     aFracTrkRS->Fill( iRun, rate[ namesAlgo.at( 2 ) ] );
0672     aChi2CKF->Fill( iRun, chi2[ namesAlgo.at( 0 ) ] );
0673     aChi2Cosmic->Fill( iRun, chi2[ namesAlgo.at( 1 ) ] );
0674     aChi2RS->Fill( iRun, chi2[ namesAlgo.at( 2 ) ] );
0675     aSnTIB->Fill( iRun, sToN[ namesDet.at( 0 ) ] );
0676     aSnTID->Fill( iRun, sToN[ namesDet.at( 1 ) ] );
0677     aSnTOB->Fill( iRun, sToN[ namesDet.at( 2 ) ] );
0678     aSnTEC->Fill( iRun, sToN[ namesDet.at( 3 ) ] );
0679     aClstOff->Fill( iRun, offTrkCl );   
0680     
0681     fileOut           << iRun << sFlag << lineTxt   << endl;
0682     if ( nRuns > 0 ) fileCacheOutTwiki << endl;
0683     fileCacheOutTwiki << iRun << flag  << lineTwiki;
0684 
0685     ++nRuns;
0686     nEvents += nEvt;
0687   }
0688   nRunsNoTracks -= nRunsNoEvents;
0689   cout << "Runs processed                     : " << nRuns                                    << " (" << nEvents     << " ev.)" << endl;
0690   cout << "Runs good                          : " << nRunsGood                                << " (" << nEventsGood << " ev.)" << endl;
0691   cout << "Runs bad                           : " << nRunsBad                                                                   << endl;
0692   cout << "--> w/o events                     : " << nRunsNoEvents                                                              << endl;
0693   cout << "--> w/  events, but no (CKF) tracks: " << nRunsNoTracks                                                              << endl;
0694   cout << "--> other reason                   : " << nRunsBad - nRunsNoTracks - nRunsNoEvents                                   << endl;
0695   
0696   XMLDocPointer_t xmlDoc( xml->NewDoc() );
0697   xml->DocSetRootElement( xmlDoc, nodeMain );
0698   xml->SaveDoc( xmlDoc, nameFileOutXml.c_str() );
0699   xml->FreeDoc( xmlDoc );
0700   
0701   fileCacheOutTwiki.close();
0702   fileOut.close();
0703   fileCacheIn.close();
0704   
0705   while ( sleep > clock() ); // here the delay is needed
0706   TXMLEngine * xmlRROut = new TXMLEngine;
0707   XMLDocPointer_t xmlRROutDoc( xmlRROut->NewDoc() );
0708   xmlRROut->SaveDoc( xmlRROutDoc, string( nameFileRR  ).c_str() );
0709   xmlRROut->FreeDoc( xmlRROutDoc );
0710   ifstream fileRRIn;
0711   fileRRIn.open( nameFileRRTmp.c_str() );
0712   ofstream fileRRCorrect;
0713   fileRRCorrect.open( nameFileRR.c_str(), ios_base::app );
0714   const UInt_t maxLength( 131071 );
0715   char xmlLine[ maxLength ];
0716   while ( fileRRIn.getline( xmlLine, maxLength ) ) fileRRCorrect << xmlLine << endl;
0717   fileRRCorrect.close();
0718   fileRRIn.close();
0719   gSystem->Exec( string( "rm " + nameFileRRTmp ).c_str() );
0720   
0721   TXMLEngine * xmlRR = new TXMLEngine;
0722   XMLDocPointer_t xmlRRDoc( xmlRR->ParseFile( nameFileRR.c_str() ) );
0723   nodeMain = xmlRR->DocGetRootElement( xmlRRDoc );
0724   ifstream fileCacheInTwikiOld;
0725   ifstream fileCacheInTwiki;
0726   ofstream fileOutTwiki;
0727   fileCacheInTwikiOld.open( string( string( gSystem->Getenv( "CMSSW_BASE" ) ) + "/src/DQM/SiStripMonitorClient/data/" + nameFileInTwiki ).c_str() );
0728   fileCacheInTwiki.open( nameFileCacheTwiki.c_str() );
0729   fileOutTwiki.open( nameFileOutTwiki.c_str() );
0730   fileOutTwiki << "%TABLE{ sort=\"on\" initsort=\"1\" initdirection=\"down\" tableborder=\"0\" cellpadding=\"4\" cellspacing=\"3\" cellborder=\"0\" headerbg=\"#D5CCB1\"  headercolor=\"#666666\" databg=\"#FAF0D4, #F3DFA8\" headerrows=\"1\"}%" << endl;
0731   fileOutTwiki << "%EDITTABLE{ format=\"| text, -1| date, -1, %SERVERTIME{\"$day-$mon-$year\"}%, %e-%b-%Y| select, -1, ,*%GREEN%Good%ENDCOLOR%*, *%RED%Bad%ENDCOLOR%*, Waiting | text, -1| select, -1, ,%GREEN%*Good*%ENDCOLOR%, %RED%*Bad*%ENDCOLOR%, %ORANGE%*Excl*%ENDCOLOR% | select, -1, ,%GREEN%*Good*%ENDCOLOR%, %RED%*Bad*%ENDCOLOR% | select, -1, ,No, %RED%*Yes*%ENDCOLOR% | text, -1|\"changerows=\"on\" }%"                                                                                                                                              << endl;
0732   fileOutTwiki << "| *Run* | *Date* | *Flag (prompt reco)* | *Comment (prompt reco)* | *Flag (CMS)* | *Flag (re-reco)* | *changed (CMS &rarr; re-reco)* | *Comment (re-reco)* |"                                                                                                                                                                                  << endl;
0733 
0734   Int_t  iRunOld( 0 ), iRunNew( 0 ) ;
0735   string sFlagOld    , sFlagNew   , sFlagRR;
0736   string sCommentOld , sCommentNew, sFlagDiff;
0737   string sDateOld;
0738   Bool_t fileGood( true );
0739   Bool_t newWasBigger( iRunNew > iRunOld );
0740   while ( fileCacheInTwikiOld.good() ) {
0741     const size_t maxLength( 128 );
0742     if ( iRunNew >= iRunOld || ! fileGood ) {
0743       fileCacheInTwikiOld >> iRunOld >> sDateOld >> sFlagOld;
0744       sFlagOld = coloredFlag( sFlagOld );
0745       char cLineInOld[ maxLength ];
0746       fileCacheInTwikiOld.getline( cLineInOld, maxLength );
0747       sCommentOld = string( cLineInOld );
0748       const size_t firstCharOld( sCommentOld.find_first_not_of( " " ) );
0749       sCommentOld.erase( 0, firstCharOld );
0750     }
0751     while ( ( fileGood = fileCacheInTwiki.good() ) && iRunNew < iRunOld ) {
0752       if ( ! newWasBigger ) {
0753         char cLineInNew[ maxLength ];
0754         fileCacheInTwiki >> iRunNew >> sFlagNew;
0755         sFlagNew = coloredFlag( sFlagNew );
0756         fileCacheInTwiki.getline( cLineInNew, maxLength );
0757         sCommentNew = string( cLineInNew );
0758         const size_t firstCharNew( sCommentNew.find_first_not_of( " " ) );
0759         sCommentNew.erase( 0, firstCharNew );
0760         sFlagRR   = "";
0761         sFlagDiff = "";
0762         XMLNodePointer_t nodeRun( xmlRR->GetChild( nodeMain ) );
0763         while ( nodeRun ) {
0764           XMLNodePointer_t nodeRunChild = xmlRR->GetChild( nodeRun );
0765           while ( nodeRunChild && string( xmlRR->GetNodeName( nodeRunChild ) ) != "RUN_NUMBER" ) {
0766             nodeRunChild = xmlRR->GetNext( nodeRunChild );
0767           }
0768           if ( nodeRunChild ) {
0769             if ( atoi( xmlRR->GetNodeContent( nodeRunChild ) ) == iRunNew ) {
0770               nodeRunChild = xmlRR->GetChild( nodeRun );
0771               while ( nodeRunChild ) {
0772                 if ( string( xmlRR->GetNodeName( nodeRunChild ) ) == "SIST" ) {
0773                   sFlagRR = xmlRR->GetNodeContent( nodeRunChild );
0774                   break;
0775                 }
0776                 nodeRunChild = xmlRR->GetNext( nodeRunChild );
0777               }
0778               break;
0779             }
0780           }
0781           nodeRun = xmlRR->GetNext( nodeRun );
0782         }
0783         if      ( sFlagRR == "GOOD" ) sFlagRR = coloredFlag( GOOD );
0784         else if ( sFlagRR == "BAD"  ) sFlagRR = coloredFlag( BAD );
0785         else if ( sFlagRR == "EXCL" ) sFlagRR = coloredFlag( EXCL );
0786         if ( sFlagRR == sFlagNew || ( sFlagRR == coloredFlag( EXCL ) && sFlagNew == coloredFlag( BAD ) ) || sFlagRR.empty() )
0787           sFlagDiff = coloredFlag( NO );
0788         else
0789           sFlagDiff = coloredFlag( YES );
0790       }
0791       if ( iRunNew < iRunOld ) {
0792         fileOutTwiki << "|  " << iRunNew << " | | | |  " << sFlagRR << " |  " << sFlagNew << " |  " << sFlagDiff << " | " << sCommentNew << "  |" << endl;
0793         newWasBigger = false;
0794       }
0795     }
0796     if ( iRunNew == iRunOld ) {
0797       fileOutTwiki << "|  " << iRunNew << " |  " << sDateOld << " |  " << sFlagOld << " | " << sCommentOld << "  |  " << sFlagRR << " |  " << sFlagNew << " |  " << sFlagDiff << " | " << sCommentNew << "  |" << endl;
0798       newWasBigger = false;
0799     } else if ( iRunNew > iRunOld || ! fileGood ) {
0800       fileOutTwiki << "|  " << iRunOld << " |  " << sDateOld << " |  " << sFlagOld << " | " << sCommentOld << "  | | | | |" << endl;
0801       newWasBigger = true;
0802     }
0803   }
0804   
0805   xmlRR->FreeDoc( xmlRRDoc );
0806   fileCacheInTwiki.close();
0807   fileOutTwiki.close();
0808   gSystem->Exec( string( "rm " + nameFileRR ).c_str() );
0809   gSystem->Exec( string( "rm " + nameFileCacheTwiki ).c_str() );
0810   
0811   gStyle->SetOptStat( 0 );
0812   TCanvas * gCanvas = new TCanvas( "gCanvas", "SiStrip Offline Run Certification - CRAFT (good runs)", 1392, 1000 );
0813   gCanvas->Divide( 2, 2 );
0814   TVirtualPad * currentPad = gCanvas->cd( 1 );
0815   gFracTrkCosmic->DrawCopy( "PL" ); // has to be the first do be drawn due to highest values
0816   gFracTrkCKF->DrawCopy( "SamePL" );
0817   gFracTrkRS->DrawCopy( "SamePL" );
0818   currentPad->SaveAs( string( "gFracTrk." + drawFormat).c_str() );
0819   currentPad = gCanvas->cd( 2 );
0820   gChi2CKF->DrawCopy( "PL" );
0821   gChi2Cosmic->DrawCopy( "SamePL" );
0822   gChi2RS->DrawCopy( "SamePL" );
0823   currentPad->SaveAs( string( "gChi2." + drawFormat ).c_str() );
0824   currentPad = gCanvas->cd( 3 );
0825   gClstOff->DrawCopy( "PL" );
0826   currentPad->SaveAs( string( "gClstOff." + drawFormat ).c_str() );
0827   currentPad = gCanvas->cd( 4 );
0828   gSnTOB->DrawCopy( "PL" ); // has to be the first do be drawn due to highest values
0829   gSnTIB->DrawCopy( "SamePL" );
0830   gSnTID->DrawCopy( "SamePL" );
0831   gSnTEC->DrawCopy( "SamePL" );
0832   currentPad->SaveAs( string( "gSToN." + drawFormat ).c_str() );
0833   gCanvas->SaveAs( string( "gPlots." + drawFormat ).c_str() );
0834   if ( closeCanvas ) {
0835     gCanvas->Close();
0836     delete gCanvas;
0837   }
0838   TCanvas * aCanvas = new TCanvas( "aCanvas", "SiStrip Offline Run Certification - CRAFT (all runs)", 1392, 1000 );
0839   aCanvas->Divide( 2, 2 );
0840   currentPad = aCanvas->cd( 1 );
0841   aFracTrkRS->DrawCopy( "PL" ); // has to be the first do be drawn due to highest values
0842   aFracTrkCKF->DrawCopy( "SamePL" );
0843   aFracTrkCosmic->DrawCopy( "SamePL" );
0844   currentPad->SaveAs( string( "aFracTrk." + drawFormat ).c_str() );
0845   currentPad = aCanvas->cd( 2 );
0846   aChi2CKF->DrawCopy( "PL" );
0847   aChi2Cosmic->DrawCopy( "SamePL" );
0848   aChi2RS->DrawCopy( "SamePL" );
0849   currentPad->SaveAs( string( "aChi2." + drawFormat ).c_str() );
0850   currentPad = aCanvas->cd( 3 );
0851   aClstOff->DrawCopy( "PL" );
0852   currentPad->SaveAs( string( "aClstOff." + drawFormat ).c_str() );
0853   currentPad = aCanvas->cd( 4 );
0854   aSnTOB->DrawCopy( "PL" ); // has to be the first do be drawn due to highest values
0855   aSnTIB->DrawCopy( "SamePL" );
0856   aSnTID->DrawCopy( "SamePL" );
0857   aSnTEC->DrawCopy( "SamePL" );
0858   currentPad->SaveAs( string( "aSToN." + drawFormat ).c_str() );
0859   aCanvas->SaveAs( string( "aPlots." + drawFormat ).c_str() );
0860   if ( closeCanvas ) {
0861     aCanvas->Close();
0862     delete aCanvas;
0863   }
0864   
0865   gFracTrkCKF->Write();
0866   gFracTrkCosmic->Write();
0867   gFracTrkRS->Write();
0868   gChi2CKF->Write();
0869   gChi2Cosmic->Write();
0870   gChi2RS->Write();
0871   gSnTIB->Write();
0872   gSnTID->Write();
0873   gSnTOB->Write();
0874   gSnTEC->Write();
0875   gClstOff->Write();
0876   fileHistos->Close();
0877 }