CMS 3D CMS Logo

DQMInstance.cc

Go to the documentation of this file.
00001 //
00002 //  File: EventFilter/src/SMProxyServer/DQMInstance.cc
00003 //
00004 //  Author:  W.Badgett (FNAL)
00005 //
00006 //  Container class for a single instance of a set of DQM objects
00007 //
00008 
00009 #include <iostream>
00010 
00011 #include "FWCore/Utilities/interface/DebugMacros.h"
00012 #include "EventFilter/StorageManager/interface/DQMInstance.h"
00013 #include "TH1.h"
00014 #include "TObjArray.h"
00015 #include "TObjString.h"
00016 #include "TString.h"
00017 #include "TDirectory.h"
00018 #include "sys/stat.h"
00019 #include "classlib/utils/Regexp.h"
00020 #include "boost/lexical_cast.hpp"
00021 
00022 // 15-Jul-2008, KAB: copied from DQMStore
00023 static const lat::Regexp s_rxmeval ("^<(.*)>(i|f|s|qr)=(.*)</\\1>$");
00024 
00025 using edm::debugit;
00026 using namespace std;
00027 using namespace stor;
00028 
00029 DQMGroupDescriptor::DQMGroupDescriptor(DQMInstance *instance,
00030                                        DQMGroup * group):
00031   instance_(instance),
00032   group_(group)
00033 {}
00034 
00035 DQMGroupDescriptor::~DQMGroupDescriptor() {}
00036 
00037 DQMFolder::DQMFolder()
00038 {}
00039 
00040 DQMFolder::~DQMFolder() 
00041 {
00042   for (std::map<std::string, TObject * >::iterator i0 = 
00043          dqmObjects_.begin(); i0 != dqmObjects_.end() ; ++i0)
00044   {
00045     TObject * object = i0->second;
00046     if ( object != NULL ) { delete(object); } 
00047   }
00048 }
00049 
00050 DQMGroup::DQMGroup(int readyTime):
00051   nUpdates_(0),
00052   readyTime_(readyTime)
00053 {
00054   lastUpdate_  = new TTimeStamp(0,0);
00055   lastServed_  = new TTimeStamp(0,0);
00056   firstUpdate_ = new TTimeStamp(0,0);
00057   firstUpdate_->Set();
00058 }
00059 
00060 void DQMGroup::incrementUpdates() 
00061 { 
00062   nUpdates_++;
00063   wasServedSinceUpdate_ = false;
00064   lastUpdate_->Set();  
00065 }
00066 
00067 bool DQMGroup::isReady(int currentTime)
00068 {
00069   time_t lastUpdateSecs = lastUpdate_->GetSec();
00070   // 29-Oct-2008, KAB - added a test that lastUpdateSecs is greater
00071   // than zero so that we don't report that a brand-new group is
00072   // ready before any updates have been added.
00073   return( lastUpdateSecs > 0 &&
00074           ( currentTime - lastUpdateSecs ) > readyTime_);
00075 }
00076 
00077 DQMGroup::~DQMGroup() 
00078 {
00079   if ( firstUpdate_ != NULL ) { delete(firstUpdate_);}
00080   if ( lastUpdate_  != NULL ) { delete(lastUpdate_);}
00081   if ( lastServed_  != NULL ) { delete(lastServed_);}
00082   for (std::map<std::string, DQMFolder * >::iterator i0 = 
00083          dqmFolders_.begin(); i0 != dqmFolders_.end() ; ++i0)
00084   {
00085     DQMFolder * folder = i0->second;
00086     if ( folder != NULL ) { delete(folder); } 
00087   }
00088 }
00089 
00090 
00091 DQMInstance::DQMInstance(int runNumber, 
00092                          int lumiSection, 
00093                          int instance,
00094                          int purgeTime,
00095                          int readyTime):
00096   runNumber_(runNumber),
00097   lumiSection_(lumiSection),
00098   instance_(instance),
00099   nUpdates_(0),
00100   purgeTime_(purgeTime),
00101   readyTime_(readyTime)
00102 {
00103   firstUpdate_ = new TTimeStamp();
00104   lastUpdate_  = new TTimeStamp();
00105 }
00106 
00107 
00108 DQMInstance::~DQMInstance()
00109 {
00110   if ( firstUpdate_ != NULL ) { delete(firstUpdate_);}
00111   if ( lastUpdate_ != NULL )  { delete(lastUpdate_);}
00112 
00113   for (std::map<std::string, DQMGroup * >::iterator i0 = 
00114          dqmGroups_.begin(); i0 != dqmGroups_.end() ; ++i0)
00115   {
00116     DQMGroup  * group     = i0->second;
00117     if ( group != NULL ) { delete(group); } 
00118   }
00119 }
00120 
00121 
00122 int DQMInstance::updateObject(std::string groupName,
00123                               std::string objectDirectory, 
00124                               TObject    *object,
00125                               int eventNumber)
00126 {
00127   lastEvent_ = eventNumber;
00128   std::string objectName = getSafeMEName(object);
00129   DQMGroup * group = dqmGroups_[groupName];
00130   if ( group == NULL )
00131   {
00132     group = new DQMGroup(readyTime_);
00133     dqmGroups_[groupName] = group;
00134   }
00135 
00136   DQMFolder * folder = group->dqmFolders_[objectDirectory];
00137   if ( folder == NULL )
00138   {
00139     folder = new DQMFolder();
00140     group->dqmFolders_[objectDirectory] = folder;
00141   }
00142 
00143   group->setLastEvent(eventNumber);
00144   TObject * storedObject = folder->dqmObjects_[objectName];
00145   if ( storedObject == NULL )
00146   {
00147     folder->dqmObjects_[objectName] = object->Clone(object->GetName());
00148   }
00149   else
00150   {
00151     if ( object->InheritsFrom("TH1") && 
00152          storedObject->InheritsFrom("TH1") )
00153     {
00154       TH1 * newHistogram    = (TH1 *)object;
00155       TH1 * storedHistogram = (TH1 *)storedObject;
00156       storedHistogram->Add(newHistogram);
00157     }
00158     else
00159     {
00160       // 15-Jul-2008, KAB - switch to the first instance at the 
00161       // request of Andreas Meyer...
00162 
00164       //delete(storedObject);
00165       //folder->dqmObjects_[objectName] = object->Clone(object->GetName());
00166     }
00167   }
00168 
00169   group->incrementUpdates();
00170   nUpdates_++;
00171   lastUpdate_->Set();
00172   return(nUpdates_);
00173 }
00174 
00175 bool DQMInstance::isReady(int currentTime)
00176 {
00177   bool readyFlag = true;
00178 
00179   // 29-Oct-2008, KAB - if there are no groups, switch
00180   // the default to false so that newly constructed DQMInstance
00181   // objects don't report ready==true before any groups have
00182   // even been created.
00183   if (dqmGroups_.size() == 0) readyFlag = false;
00184 
00185   for (std::map<std::string, DQMGroup * >::iterator i0 = 
00186          dqmGroups_.begin(); i0 != dqmGroups_.end() ; ++i0)
00187   {
00188     DQMGroup  * group     = i0->second;
00189     if ( group != NULL && ! group->isReady(currentTime) ) {
00190       readyFlag = false;
00191     }
00192   }
00193   return readyFlag;
00194 }
00195 
00196 bool DQMInstance::isStale(int currentTime)
00197 {
00198   return( ( currentTime - lastUpdate_->GetSec() ) > purgeTime_);
00199 }
00200 
00201 int DQMInstance::writeFile(std::string filePrefix, bool endRunFlag)
00202 {
00203   int reply = 0;
00204   char fileName[1024];
00205   TTimeStamp now;
00206   now.Set();
00207   std::string runString("Run ");
00208   runString.append(boost::lexical_cast<std::string>(runNumber_));
00209 
00210   for (std::map<std::string, DQMGroup * >::iterator i0 = 
00211          dqmGroups_.begin(); i0 != dqmGroups_.end() ; ++i0)
00212   {
00213     DQMGroup * group = i0->second;
00214     if (endRunFlag) {
00215       sprintf(fileName,"%s/DQM_V0001_EvF_R%9.9d.root", 
00216               filePrefix.c_str(), runNumber_);
00217     }
00218     else {
00219       sprintf(fileName,"%s/DQM_V0001_EvF_R%9.9d_L%6.6d.root", 
00220               filePrefix.c_str(), runNumber_, lumiSection_);
00221     }
00222 
00223     TFile * file = new TFile(fileName,"UPDATE");
00224     if (( file != NULL ) && file->IsOpen())
00225     {
00226       int ctr=0;
00227 
00228       // First create directories inside the root file
00229       TString token("/");
00230       for ( std::map<std::string, DQMFolder *>::iterator i1 = 
00231               group->dqmFolders_.begin(); i1 != group->dqmFolders_.end(); ++i1)
00232       {
00233         std::string folderName = i1->first;
00234         TString path(folderName.c_str());
00235         DQMFolder * folder = i1->second;
00236 
00237         TObjArray * tokens = path.Tokenize(token);
00238 
00239         // 15-Oct-2008, KAB - add several extra levels to the
00240         // directory structure to match consumer-based histograms.
00241         // The TObjArray is the owner of the memory used by its elements,
00242         // so it takes care of deleting the extra entries that we add.
00243         TObjString * tmpEntry;
00244         int origSize = tokens->GetEntries();
00245         if (origSize >= 2) {
00246           tokens->Expand(origSize + 3);
00247         }
00248         else {
00249           tokens->Expand(origSize + 2);
00250         }
00251         for (int idx = origSize-1; idx >= 0; --idx) {
00252           tmpEntry = (TObjString *) tokens->RemoveAt(idx);
00253           if (origSize >= 2 && idx > 0) {
00254             tokens->AddAt(tmpEntry, idx+3);
00255           }
00256           else {
00257             tokens->AddAt(tmpEntry, idx+2);
00258           }
00259         }
00260         if (origSize >= 2) {
00261           tmpEntry = new TObjString("Run summary");
00262           tokens->AddAt(tmpEntry, 3);
00263         }
00264         tmpEntry = new TObjString(runString.c_str());
00265         tokens->AddAt(tmpEntry, 1);
00266         tmpEntry = new TObjString("DQMData");
00267         tokens->AddAt(tmpEntry, 0);
00268 
00269         int nTokens = tokens->GetEntries();
00270         TDirectory * newDir = NULL;
00271         TDirectory * oldDir = (TDirectory *)file;
00272         for ( int j=0; j<nTokens; j++)
00273         {
00274           TString newDirName = ((TObjString *)tokens->At(j))->String();
00275           oldDir->cd();
00276           newDir = oldDir->GetDirectory(newDirName.Data(),kFALSE,"cd");
00277           if ( newDir == NULL )
00278           {
00279             newDir = oldDir->mkdir(newDirName.Data());
00280           }
00281           oldDir = newDir;
00282         }
00283         delete(tokens);
00284         oldDir->cd();
00285 
00286         for ( std::map<std::string, TObject *>::iterator i2 = 
00287               folder->dqmObjects_.begin(); i2 != folder->dqmObjects_.end(); 
00288               ++i2)
00289         {
00290           std::string objectName = i2->first;
00291           TObject *object = i2->second;
00292           if ( object != NULL ) 
00293           {
00294             object->Write();
00295             reply++;
00296             ctr++;
00297           }
00298         }
00299       }
00300       file->Close();
00301       delete(file);
00302       chmod(fileName,S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH );
00303       FDEBUG(1) << "Wrote file " << fileName << " " << ctr << " objects"
00304                 << std::endl; 
00305     }
00306   }
00307   return(reply);
00308 }
00309 
00310 DQMGroup * DQMInstance::getDQMGroup(std::string groupName)
00311 { return(dqmGroups_[groupName]);}
00312 
00313 // 15-Jul-2008, KAB - this method should probably exist in DQMStore
00314 // rather than here, but I'm going for expediency...
00315 // The main purpose of the method is to pull out the ME name
00316 // from scalar MEs (ints, floats, strings)
00317 std::string DQMInstance::getSafeMEName(TObject *object)
00318 {
00319   std::string rawName = object->GetName();
00320   std::string safeName = rawName;
00321 
00322   lat::RegexpMatch patternMatch;
00323   if (dynamic_cast<TObjString *>(object) &&
00324       s_rxmeval.match(rawName, 0, 0, &patternMatch)) {
00325     safeName = patternMatch.matchString(rawName, 1);
00326   }
00327 
00328   return safeName;
00329 }

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