Gaudi Framework, version v21r8

Home   Generated: 17 Mar 2010

THistSvc.cpp

Go to the documentation of this file.
00001 #include "THistSvc.h"
00002 
00003 #include "GaudiKernel/SvcFactory.h"
00004 #include "GaudiKernel/ISvcLocator.h"
00005 #include "GaudiKernel/Tokenizer.h"
00006 #include "GaudiKernel/GaudiException.h"
00007 #include "GaudiKernel/Property.h"
00008 #include "GaudiKernel/IIncidentSvc.h"
00009 #include "GaudiKernel/IEventProcessor.h"
00010 
00011 #include "TROOT.h"
00012 #include "TFile.h"
00013 #include "TDirectory.h"
00014 #include "TKey.h"
00015 #include "TError.h"
00016 #include "TGraph.h"
00017 
00018 #include <sstream>
00019 #include <streambuf>
00020 #include <cstdio>
00021 
00022 using namespace std;
00023 
00024 
00025 DECLARE_SERVICE_FACTORY(THistSvc)
00026 
00027 inline void toupper(std::string &s)
00028 {
00029     std::string::iterator it=s.begin();
00030     while(it != s.end())
00031     {
00032         *it = toupper(*it);
00033         it++;
00034     }
00035 }
00036 
00037 
00038 //*************************************************************************//
00039 
00040 THistSvc::THistSvc( const std::string& name, ISvcLocator* svc )
00041   : base_class(name, svc), m_log(msgSvc(), name ), signaledStop(false) {
00042 
00043   declareProperty ("Output", m_outputfile );
00044   declareProperty ("Input", m_inputfile );
00045   declareProperty ("AutoSave", m_autoSave=0 );
00046   declareProperty ("PrintAll", m_print=false);
00047   declareProperty ("CompressionLevel", m_compressionLevel=1 );
00048   declareProperty ("MaxFileSize", m_maxFileSize=5120, 
00049                    "maximum file size in MB. if exceeded, will cause an abort");
00050 
00051   m_inputfile.declareUpdateHandler ( &THistSvc::setupInputFile,  this );
00052   m_outputfile.declareUpdateHandler( &THistSvc::setupOutputFile, this );
00053 }
00054 
00055 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00056 
00057 THistSvc::~THistSvc() {
00058 
00059 }
00060 
00061 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00062 
00063 StatusCode
00064 THistSvc::initialize() {
00065   GlobalDirectoryRestore restore;
00066 
00067   m_alreadyConnectedOutFiles.clear();
00068   m_alreadyConnectedInFiles.clear();
00069 
00070   StatusCode status = Service::initialize();
00071   m_log.setLevel( m_outputLevel.value() );
00072 
00073   if (status.isFailure()) {
00074     MsgStream log ( msgSvc(), name() );
00075     log << MSG::ERROR << "initializing service" << endmsg;
00076     return status;
00077   }
00078 
00079   vector<string>::const_iterator itr;
00080   StatusCode st(StatusCode::SUCCESS);
00081 
00082   try {
00083     setupOutputFile( m_outputfile );
00084   } catch ( GaudiException& err ) {
00085     m_log << MSG::ERROR
00086           << "Caught: " << err << endmsg;
00087     st = StatusCode::FAILURE;
00088   }
00089 
00090   try {
00091     setupInputFile( m_inputfile );
00092   } catch ( GaudiException& err ) {
00093     m_log << MSG::ERROR
00094           << "Caught: " << err << endmsg;
00095     st = StatusCode::FAILURE;
00096   }
00097 
00098   // Protect against multiple instances of TROOT
00099   if ( 0 == gROOT )   {
00100     static TROOT root("root","ROOT I/O");
00101     //    gDebug = 99;
00102   } else {
00103     m_log << MSG::VERBOSE << "ROOT already initialized, debug = "
00104           << gDebug<< endmsg;
00105   }
00106 
00107   IIncidentSvc* p_incSvc(0);
00108   
00109   if (service("IncidentSvc", p_incSvc, true).isFailure()) {
00110     m_log << MSG::ERROR << "unable to get the IncidentSvc" << endmsg;
00111     st = StatusCode::FAILURE;
00112   } else {
00113     p_incSvc->addListener( this, "EndEvent", 100, true);
00114   }
00115 
00116   if (st.isFailure()) {
00117     m_log << MSG::FATAL << "Unable to initialize THistSvc" << endmsg;
00118   }
00119 
00120   return st;
00121 
00122 }
00123 
00124 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00125 
00126 StatusCode
00127 THistSvc::reinitialize() {
00128 
00129   GlobalDirectoryRestore restore;
00130 
00131   m_log << MSG::WARNING << "reinitialize not implemented" << endmsg;
00132 
00133 
00134   return StatusCode::SUCCESS;
00135 
00136 }
00137 
00138 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00139 
00140 StatusCode
00141 THistSvc::finalize() {
00142 
00143   GlobalDirectoryRestore restore;
00144 
00145   m_log << MSG::DEBUG << "THistSvc::finalize" << endmsg;
00146 
00147   uidMap::const_iterator uitr;
00148   for (uitr=m_uids.begin(); uitr != m_uids.end(); ++uitr) {
00149 
00150     TObject* to = uitr->second.obj;
00151 
00152     string dirname("none");
00153     if (to->IsA()->InheritsFrom("TTree")) {
00154       TTree* tr = dynamic_cast<TTree*>(to);
00155       if (tr->GetDirectory() != 0) {
00156         dirname = tr->GetDirectory()->GetPath();
00157       }
00158     } else if (to->IsA()->InheritsFrom("TGraph")) {
00159       if (!uitr->second.temp) {
00160         dirname = uitr->second.file->GetPath();
00161         string id2(uitr->second.id);
00162         id2.erase(0,id2.find("/",1));
00163         id2.erase(id2.rfind("/"), id2.length());
00164         if (id2.find("/") == 0) {
00165           id2.erase(0,1);
00166         }
00167         dirname += id2;
00168       } else {
00169         dirname = "/tmp";
00170       }
00171     } else if (to->IsA()->InheritsFrom("TH1")) {
00172       TH1* th = dynamic_cast<TH1*>(to);
00173       if (th == 0) {
00174         m_log << MSG::ERROR << "Couldn't dcast: " << uitr->first << endmsg;
00175       } else {
00176         if (th->GetDirectory() != 0) {
00177           dirname = th->GetDirectory()->GetPath();
00178         }
00179       }
00180     }
00181 
00182     m_log << MSG::DEBUG << "uid: \"" << uitr->first << "\"  temp: "
00183         << uitr->second.temp << "  dir: " << dirname
00184         << endmsg;
00185 
00186 
00187 //     if (uitr->second.temp == true) {
00188 //       log << MSG::INFO << "Deleting \"" << uitr->first << "\"" << endmsg;
00189 //       delete uitr->second.obj;
00190 //     }
00191   }
00192 
00193   StatusCode sc = write();
00194   if (sc.isFailure()) {
00195     m_log << MSG::ERROR << "problems writing histograms" << endmsg;
00196   }
00197 
00198   if (m_print) {
00199     m_log << MSG::INFO << "Listing contents of ROOT files: " << endmsg;
00200   }
00201   vector<TFile*> deleted_files;
00202   map<string, pair<TFile*,Mode> >::const_iterator itr;
00203   for (itr = m_files.begin(); itr != m_files.end(); ++itr) {
00204 
00205     if (find(deleted_files.begin(), deleted_files.end(), itr->second.first) ==
00206         deleted_files.end()) {
00207       deleted_files.push_back(itr->second.first);
00208 
00209       m_log << MSG::DEBUG << "finalizing stream/file " << itr->first << ":"
00210             << itr->second.first->GetName()
00211             << endmsg;
00212     } else {
00213       m_log << MSG::DEBUG << "already finalized stream " << itr->first << endmsg;
00214       continue;
00215     }
00216 
00217 
00218     if (m_print && m_log.level() <= MSG::INFO) {
00219 
00220       m_log << MSG::INFO;
00221       m_log << "==> File: " << itr->second.first->GetName()
00222             << "  stream: " << itr->first << endmsg;
00223 
00224       itr->second.first->Print("base");
00225     }
00226 
00227     string tmpfn=itr->second.first->GetName();
00228 
00229     itr->second.first->Close();
00230 
00231     if (itr->second.second==SHARE) {
00232       TFile *outputfile;
00233       //Merge File
00234       try {
00235         m_log << MSG::DEBUG << "Opening Final Output File: " <<m_sharedFiles[itr->first].c_str()<<endmsg;
00236         outputfile = new TFile(m_sharedFiles[itr->first].c_str(), "UPDATE");
00237       } catch (const std::exception& Exception) {
00238       m_log << MSG::ERROR << "exception caught while trying to open root"
00239             << " file for appending: " << Exception.what() << std::endl
00240             << "  -> file probably corrupt." << endmsg;
00241       return StatusCode::FAILURE;
00242       } catch (...) {
00243         m_log << MSG::ERROR << "Problems opening output file  \"" << m_sharedFiles[itr->first]
00244             << "\" for append: probably corrupt" << endmsg;
00245         return StatusCode::FAILURE;
00246       }
00247 
00248       m_log << MSG::DEBUG << "THistSvc::write()::Merging Rootfile "<<endmsg;
00249       TFile *inputfile;
00250       try {
00251         m_log << MSG::DEBUG << "Openning again Temporary File: " <<tmpfn.c_str()<<endmsg;
00252         inputfile=new TFile(tmpfn.c_str(),"READ");
00253       } catch (const std::exception& Exception) {
00254         m_log << MSG::ERROR << "exception caught while trying to open root"
00255               << " file for appending: " << Exception.what() << std::endl
00256               << "  -> file probably corrupt." << endmsg;
00257         return StatusCode::FAILURE;
00258       } catch (...) {
00259         m_log << MSG::ERROR << "Problems opening output file  \"" 
00260               << tmpfn.c_str()
00261               << "\" for append: probably corrupt" << endmsg;
00262         return StatusCode::FAILURE;
00263       }
00264 
00265       MergeRootFile(outputfile, inputfile);
00266 
00267       outputfile->SetCompressionLevel( m_compressionLevel );
00268 
00269       outputfile->Write();
00270       outputfile->Close();
00271       inputfile->Close();
00272 
00273       m_log << MSG::DEBUG << "Trying to remove temporary file \"" << tmpfn
00274             << "\""<<endmsg;
00275 
00276       std::remove(tmpfn.c_str());
00277     }
00278     delete itr->second.first;
00279   }
00280 
00281   m_sharedFiles.clear();
00282   m_fileStreams.clear();
00283   m_files.clear();
00284   m_uids.clear();
00285   m_ids.clear();
00286   m_tobjs.clear();
00287 
00288   return Service::finalize();
00289 }
00290 
00291 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00292 
00293 bool
00294 THistSvc::browseTDir(TDirectory *dir) const {
00295 
00296   if (dir == 0) {
00297     std::cerr << "TDirectory == 0" << std::endl;
00298     return false;
00299   }
00300 
00301   GlobalDirectoryRestore restore;
00302 
00303   dir->cd();
00304 
00305 
00306   cout << "-> " << dir->GetPath() << "  "
00307        << dir->GetListOfKeys()->GetSize() << endl;
00308 
00309   //  TIter nextkey(dir->GetListOfKeys());
00310   TIter nextkey(dir->GetList());
00311   while (TKey *key = (TKey*)nextkey()) {
00312 
00313     TObject *obj = key->ReadObj();
00314     if (obj == 0) { cout << key->GetName() << " obj==0"<< endl; continue; }
00315     //    if (obj->IsA()->InheritsFrom("TDirectory")) {
00316       cout << "  Key: " << key->GetName() << "   "
00317            << " tit: " << obj->GetTitle() << "   "
00318            << " (" << key->GetClassName() << ")" << endl;
00319       //    }
00320   }
00321 
00322   nextkey = dir->GetListOfKeys();
00323   while (TKey *key = (TKey*)nextkey()) {
00324 
00325     TObject *obj = key->ReadObj();
00326     if (obj == 0) { cout << key->GetName() << " obj==0"<< endl; continue; }
00327     if (obj->IsA()->InheritsFrom("TDirectory")) {
00328       TDirectory *tt = dynamic_cast<TDirectory*>(obj);
00329       browseTDir(tt);
00330     }
00331   }
00332 
00333   return true;
00334 }
00335 
00336 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00337 
00338 StatusCode
00339 THistSvc::getTHists(TDirectory *td, TList & tl) const {
00340 
00341   GlobalDirectoryRestore restore;
00342 
00343   gErrorIgnoreLevel = kBreak;
00344 
00345   if (!td->cd()) {
00346     m_log << MSG::ERROR << "No such TDirectory \"" << td->GetPath() << "\""
00347           << endmsg;
00348     return StatusCode::FAILURE;
00349   }
00350 
00351   TIter nextkey(td->GetList());
00352   while (TObject *key = (TObject*)nextkey()) {
00353     if (key != 0) {
00354       if (key->IsA()->InheritsFrom("TH1")) { tl.Add(key); }
00355     }
00356   }
00357 
00358 
00359   return StatusCode::SUCCESS;
00360 
00361 }
00362 
00363 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00364 
00365 StatusCode
00366 THistSvc::getTHists(const std::string& dir, TList & tl) const {
00367 
00368   GlobalDirectoryRestore restore;
00369 
00370   gErrorIgnoreLevel = kBreak;
00371 
00372   StatusCode sc;
00373 
00374   if (!gDirectory->cd(dir.c_str())) {
00375     m_log << MSG::ERROR << "No such TDirectory \"" << dir << "\""
00376           << endmsg;
00377     sc = StatusCode::FAILURE;
00378   } else {
00379     sc = getTHists(gDirectory,tl);
00380   }
00381 
00382   return sc;
00383 
00384 }
00385 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00386 
00387 StatusCode
00388 THistSvc::getTTrees(TDirectory *td, TList & tl) const {
00389 
00390   GlobalDirectoryRestore restore;
00391 
00392   gErrorIgnoreLevel = kBreak;
00393 
00394   if (!td->cd()) {
00395     m_log << MSG::ERROR << "No such TDirectory \"" << td->GetPath() << "\""
00396           << endmsg;
00397     return StatusCode::FAILURE;
00398   }
00399 
00400   TIter nextkey(td->GetList());
00401   while (TObject *key = (TObject*)nextkey()) {
00402     if (key != 0) {
00403       if (key->IsA()->InheritsFrom("TTree")) { tl.Add(key); }
00404     }
00405   }
00406 
00407   return StatusCode::SUCCESS;
00408 
00409 }
00410 
00411 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00412 
00413 StatusCode
00414 THistSvc::getTTrees(const std::string& dir, TList & tl) const {
00415 
00416   GlobalDirectoryRestore restore;
00417 
00418   gErrorIgnoreLevel = kBreak;
00419 
00420   StatusCode sc;
00421 
00422   if (!gDirectory->cd(dir.c_str())) {
00423     m_log << MSG::ERROR << "No such TDirectory \"" << dir << "\""
00424           << endmsg;
00425     sc = StatusCode::FAILURE;
00426   } else {
00427     sc = getTTrees(gDirectory,tl);
00428   }
00429 
00430   return sc;
00431 
00432 }
00433 
00434 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00435 
00436 StatusCode
00437 THistSvc::deReg(TObject* obj) {
00438 
00439   objMap::iterator itr = m_tobjs.find(obj);
00440   if (itr != m_tobjs.end()) {
00441     THistID hid = itr->second;
00442 
00443     uidMap::iterator itr2 = m_uids.find(hid.id);
00444     if (itr2 == m_uids.end()) {
00445       m_log << MSG::ERROR << "Problems deregistering TObject \""
00446             << obj->GetName()
00447             << "\" with id \"" << hid.id << "\"" << endmsg;
00448       return StatusCode::FAILURE;
00449     }
00450 
00451     std::string id,root,rem;
00452     parseString(hid.id, root, rem);
00453 
00454     idMap::iterator itr3;
00455     bool found(false);
00456 
00457     std::pair<idMap::iterator, idMap::iterator> mitr = m_ids.equal_range(rem);
00458     if (mitr.first == mitr.second) {
00459       m_log << MSG::ERROR << "Problems deregistering TObject \""
00460             << obj->GetName()
00461             << "\" with id \"" << hid.id << "\"" << endmsg;
00462       return StatusCode::FAILURE;
00463     } else {
00464       for (itr3 = mitr.first; itr3 != mitr.second; ++itr3) {
00465         if (itr3->second.obj == obj) {
00466           found = true;
00467           break;
00468         }
00469       }
00470       if (!found) {
00471         m_log << MSG::ERROR << "Problems deregistering TObject \""
00472               << obj->GetName()
00473               << "\" with id \"" << hid.id << "\"" << endmsg;
00474       }
00475     }
00476 
00477     m_tobjs.erase(itr);
00478     m_uids.erase(itr2);
00479     m_ids.erase(itr3);
00480 
00481     return StatusCode::SUCCESS;
00482 
00483   } else {
00484     m_log << MSG::ERROR << "Cannot unregister TObject \"" << obj->GetName()
00485           << "\": not known to THistSvc" << endmsg;
00486     return StatusCode::FAILURE;
00487   }
00488 
00489 }
00490 
00491 
00492 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00493 
00494 StatusCode
00495 THistSvc::deReg(const std::string& id) {
00496 
00497   uidMap::iterator itr = m_uids.find(id);
00498   if (itr == m_uids.end()) {
00499     m_log << MSG::ERROR << "Problems deregistering id \""
00500           << id << "\"" << endmsg;
00501     return StatusCode::FAILURE;
00502   }
00503 
00504   TObject* obj = itr->second.obj;
00505 
00506   return deReg(obj);
00507 }
00508 
00509 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00510 
00511 StatusCode
00512 THistSvc::regHist(const std::string& id) {
00513 
00514   TH1 *hist(0);
00515 
00516   return regHist_i(hist, id);
00517 }
00518 
00519 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00520 
00521 StatusCode
00522 THistSvc::regHist(const std::string& id, TH1* hist) {
00523   return regHist_i(hist, id);
00524 }
00525 
00526 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00527 
00528 StatusCode
00529 THistSvc::regHist(const std::string& id, TH2* hist) {
00530   return regHist_i(hist, id);
00531 }
00532 
00533 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00534 
00535 StatusCode
00536 THistSvc::regHist(const std::string& id, TH3* hist) {
00537   return regHist_i(hist, id);
00538 }
00539 
00540 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00541 
00542 StatusCode
00543 THistSvc::regTree(const std::string& id) {
00544   TTree *hist(0);
00545   return regHist_i(hist, id);
00546 }
00547 
00548 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00549 
00550 StatusCode
00551 THistSvc::regTree(const std::string& id, TTree* hist) {
00552   StatusCode sc = regHist_i(hist, id);
00553   if (hist != 0 && m_autoSave != 0 && sc.isSuccess()) {
00554     hist->SetAutoSave(m_autoSave);
00555   }
00556   return sc;
00557 }
00558 
00559 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00560 
00561 StatusCode
00562 THistSvc::regGraph(const std::string& id) {
00563   TGraph *hist(0);
00564   return regHist_i(hist, id);
00565 }
00566 
00567 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00568 
00569 StatusCode
00570 THistSvc::regGraph(const std::string& id, TGraph* hist) {
00571   if ( strcmp(hist->GetName(),"Graph") == 0 ) {
00572 
00573     std::string id2(id);
00574     string::size_type i = id2.rfind("/");
00575     if (i != string::npos) {
00576       id2.erase(0,i+1);
00577     }
00578 
00579     m_log << MSG::INFO << "setting name of TGraph id: \"" << id << "\" to \""
00580           << id2 << "\" since it is unset" << endmsg;
00581     hist->SetName(id2.c_str());
00582   }
00583 
00584   return regHist_i(hist, id);
00585 }
00586 
00587 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00588 
00589 StatusCode
00590 THistSvc::getHist(const std::string& id, TH1*& hist) const {
00591   return getHist_i(id, hist);
00592 }
00593 
00594 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00595 
00596 StatusCode
00597 THistSvc::getHist(const std::string& id, TH2*& hist) const {
00598   return getHist_i(id, hist);
00599 }
00600 
00601 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00602 
00603 StatusCode
00604 THistSvc::getHist(const std::string& id, TH3*& hist) const {
00605   return getHist_i(id, hist);
00606 }
00607 
00608 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00609 
00610 std::vector<std::string>
00611 THistSvc::getHists() const {
00612 
00613   std::vector<std::string> names;
00614   names.reserve(m_uids.size());
00615 
00616   uidMap::const_iterator itr;
00617   for (itr = m_uids.begin(); itr != m_uids.end(); ++itr) {
00618     THistID tid = itr->second;
00619 
00620     if (tid.obj->IsA()->InheritsFrom("TH1")) {
00621       names.push_back(itr->first);
00622     }
00623 
00624   }
00625 
00626   return names;
00627 
00628 }
00629 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00630 
00631 StatusCode
00632 THistSvc::getTree(const std::string& id, TTree*& hist) const {
00633   return getHist_i(id, hist);
00634 }
00635 
00636 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00637 
00638 std::vector<std::string>
00639 THistSvc::getTrees() const {
00640 
00641   std::vector<std::string> names;
00642   names.reserve(m_uids.size());
00643 
00644   uidMap::const_iterator itr;
00645   for (itr = m_uids.begin(); itr != m_uids.end(); ++itr) {
00646     THistID tid = itr->second;
00647 
00648     if (tid.obj->IsA()->InheritsFrom("TTree")) {
00649       names.push_back(itr->first);
00650     }
00651 
00652   }
00653 
00654   return names;
00655 
00656 }
00657 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00658 
00659 StatusCode
00660 THistSvc::getGraph(const std::string& id, TGraph*& hist) const {
00661   return getHist_i(id, hist);
00662 }
00663 
00664 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00665 
00666 std::vector<std::string>
00667 THistSvc::getGraphs() const {
00668 
00669   std::vector<std::string> names;
00670   names.reserve(m_uids.size());
00671 
00672   uidMap::const_iterator itr;
00673   for (itr = m_uids.begin(); itr != m_uids.end(); ++itr) {
00674     THistID tid = itr->second;
00675 
00676     if (tid.obj->IsA()->InheritsFrom("TGraph")) {
00677       names.push_back(itr->first);
00678     }
00679 
00680   }
00681 
00682   return names;
00683 
00684 }
00685 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00686 
00687 StatusCode
00688 THistSvc::readHist(const std::string& id, TH1*& hist) const {
00689   return readHist_i(id, hist);
00690 }
00691 
00692 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00693 
00694 StatusCode
00695 THistSvc::readHist(const std::string& id, TH2*& hist) const {
00696   return readHist_i(id, hist);
00697 }
00698 
00699 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00700 
00701 StatusCode
00702 THistSvc::readHist(const std::string& id, TH3*& hist) const {
00703   return readHist_i(id, hist);
00704 }
00705 
00706 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00707 
00708 StatusCode
00709 THistSvc::readTree(const std::string& id, TTree*& hist) const {
00710   return readHist_i(id, hist);
00711 }
00712 
00713 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00714 
00715 bool
00716 THistSvc::findStream(const string& id, string& stream, string& rem,
00717                    TFile*& file) const {
00718 
00719   string::size_type pos = id.find("/");
00720 
00721   if (pos == string::npos) {
00722     stream = "temp";
00723     rem = id;
00724   } else if (pos != 0) {
00725     stream = "temp";
00726     rem = id;
00727   } else {
00728 
00729     string::size_type pos2 = id.find("/",pos+1);
00730 
00731     if (pos2 == string::npos) {
00732       m_log << MSG::ERROR << "badly formed Hist/Tree id: \"" << id << "\""
00733             << endmsg;
00734       return false;
00735     }
00736 
00737     parseString(id,stream,rem);
00738 
00739   }
00740 
00741   if (stream == "temp") {
00742     file = 0;
00743     return true;
00744   }
00745 
00746   map< string,pair<TFile*,Mode> >::const_iterator itr = m_files.find(stream);
00747   if (itr != m_files.end()) {
00748     file = itr->second.first;
00749   } else {
00750     file = 0;
00751     m_log << MSG::WARNING << "no stream \"" << stream
00752           << "\" associated with id: \"" << id << "\""
00753           << endmsg;
00754   }
00755 
00756   return true;
00757 
00758 }
00759 
00760 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00761 
00762 void
00763 THistSvc::parseString(const string& id, string& root, string& rem) const {
00764   string::size_type pos = id.find("/");
00765 
00766   if (pos == string::npos) {
00767     root = "";
00768     rem = id;
00769     return;
00770   }
00771 
00772   if (pos == 0) {
00773     parseString(id.substr(1,id.length()),root,rem);
00774   } else {
00775     root = id.substr(0,pos);
00776     rem = id.substr(pos+1,id.length());
00777   }
00778 
00779 }
00780 
00781 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00782 
00783 void
00784 THistSvc::setupInputFile( Property& /*m_inputfile*/ )
00785 {
00786   StatusCode sc = StatusCode::SUCCESS;
00787 
00788   typedef std::vector<std::string> Strings_t;
00789   for ( Strings_t::const_iterator
00790           itr  = m_inputfile.value().begin(),
00791           iEnd = m_inputfile.value().end();
00792         itr != iEnd;
00793         ++itr ) {
00794     if ( m_alreadyConnectedInFiles.end() ==
00795          m_alreadyConnectedInFiles.find( *itr ) ) {
00796       if ( connect(*itr).isFailure() ) {
00797         sc = StatusCode::FAILURE;
00798       } else {
00799         m_alreadyConnectedInFiles.insert( *itr );
00800       }
00801     }
00802   }
00803 
00804   if ( !sc.isSuccess() ) {
00805     throw GaudiException( "Problem connecting inputfile !!", name(),
00806                           StatusCode::FAILURE );
00807   }
00808   return;
00809 }
00810 
00811 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00812 
00813 void
00814 THistSvc::setupOutputFile( Property& /*m_outputfile*/ )
00815 {
00816   StatusCode sc = StatusCode::SUCCESS;
00817 
00818   typedef std::vector<std::string> Strings_t;
00819   for ( Strings_t::const_iterator
00820           itr  = m_outputfile.value().begin(),
00821           iEnd = m_outputfile.value().end();
00822         itr != iEnd;
00823         ++itr ) {
00824     if ( m_alreadyConnectedOutFiles.end() ==
00825          m_alreadyConnectedOutFiles.find( *itr ) ) {
00826       if ( connect(*itr).isFailure() ) {
00827         sc = StatusCode::FAILURE;
00828       } else {
00829         m_alreadyConnectedOutFiles.insert( *itr );
00830       }
00831     }
00832   }
00833 
00834   if ( !sc.isSuccess() ) {
00835     throw GaudiException( "Problem connecting outputfile !!", name(),
00836                           StatusCode::FAILURE );
00837   }
00838   return;
00839 }
00840 
00841 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00842 
00843 void
00844 THistSvc::updateFiles() {
00845 
00846   // If TTrees grow beyond TTree::fgMaxFileSize, a new file is
00847   // automatically created by root, and the old one closed. We
00848   // need to migrate all the UIDs over to show the correct file
00849   // pointer. This is ugly.
00850 
00851   uidMap::iterator uitr, uitr2;
00852   for (uitr=m_uids.begin(); uitr != m_uids.end(); ++uitr) {
00853     TObject* to = uitr->second.obj;
00854     TFile* oldFile = uitr->second.file;
00855     if (to->IsA()->InheritsFrom("TTree")) {
00856       TTree* tr = dynamic_cast<TTree*>(to);
00857       TFile* newFile = tr->GetCurrentFile();
00858 
00859       if (oldFile != newFile) {
00860         std::string newFileName = newFile->GetName();
00861         std::string oldFileName(""), streamName, rem;
00862         TFile* dummy;
00863         findStream(uitr->second.id, streamName, rem, dummy);
00864 
00865         map<string, pair<TFile*,Mode> >::iterator itr;
00866         for (itr=m_files.begin(); itr!= m_files.end(); ++itr) {
00867           if (itr->second.first == oldFile) {
00868             itr->second.first = newFile;
00869 
00870           }
00871         }
00872 
00873         uitr2 = uitr;
00874         for (; uitr2 != m_uids.end(); ++uitr2) {
00875           if (uitr2->second.file == oldFile) {
00876             uitr2->second.file = newFile;
00877           }
00878         }
00879 
00880         streamMap::iterator sitr;
00881         for (sitr = m_fileStreams.begin(); sitr!=m_fileStreams.end(); ++sitr) {
00882           if (sitr->second == streamName) {
00883             oldFileName = sitr->first;
00884             break;
00885           }
00886         }
00887 
00888         
00889 #ifndef NDEBUG
00890         m_log << MSG::DEBUG << "migrating uid: " << uitr->second.id
00891               << "   stream: " << streamName 
00892               << "   oldFile: " << oldFileName
00893               << "   newFile: " << newFileName
00894               << endmsg;
00895 #endif
00896 
00897 
00898         if (oldFileName != "") {
00899           while ( (sitr=m_fileStreams.find(oldFileName)) != m_fileStreams.end() ) {
00900 
00901 #ifndef NDEBUG
00902             m_log << MSG::DEBUG << "changing filename \"" << oldFileName
00903                   << "\" to \"" << newFileName << "\" for stream \""
00904                   << sitr->second << "\"" << endmsg;
00905 #endif
00906             m_fileStreams.erase(sitr);
00907             m_fileStreams.insert( make_pair<std::string,std::string>(newFileName,streamName) );
00908           }
00909 
00910 
00911         } else {
00912           m_log << MSG::ERROR
00913                 << "Problems updating fileStreams with new file name" << endmsg;
00914         }
00915 
00916       }
00917 
00918     }
00919   }
00920 
00921 }
00922 
00923 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00924 
00925 StatusCode
00926 THistSvc::write() {
00927 
00928   updateFiles();
00929 
00930   map<string, pair<TFile*,Mode> >::const_iterator itr;
00931   for (itr=m_files.begin(); itr!= m_files.end(); ++itr) {
00932     if (itr->second.second == WRITE || itr->second.second == UPDATE
00933         ||itr->second.second==SHARE) {
00934       itr->second.first->Write("",TObject::kOverwrite);
00935     } else if (itr->second.second == APPEND) {
00936       itr->second.first->Write("");
00937     }
00938   }
00939 
00940 
00941   m_log << MSG::DEBUG << "THistSvc::write()::List of Files connected in ROOT "
00942         << endmsg;
00943 
00944   TSeqCollection *filelist=gROOT->GetListOfFiles();
00945   for (int ii=0; ii<filelist->GetEntries(); ii++) {
00946     m_log << MSG::DEBUG
00947           << "THistSvc::write()::List of Files connected in ROOT: \""
00948           << filelist->At(ii)->GetName()<<"\""<<endmsg;
00949   }
00950 
00951   return StatusCode::SUCCESS;
00952 
00953 }
00954 
00955 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
00956 
00957 StatusCode
00958 THistSvc::connect(const std::string& ident) {
00959 
00960   Tokenizer tok(true);
00961 
00962   string::size_type loc = ident.find(" ");
00963   string stream = ident.substr(0,loc);
00964   char typ(0);
00965   typedef std::pair<std::string,std::string>      Prop;
00966   std::vector<Prop> props;
00967   string val,VAL,TAG,filename,db_typ("ROOT");
00968 
00969   tok.analyse(ident.substr(loc+1,ident.length()), " ", "", "", "=", "'", "'");
00970 
00971   for ( Tokenizer::Items::iterator i = tok.items().begin(); i != tok.items().end(); i++)    {
00972     const std::string& tag = (*i).tag();
00973     TAG = tag;
00974     toupper(TAG);
00975 
00976     val = (*i).value();
00977     VAL = val;
00978     toupper(VAL);
00979 
00980     if (TAG == "FILE" || TAG == "DATAFILE") {
00981       filename = val;
00982       removeDoubleSlash( filename );
00983     } else if ( TAG == "OPT" ) {
00984       if ( VAL == "APPEND" || VAL == "UPDATE" ) {
00985         typ = 'A';
00986       } else if ( VAL == "CREATE" || VAL == "NEW" || VAL == "WRITE" ) {
00987         typ = 'N';
00988       } else if ( VAL == "RECREATE" ) {
00989         typ = 'R';
00990       } else if (VAL == "SHARE") {
00991         typ = 'S';
00992       } else if ( VAL == "OLD" || VAL == "READ" ) {
00993         typ = 'O';
00994       } else {
00995         m_log << MSG::ERROR << "Unknown OPT: \"" << (*i).value() << "\""
00996             << endmsg;
00997         typ = 0;
00998       }
00999     } else if (TAG == "TYP") {
01000       db_typ = (*i).value();
01001     } else {
01002       props.push_back( Prop((*i).tag(), (*i).value()));
01003     }
01004 
01005   }
01006 
01007   if (stream == "temp") {
01008     m_log << MSG::ERROR << "in JobOption \"" << ident
01009           << "\": stream name \"temp\" reserved."
01010           << endmsg;
01011     return StatusCode::FAILURE;
01012   }
01013 
01014   if (db_typ != "ROOT") {
01015     m_log << MSG::ERROR << "in JobOption \"" << ident
01016           << "\": technology type \"" << db_typ << "\" not supported."
01017           << endmsg;
01018     return StatusCode::FAILURE;
01019   }
01020 
01021 
01022   if (m_files.find(stream) != m_files.end()) {
01023     m_log << MSG::ERROR << "in JobOption \"" << ident
01024           << "\":\n stream \"" << stream << "\" already connected to file: \""
01025           << m_files[stream].first->GetName() << "\""
01026           << endmsg;
01027     return StatusCode::FAILURE;
01028   }
01029 
01030   Mode newMode;
01031   if (typ == 'O') {
01032     newMode = THistSvc::READ;
01033   } else if (typ == 'N') {
01034     newMode = THistSvc::WRITE;
01035   } else if (typ == 'A') {
01036     newMode = THistSvc::APPEND;
01037   } else if (typ == 'R') {
01038     newMode = THistSvc::UPDATE;
01039   } else if (typ == 'S') {
01040     newMode = THistSvc::SHARE;
01041   } else {
01042     // something else?
01043     m_log << MSG::ERROR << "No OPT= specified or unknown access mode in: "
01044           << ident << endmsg;
01045     return StatusCode::FAILURE;
01046   }
01047 
01048   // Is this file already connected to another stream?
01049   if (m_fileStreams.find(filename) != m_fileStreams.end()) {
01050     std::pair<streamMap::iterator, streamMap::iterator> fitr =
01051       m_fileStreams.equal_range(filename);
01052 
01053     std::string oldstream = (fitr.first)->second;
01054 
01055     std::pair<TFile*,Mode> f_info = m_files[oldstream];
01056 
01057     if (newMode != f_info.second) {
01058       m_log << MSG::ERROR << "in JobOption \"" << ident
01059             << "\":\n file \"" << filename << "\" already opened by stream: \""
01060             << oldstream << "\" with different access mode."
01061             << endmsg;
01062       return StatusCode::FAILURE;
01063     } else {
01064       TFile *f2 = f_info.first;
01065       m_files[stream] = make_pair<TFile*,Mode>(f2,newMode);
01066       m_log << MSG::DEBUG << "Connecting stream: \"" << stream
01067             << "\" to previously opened TFile: \"" << filename << "\""
01068             << endmsg;
01069       return StatusCode::SUCCESS;
01070     }
01071   }
01072 
01073 
01074   TFile *f(0) ;
01075   if (newMode == THistSvc::READ) {
01076     // old file
01077 
01078     try {
01079       f = TFile::Open(filename.c_str(),"READ");
01080     } catch (const std::exception& Exception) {
01081       m_log << MSG::ERROR << "exception caught while trying to open root"
01082             << " file for reading: " << Exception.what() << std::endl
01083             << "  -> file probably corrupt." << endmsg;
01084       return StatusCode::FAILURE;
01085     } catch (...) {
01086       m_log << MSG::ERROR << "Problems opening input file  \"" << filename
01087             << "\": probably corrupt" << endmsg;
01088       return StatusCode::FAILURE;
01089     }
01090 
01091     if (!f->IsOpen()) {
01092       m_log << MSG::ERROR << "Unable to open input file \"" << filename
01093             << "\": file does not exist" << endmsg;
01094       return StatusCode::FAILURE;
01095     }
01096 
01097 
01098   } else if (newMode == THistSvc::WRITE) {
01099     // new file
01100 
01101     f = TFile::Open(filename.c_str(),"NEW");
01102     if (!f->IsOpen()) {
01103       m_log << MSG::ERROR << "Unable to create new output file \"" << filename
01104             << "\" for writing: file already exists" << endmsg;
01105       return StatusCode::FAILURE;
01106     }
01107     f->SetCompressionLevel( m_compressionLevel );
01108 
01109   } else if (newMode == THistSvc::APPEND) {
01110     // update file
01111 
01112     try {
01113       f =  TFile::Open(filename.c_str(),"UPDATE");
01114     } catch (const std::exception& Exception) {
01115       m_log << MSG::ERROR << "exception caught while trying to open root"
01116             << " file for appending: " << Exception.what() << std::endl
01117             << "  -> file probably corrupt." << endmsg;
01118       return StatusCode::FAILURE;
01119     } catch (...) {
01120       m_log << MSG::ERROR << "Problems opening output file  \"" << filename
01121             << "\" for append: probably corrupt" << endmsg;
01122       return StatusCode::FAILURE;
01123     }
01124 
01125     if (!f->IsOpen()) {
01126       m_log << MSG::ERROR << "Unable to open output file \"" << filename
01127             << "\" for appending" << endmsg;
01128       return StatusCode::FAILURE;
01129     }
01130     f->SetCompressionLevel( m_compressionLevel );
01131 
01132   } else if (newMode == THistSvc::SHARE) {
01133     // SHARE file type
01134     //For SHARE files, all data will be stored in a temp file and will be merged into the target file
01135     //in write() when finalize(), this help to solve some confliction. e.g. with storegate
01136     
01137     static int ishared = 0;
01138     stringstream out;
01139     string realfilename=filename;
01140     out << ishared++;
01141     filename = string("tmp_THistSvc_")+out.str()+string(".root");
01142     
01143     m_log << MSG::DEBUG << "Creating temp file \"" << filename
01144           << "\" and realfilename="<<realfilename << endmsg;
01145     m_sharedFiles[stream]=realfilename;
01146     
01147     try {
01148       f = TFile::Open(filename.c_str(),"NEW");
01149     } catch (const std::exception& Exception) {
01150       m_log << MSG::ERROR << "exception caught while trying to open root"
01151             << " file for appending: " << Exception.what() << std::endl
01152             << "  -> file probably corrupt." << endmsg;
01153       return StatusCode::FAILURE;
01154     } catch (...) {
01155       m_log << MSG::ERROR << "Problems opening output file  \"" << filename
01156             << "\" for append: probably corrupt" << endmsg;
01157       return StatusCode::FAILURE;
01158     }
01159     
01160     if (!f->IsOpen()) {
01161       m_log << MSG::ERROR << "Unable to open output file \"" << filename
01162           << "\" for appending" << endmsg;
01163       return StatusCode::FAILURE;
01164     }
01165     f->SetCompressionLevel( m_compressionLevel );
01166 
01167   } else if (newMode == THistSvc::UPDATE) {
01168     // update file
01169 
01170     try {
01171       f =  TFile::Open(filename.c_str(),"RECREATE");
01172     } catch (const std::exception& Exception) {
01173       m_log << MSG::ERROR << "exception caught while trying to open root"
01174             << " file for updating: " << Exception.what() << std::endl
01175             << "  -> file probably corrupt." << endmsg;
01176       return StatusCode::FAILURE;
01177     } catch (...) {
01178       m_log << MSG::ERROR << "Problems opening output file  \"" << filename
01179             << "\" for update: probably corrupt" << endmsg;
01180       return StatusCode::FAILURE;
01181     }
01182 
01183     if (!f->IsOpen()) {
01184       m_log << MSG::ERROR << "Unable to open output file \"" << filename
01185             << "\" for updating" << endmsg;
01186       return StatusCode::FAILURE;
01187     }
01188     f->SetCompressionLevel( m_compressionLevel );
01189 
01190   }
01191 
01192   m_files[stream] = make_pair<TFile*,Mode>(f,newMode);
01193   m_fileStreams.insert(make_pair<std::string,std::string>(filename,stream));
01194 
01195   m_log << MSG::DEBUG << "Opening TFile \"" << filename << "\"  stream: \""
01196         << stream << "\"  mode: \"" << typ << "\""
01197         << endmsg;
01198 
01199   return StatusCode::SUCCESS;
01200 }
01201 
01202 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
01203 
01204 TDirectory*
01205 THistSvc::changeDir(const THistSvc::THistID& hid) const {
01206 
01207   string uid = hid.id;
01208   TFile* file = hid.file;
01209   string stream, fdir, bdir, dir, id;
01210 
01211   if (file != 0) {
01212     file->cd("/");
01213   } else {
01214     gROOT->cd();
01215   }
01216 
01217   fdir = uid;
01218   bdir = dirname(fdir);
01219 
01220   while ( (dir = dirname(fdir)) != "") {
01221     if (! gDirectory->GetKey(dir.c_str())) {
01222       gDirectory->mkdir(dir.c_str());
01223     }
01224     gDirectory->cd(dir.c_str());
01225   }
01226 
01227   return gDirectory;
01228 
01229 }
01230 
01231 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
01232 
01233 std::string
01234 THistSvc::dirname(std::string& dir) const {
01235 
01236 
01237   string::size_type i = dir.find("/");
01238 
01239   if (i == string::npos) {
01240     return "";
01241   }
01242 
01243   if ( i == 0 ) {
01244     dir.erase(0,1);
01245     return dirname(dir);
01246   }
01247 
01248   string root = dir.substr(0,i);
01249   dir.erase(0,i);
01250 
01251   return root;
01252 
01253 }
01254 
01255 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
01256 
01257 THistSvc::GlobalDirectoryRestore::GlobalDirectoryRestore() {
01258   m_gd = gDirectory;
01259   m_gf = gFile;
01260   m_ge = gErrorIgnoreLevel;
01261 }
01262 
01263 THistSvc::GlobalDirectoryRestore::~GlobalDirectoryRestore() {
01264   gDirectory = m_gd;
01265   gFile = m_gf;
01266   gErrorIgnoreLevel = m_ge;
01267 }
01268 
01269 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
01270 
01271 void
01272 THistSvc::removeDoubleSlash(std::string& id) const {
01273 
01274   while (id.find("//") != std::string::npos) {
01275     id.replace(id.find("//"),2,"/");
01276   }
01277 
01278 }
01279 
01280 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
01281 
01282 void THistSvc::MergeRootFile(TDirectory *target, TDirectory *source) {
01283 
01284   m_log <<MSG::DEBUG << "Target path: " << target->GetPath() << endmsg;
01285   TString path( (char*)strstr(target->GetPath(), ":") );
01286   path.Remove( 0, 2);
01287 
01288   source->cd(path);
01289   TDirectory *current_sourcedir = gDirectory;
01290 
01291   // loop over all keys in this directory
01292   TList *lkeys=current_sourcedir->GetListOfKeys();
01293   int nkeys=lkeys->GetEntries();
01294   TKey *key;
01295   for (int jj=0; jj<nkeys; jj++) {
01296     key=(TKey*) lkeys->At(jj);
01297     string pathnameinsource=current_sourcedir->GetPath()+string("/")+key->GetName();
01298     m_log <<MSG::DEBUG << "Reading Key:" << pathnameinsource << endmsg;
01299     //key->Dump();
01300     //TObject *obj=key->ReadObj();
01301     TObject *obj=source->Get(pathnameinsource.c_str());
01302 
01303     if (obj->IsA()->InheritsFrom("TDirectory") ) {
01304       // it's a subdirectory
01305 
01306       m_log <<MSG::DEBUG << "Found subdirectory " << obj->GetName()
01307             << endmsg;
01308 
01309       // create a new subdir of same name and title in the target file
01310       target->cd();
01311       TDirectory *newtargetdir =
01312         target->mkdir(obj->GetName(), obj->GetTitle() );
01313 
01314       MergeRootFile(newtargetdir, source);
01315 
01316     } else if (obj->IsA()->InheritsFrom("TTree")) {
01317       m_log <<MSG::DEBUG << "Found TTree " << obj->GetName() << endmsg;
01318       TTree *mytree=dynamic_cast<TTree*>(obj);
01319       int nentries=(int) mytree->GetEntries();
01320       mytree->SetBranchStatus("*",1);
01321 
01322       m_log <<MSG::DEBUG << "Dumping TTree " << nentries <<" entries"
01323           << endmsg;
01324       //mytree->Print();
01325       //for (int ij=0; ij<nentries; ij++) {
01326       //m_log <<MSG::DEBUG << "Dumping TTree Show( " << ij <<" )"
01327       //<< endmsg;
01328       //mytree->Show(ij);
01329       //}
01330       target->cd();
01331       mytree->CloneTree();
01332 
01333       //m_log <<MSG::DEBUG << "Writing TTree to target file: ( "
01334       //<< mycopiedtree->Write(key->GetName()) <<" ) bytes written"
01335       //<< endmsg;
01336 
01337     } else if (obj) {
01338       target->cd();
01339       obj->Write(key->GetName() );
01340     }
01341 
01342   } // while ( ( TKey *key = (TKey*)nextkey() ) )
01343 
01344   // save modifications to target file
01345 
01346 }
01347 
01348 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
01349 
01350 bool
01351 THistSvc::exists( const std::string& name ) const {
01352 
01353   TH1* h;
01354 
01355   return getHist_i(name,h,true).isSuccess();
01356 
01357 
01358 }
01359 
01360 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
01361 
01362 void
01363 THistSvc::handle( const Incident& /* inc */ ) {
01364 
01365   if (signaledStop) return ;
01366 
01367   // convert to bytes.
01368   Long64_t mfs = (Long64_t)m_maxFileSize.value() * (Long64_t)1048576;
01369 
01370   updateFiles();
01371 
01372   map<string, pair<TFile*,Mode> >::const_iterator itr;
01373   for (itr=m_files.begin(); itr!= m_files.end(); ++itr) {
01374     TFile* tf = itr->second.first;
01375   
01376 #ifndef NDEBUG
01377     m_log << MSG::DEBUG << "stream: " << itr->first << "  name: "
01378           << tf->GetName() << "  size: " << tf->GetSize()
01379           << endmsg;
01380 #endif
01381 
01382     // Signal job to terminate if output file is too large
01383     if (tf->GetSize() > mfs) {
01384 
01385       signaledStop = true;
01386 
01387       m_log << MSG::FATAL << "file \"" << tf->GetName() 
01388             << "\" associated with stream \"" << itr->first 
01389             << "\" has exceeded the max file size of "
01390             << m_maxFileSize.value() << "MB. Terminating Job."
01391             << endmsg;
01392 
01393       IEventProcessor* evt(0);
01394       if (service("ApplicationMgr", evt, true).isSuccess()) {
01395         evt->stopRun();
01396         evt->release();
01397       } else {
01398         abort();
01399       }
01400     }
01401   }
01402 }

Generated at Wed Mar 17 18:06:50 2010 for Gaudi Framework, version v21r8 by Doxygen version 1.5.6 written by Dimitri van Heesch, © 1997-2004