00001
00002
00003
00004
00005
00006
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
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
00071
00072
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
00161
00162
00164
00165
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
00180
00181
00182
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
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
00240
00241
00242
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
00314
00315
00316
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 }