Gaudi Framework, version v21r9

Home   Generated: 3 May 2010

THistSvc.cpp

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

Generated at Mon May 3 12:14:54 2010 for Gaudi Framework, version v21r9 by Doxygen version 1.5.6 written by Dimitri van Heesch, © 1997-2004