| # Gaudi Framework, version v22r2 |

Home |  | Generated: Tue May 10 2011

# 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/FileIncident.h"
    00016 #include "GaudiKernel/IEventProcessor.h"
    00017 #include "GaudiKernel/IJobOptionsSvc.h"
    00018
    00019
    00020 #include "TROOT.h"
    00021 #include "TFile.h"
    00022 #include "TDirectory.h"
    00023 #include "TKey.h"
    00024 #include "TError.h"
    00025 #include "TGraph.h"
    00026
    00027 #include <sstream>
    00028 #include <streambuf>
    00029 #include <cstdio>
    00030
    00031 using namespace std;
    00032
    00033
    00034 DECLARE_SERVICE_FACTORY(THistSvc)
    00035
    00036 inline void toupper(std::string &s)
    00037 {
    00038   std::transform(s.begin(), s.end(), s.begin(),
    00039                  (int(*)(int)) toupper);
    00040 }
    00041
    00042
    00043 //*************************************************************************//
    00044
    00045 THistSvc::THistSvc( const std::string& name, ISvcLocator* svc )
    00046   : base_class(name, svc), m_log(msgSvc(), name ), signaledStop(false) {
    00047
    00048   declareProperty ("AutoSave", m_autoSave=0 );
    00049   declareProperty ("AutoFlush", m_autoFlush=0 );
    00050   declareProperty ("PrintAll", m_print=false);
    00051   declareProperty ("MaxFileSize", m_maxFileSize=10240,
    00052                    "maximum file size in MB. if exceeded, will cause an abort");
    00053   declareProperty ("CompressionLevel", m_compressionLevel=1 )->declareUpdateHandler( &THistSvc::setupCompressionLevel, this );
    00054   declareProperty ("Output", m_outputfile )->declareUpdateHandler( &THistSvc::setupOutputFile, this );
    00055   declareProperty ("Input", m_inputfile )->declareUpdateHandler ( &THistSvc::setupInputFile,  this );
    00056
    00057
    00058 }
    00059
    00060 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00061
    00062 THistSvc::~THistSvc() {
    00063
    00064 }
    00065
    00066 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00067
    00068 StatusCode
    00069 THistSvc::initialize() {
    00070   GlobalDirectoryRestore restore;
    00071
    00072   m_alreadyConnectedOutFiles.clear();
    00073   m_alreadyConnectedInFiles.clear();
    00074
    00075
    00076   // Super ugly hack to make sure we have the OutputLevel set first, so we
    00077   // can see DEBUG printouts in update handlers.
    00078   IJobOptionsSvc* jos(0);
    00079   if( serviceLocator()->service( "JobOptionsSvc", jos, true ).isSuccess() ) {
    00080     const std::vector<const Property*> *props = jos->getProperties( name() );
    00081
    00082     if (props != NULL) {
    00083       for ( std::vector<const Property*>::const_iterator cur = props->begin();
    00084             cur != props->end(); cur++) {
    00085         if ( (*cur)->name() == "OutputLevel" ) {
    00086           setProperty( **cur ).ignore();
    00087           m_log.setLevel( m_outputLevel.value() );
    00088           break;
    00089         }
    00090       }
    00091     }
    00092   }
    00093
    00094
    00095   StatusCode status = Service::initialize();
    00096   m_log.setLevel( m_outputLevel.value() );
    00097
    00098   if (status.isFailure()) {
    00099     m_log << MSG::ERROR << "initializing service" << endmsg;
    00100     return status;
    00101   }
    00102
    00103   vector<string>::const_iterator itr;
    00104   StatusCode st(StatusCode::SUCCESS);
    00105
    00106   try {
    00107     setupOutputFile( m_outputfile );
    00108   } catch ( GaudiException& err ) {
    00109     m_log << MSG::ERROR
    00110           << "Caught: " << err << endmsg;
    00111     st = StatusCode::FAILURE;
    00112   }
    00113
    00114   try {
    00115     setupInputFile( m_inputfile );
    00116   } catch ( GaudiException& err ) {
    00117     m_log << MSG::ERROR
    00118           << "Caught: " << err << endmsg;
    00119     st = StatusCode::FAILURE;
    00120   }
    00121
    00122   // Protect against multiple instances of TROOT
    00123   if ( 0 == gROOT )   {
    00124     static TROOT root("root","ROOT I/O");
    00125     //    gDebug = 99;
    00126   } else {
    00127     if (m_log.level() <= MSG::VERBOSE)
    00128       m_log << MSG::VERBOSE << "ROOT already initialized, debug = "
    00129             << gDebug<< endmsg;
    00130   }
    00131
    00132   IIncidentSvc* p_incSvc(0);
    00133
    00134   if (service("IncidentSvc", p_incSvc, true).isFailure()) {
    00135     m_log << MSG::ERROR << "unable to get the IncidentSvc" << endmsg;
    00136     st = StatusCode::FAILURE;
    00137   } else {
    00138     p_incSvc->addListener( this, "EndEvent", 100, true);
    00139   }
    00140
    00141   if (st.isFailure()) {
    00142     m_log << MSG::FATAL << "Unable to initialize THistSvc" << endmsg;
    00143   }
    00144
    00145   return st;
    00146
    00147 }
    00148
    00149 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00150
    00151 StatusCode
    00152 THistSvc::reinitialize() {
    00153
    00154   GlobalDirectoryRestore restore;
    00155
    00156   m_log << MSG::WARNING << "reinitialize not implemented" << endmsg;
    00157
    00158
    00159   return StatusCode::SUCCESS;
    00160
    00161 }
    00162
    00163 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00164
    00165 StatusCode
    00166 THistSvc::finalize() {
    00167
    00168   GlobalDirectoryRestore restore;
    00169
    00170   if (m_log.level() <= MSG::DEBUG)
    00171     m_log << MSG::DEBUG << "THistSvc::finalize" << endmsg;
    00172
    00173   uidMap::const_iterator uitr;
    00174   for (uitr=m_uids.begin(); uitr != m_uids.end(); ++uitr) {
    00175
    00176     TObject* to = uitr->second.obj;
    00177
    00178     string dirname("none");
    00179     if (to->IsA()->InheritsFrom("TTree")) {
    00180       TTree* tr = dynamic_cast<TTree*>(to);
    00181       if (tr->GetDirectory() != 0) {
    00182         dirname = tr->GetDirectory()->GetPath();
    00183       }
    00184     } else if (to->IsA()->InheritsFrom("TGraph")) {
    00185       if (!uitr->second.temp) {
    00186         dirname = uitr->second.file->GetPath();
    00187         string id2(uitr->second.id);
    00188         id2.erase(0,id2.find("/",1));
    00189         id2.erase(id2.rfind("/"), id2.length());
    00190         if (id2.find("/") == 0) {
    00191           id2.erase(0,1);
    00192         }
    00193         dirname += id2;
    00194       } else {
    00195         dirname = "/tmp";
    00196       }
    00197     } else if (to->IsA()->InheritsFrom("TH1")) {
    00198       TH1* th = dynamic_cast<TH1*>(to);
    00199       if (th == 0) {
    00200         m_log << MSG::ERROR << "Couldn't dcast: " << uitr->first << endmsg;
    00201       } else {
    00202         if (th->GetDirectory() != 0) {
    00203           dirname = th->GetDirectory()->GetPath();
    00204         }
    00205       }
    00206     }
    00207
    00208 #ifndef NDEBUG
    00209     if (m_log.level() <= MSG::DEBUG)
    00210       m_log << MSG::DEBUG << "uid: \"" << uitr->first << "\"  temp: "
    00211             << uitr->second.temp << "  dir: " << dirname
    00212             << endmsg;
    00213 #endif
    00214
    00215
    00216 //     if (uitr->second.temp == true) {
    00217 //       log << MSG::INFO << "Deleting \"" << uitr->first << "\"" << endmsg;
    00218 //       delete uitr->second.obj;
    00219 //     }
    00220   }
    00221
    00222   StatusCode sc = write();
    00223   if (sc.isFailure()) {
    00224     m_log << MSG::ERROR << "problems writing histograms" << endmsg;
    00225   }
    00226
    00227   if (m_print) {
    00228     m_log << MSG::INFO << "Listing contents of ROOT files: " << endmsg;
    00229   }
    00230   vector<TFile*> deleted_files;
    00231   map<string, pair<TFile*,Mode> >::const_iterator itr;
    00232   for (itr = m_files.begin(); itr != m_files.end(); ++itr) {
    00233
    00234     if (find(deleted_files.begin(), deleted_files.end(), itr->second.first) ==
    00235         deleted_files.end()) {
    00236       deleted_files.push_back(itr->second.first);
    00237
    00238 #ifndef NDEBUG
    00239       if (m_log.level() <= MSG::DEBUG)
    00240         m_log << MSG::DEBUG << "finalizing stream/file " << itr->first << ":"
    00241               << itr->second.first->GetName()
    00242               << endmsg;
    00243 #endif
    00244     } else {
    00245 #ifndef NDEBUG
    00246       if (m_log.level() <= MSG::DEBUG)
    00247         m_log << MSG::DEBUG << "already finalized stream " << itr->first << endmsg;
    00248 #endif
    00249       continue;
    00250     }
    00251
    00252
    00253     if (m_print && m_log.level() <= MSG::INFO) {
    00254
    00255       m_log << MSG::INFO;
    00256       m_log << "==> File: " << itr->second.first->GetName()
    00257             << "  stream: " << itr->first << endmsg;
    00258
    00259       itr->second.first->Print("base");
    00260     }
    00261
    00262     string tmpfn=itr->second.first->GetName();
    00263
    00264     itr->second.first->Close();
    00265
    00266     IIncidentSvc *pi(0);
    00267     if (service("IncidentSvc",pi).isFailure()) {
    00268       m_log << MSG::ERROR << "Unable to get the IncidentSvc" << endmsg;
    00269       return StatusCode::FAILURE;
    00270     }
    00271
    00272     if (itr->second.second==SHARE) {
    00273       TFile *outputfile;
    00274       //Merge File
    00275       try {
    00276         if (m_log.level() <= MSG::DEBUG)
    00277           m_log << MSG::DEBUG << "Opening Final Output File: " <<m_sharedFiles[itr->first].c_str()<<endmsg;
    00278         outputfile = new TFile(m_sharedFiles[itr->first].c_str(), "UPDATE");
    00279       } catch (const std::exception& Exception) {
    00280         m_log << MSG::ERROR << "exception caught while trying to open root"
    00281               << " file for appending: " << Exception.what() << std::endl
    00282               << "  -> file probably corrupt." << endmsg;
    00283         pi->fireIncident(FileIncident(name(), IncidentType::FailOutputFile,
    00284                                       m_sharedFiles[itr->first]));
    00285         return StatusCode::FAILURE;
    00286       } catch (...) {
    00287         m_log << MSG::ERROR << "Problems opening output file  \""
    00288               << m_sharedFiles[itr->first]
    00289               << "\" for append: probably corrupt" << endmsg;
    00290         pi->fireIncident(FileIncident(name(), IncidentType::FailOutputFile,
    00291                                       m_sharedFiles[itr->first]));
    00292         return StatusCode::FAILURE;
    00293       }
    00294
    00295       pi->fireIncident(FileIncident(name(), IncidentType::WroteToOutputFile,
    00296                                     m_sharedFiles[itr->first]));
    00297
    00298       if (m_log.level() <= MSG::DEBUG)
    00299         m_log << MSG::DEBUG << "THistSvc::write()::Merging Rootfile "<<endmsg;
    00300       TFile *inputfile;
    00301       try {
    00302         if (m_log.level() <= MSG::DEBUG)
    00303           m_log << MSG::DEBUG << "Openning again Temporary File: " <<tmpfn.c_str()<<endmsg;
    00304         inputfile=new TFile(tmpfn.c_str(),"READ");
    00305       } catch (const std::exception& Exception) {
    00306         m_log << MSG::ERROR << "exception caught while trying to open root"
    00307               << " file for appending: " << Exception.what() << std::endl
    00308               << "  -> file probably corrupt." << endmsg;
    00309         return StatusCode::FAILURE;
    00310       } catch (...) {
    00311         m_log << MSG::ERROR << "Problems opening output file  \""
    00312               << tmpfn.c_str()
    00313               << "\" for append: probably corrupt" << endmsg;
    00314         return StatusCode::FAILURE;
    00315       }
    00316
    00317       outputfile->SetCompressionLevel( inputfile->GetCompressionLevel() );
    00318
    00319       MergeRootFile(outputfile, inputfile);
    00320
    00321       outputfile->Write();
    00322       outputfile->Close();
    00323       inputfile->Close();
    00324
    00325       if (m_log.level() <= MSG::DEBUG)
    00326         m_log << MSG::DEBUG << "Trying to remove temporary file \"" << tmpfn
    00327               << "\""<<endmsg;
    00328
    00329       std::remove(tmpfn.c_str());
    00330     }
    00331     delete itr->second.first;
    00332   }
    00333
    00334   m_sharedFiles.clear();
    00335   m_fileStreams.clear();
    00336   m_files.clear();
    00337   m_uids.clear();
    00338   m_ids.clear();
    00339   m_tobjs.clear();
    00340
    00341   return Service::finalize();
    00342 }
    00343
    00344 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00345
    00346 bool
    00347 THistSvc::browseTDir(TDirectory *dir) const {
    00348
    00349   if (dir == 0) {
    00350     std::cerr << "TDirectory == 0" << std::endl;
    00351     return false;
    00352   }
    00353
    00354   GlobalDirectoryRestore restore;
    00355
    00356   dir->cd();
    00357
    00358
    00359   cout << "-> " << dir->GetPath() << "  "
    00360        << dir->GetListOfKeys()->GetSize() << endl;
    00361
    00362   //  TIter nextkey(dir->GetListOfKeys());
    00363   TIter nextkey(dir->GetList());
    00364   while (TKey *key = (TKey*)nextkey()) {
    00365
    00366     TObject *obj = key->ReadObj();
    00367     if (obj == 0) { cout << key->GetName() << " obj==0"<< endl; continue; }
    00368     //    if (obj->IsA()->InheritsFrom("TDirectory")) {
    00369       cout << "  Key: " << key->GetName() << "   "
    00370            << " tit: " << obj->GetTitle() << "   "
    00371            << " (" << key->GetClassName() << ")" << endl;
    00372       //    }
    00373   }
    00374
    00375   nextkey = dir->GetListOfKeys();
    00376   while (TKey *key = (TKey*)nextkey()) {
    00377
    00378     TObject *obj = key->ReadObj();
    00379     if (obj == 0) { cout << key->GetName() << " obj==0"<< endl; continue; }
    00380     if (obj->IsA()->InheritsFrom("TDirectory")) {
    00381       TDirectory *tt = dynamic_cast<TDirectory*>(obj);
    00382       browseTDir(tt);
    00383     }
    00384   }
    00385
    00386   return true;
    00387 }
    00388
    00389
    00390 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00391
    00392 StatusCode
    00393 THistSvc::getTHists(TDirectory *td, TList & tl, bool rcs) const {
    00394   GlobalDirectoryRestore restore;
    00395
    00396   gErrorIgnoreLevel = kBreak;
    00397
    00398   if (!td->cd()) {
    00399     m_log << MSG::ERROR << "getTHists: No such TDirectory \"" << td->GetPath()
    00400           << "\"" << endmsg;
    00401     return StatusCode::FAILURE;
    00402   }
    00403
    00404   if (m_log.level() <= MSG::DEBUG)
    00405     m_log << MSG::DEBUG << "getTHists: \"" << td->GetPath() << "\": found "
    00406           << td->GetListOfKeys()->GetSize() << " keys" << endmsg;
    00407
    00408   TIter nextkey(td->GetListOfKeys());
    00409   while (TKey *key = (TKey*)nextkey()) {
    00410     if (m_log.level() <= MSG::DEBUG)
    00411       m_log << MSG::DEBUG << "  key: " << key->GetName();
    00412     TObject *obj = key->ReadObj();
    00413     if (obj != 0 && obj->IsA()->InheritsFrom("TDirectory")) {
    00414       if (m_log.level() <= MSG::DEBUG)
    00415         m_log << " (" << obj->IsA()->GetName() << ")";
    00416     } else if (obj != 0 && obj->IsA()->InheritsFrom("TH1")) {
    00417       if (m_log.level() <= MSG::DEBUG)
    00418         m_log << " (" << obj->IsA()->GetName() << ")";
    00419       tl.Add(obj);
    00420     } else if (obj != 0) {
    00421       if (m_log.level() <= MSG::DEBUG)
    00422         m_log << " [" << obj->IsA()->GetName() << "]";
    00423     }
    00424     if (m_log.level() <= MSG::DEBUG)
    00425       m_log << endmsg;
    00426   }
    00427
    00428   // operate recursively
    00429   if (rcs) {
    00430     nextkey = td->GetListOfKeys();
    00431     while (TKey *key = (TKey*)nextkey()) {
    00432       TObject *obj = key->ReadObj();
    00433       if (obj != 0 && obj->IsA()->InheritsFrom("TDirectory")) {
    00434           TDirectory *tt = dynamic_cast<TDirectory*>(obj);
    00435           getTHists(tt, tl, rcs);
    00436       }
    00437     }
    00438   }
    00439
    00440   return StatusCode::SUCCESS;
    00441
    00442
    00443 }
    00444
    00445 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00446
    00447 StatusCode
    00448 THistSvc::getTHists(const std::string& dir, TList & tl, bool rcs) const {
    00449
    00450   GlobalDirectoryRestore restore;
    00451
    00452   gErrorIgnoreLevel = kBreak;
    00453
    00454   StatusCode sc;
    00455
    00456   std::string stream,rem,r2;
    00457   parseString(dir,stream,rem);
    00458
    00459   map< string,pair<TFile*,Mode> >::const_iterator itr = m_files.find(stream);
    00460   if (itr != m_files.end()) {
    00461     r2 = itr->second.first->GetName();
    00462     r2 += ":/";
    00463     r2 += rem;
    00464
    00465     if (m_log.level() <= MSG::DEBUG)
    00466       m_log << MSG::DEBUG << "getTHists: \"" << dir
    00467             << "\" looks like a stream name."  << " associated TFile: \""
    00468             << itr->second.first->GetName() << "\"" << endmsg;
    00469
    00470     if (gDirectory->cd(r2.c_str())) {
    00471       m_curstream = stream;
    00472       sc = getTHists(gDirectory,tl,rcs);
    00473       m_curstream = "";
    00474       return sc;
    00475     } else {
    00476       if (m_log.level() <= MSG::DEBUG)
    00477         m_log << MSG::DEBUG << "getTHists: no such TDirectory \""
    00478               << r2 << "\"" << endmsg;
    00479     }
    00480
    00481   } else {
    00482     if (m_log.level() <= MSG::DEBUG)
    00483       m_log << MSG::DEBUG << "getTHists: stream \"" << stream << "\" not found"
    00484             << endmsg;
    00485   }
    00486
    00487   if (!gDirectory->cd(dir.c_str())) {
    00488     m_log << MSG::ERROR << "getTHists: No such TDirectory/stream \"" << dir
    00489           << "\"" << endmsg;
    00490     sc = StatusCode::FAILURE;
    00491   } else {
    00492     sc = getTHists(gDirectory,tl,rcs);
    00493   }
    00494
    00495   return sc;
    00496
    00497 }
    00498 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00499
    00500 StatusCode
    00501 THistSvc::getTTrees(TDirectory *td, TList & tl, bool rcs) const {
    00502   GlobalDirectoryRestore restore;
    00503
    00504   gErrorIgnoreLevel = kBreak;
    00505
    00506   if (!td->cd()) {
    00507     m_log << MSG::ERROR << "getTTrees: No such TDirectory \""
    00508           << td->GetPath() << "\"" << endmsg;
    00509     return StatusCode::FAILURE;
    00510   }
    00511
    00512   if (m_log.level() <= MSG::DEBUG)
    00513     m_log << MSG::DEBUG << "getTHists: \"" << td->GetPath() << "\": found "
    00514           << td->GetListOfKeys()->GetSize() << " keys" << endmsg;
    00515
    00516   TIter nextkey(td->GetListOfKeys());
    00517   while (TKey *key = (TKey*)nextkey()) {
    00518     if (m_log.level() <= MSG::DEBUG)
    00519       m_log << MSG::DEBUG << "  key: " << key->GetName();
    00520     TObject *obj = key->ReadObj();
    00521     if (obj != 0 && obj->IsA()->InheritsFrom("TDirectory")) {
    00522       if (m_log.level() <= MSG::DEBUG)
    00523         m_log << " (" << obj->IsA()->GetName() << ")";
    00524     } else if (obj != 0 && obj->IsA()->InheritsFrom("TTree")) {
    00525       if (m_log.level() <= MSG::DEBUG)
    00526         m_log << " (" << obj->IsA()->GetName() << ")";
    00527       tl.Add(obj);
    00528     } else if (obj != 0) {
    00529       if (m_log.level() <= MSG::DEBUG)
    00530         m_log << " [" << obj->IsA()->GetName() << "]";
    00531     }
    00532     m_log << endmsg;
    00533   }
    00534
    00535   // operate recursively
    00536   if (rcs) {
    00537     nextkey = td->GetListOfKeys();
    00538     while (TKey *key = (TKey*)nextkey()) {
    00539       TObject *obj = key->ReadObj();
    00540       if (obj != 0 && obj->IsA()->InheritsFrom("TDirectory")) {
    00541           TDirectory *tt = dynamic_cast<TDirectory*>(obj);
    00542           getTTrees(tt, tl, rcs);
    00543       }
    00544     }
    00545   }
    00546
    00547   return StatusCode::SUCCESS;
    00548
    00549 }
    00550
    00551 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00552
    00553 StatusCode
    00554 THistSvc::getTTrees(const std::string& dir, TList & tl, bool rcs) const {
    00555   GlobalDirectoryRestore restore;
    00556
    00557   gErrorIgnoreLevel = kBreak;
    00558
    00559   StatusCode sc;
    00560
    00561   std::string stream,rem,r2;
    00562   parseString(dir,stream,rem);
    00563
    00564   map< string,pair<TFile*,Mode> >::const_iterator itr = m_files.find(stream);
    00565   if (itr != m_files.end()) {
    00566     r2 = itr->second.first->GetName();
    00567     r2 += ":/";
    00568     r2 += rem;
    00569
    00570     if (m_log.level() <= MSG::DEBUG)
    00571       m_log << MSG::DEBUG << "getTTrees: \"" << dir
    00572             << "\" looks like a stream name."  << " associated TFile: \""
    00573             << itr->second.first->GetName() << "\"" << endmsg;
    00574
    00575     if (gDirectory->cd(r2.c_str())) {
    00576       return getTTrees(gDirectory,tl,rcs);
    00577     } else {
    00578       if (m_log.level() <= MSG::DEBUG)
    00579         m_log << MSG::DEBUG << "getTTrees: no such TDirectory \""
    00580               << r2 << "\"" << endmsg;
    00581     }
    00582
    00583   } else {
    00584     if (m_log.level() <= MSG::DEBUG)
    00585       m_log << MSG::DEBUG << "getTTrees: stream \"" << stream << "\" not found"
    00586             << endmsg;
    00587   }
    00588
    00589   if (!gDirectory->cd(dir.c_str())) {
    00590     m_log << MSG::ERROR << "getTTrees: No such TDirectory/stream \"" << dir
    00591           << "\"" << endmsg;
    00592     sc = StatusCode::FAILURE;
    00593   } else {
    00594     sc = getTTrees(gDirectory,tl,rcs);
    00595   }
    00596
    00597   return sc;
    00598
    00599
    00600 }
    00601
    00602
    00603 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00604
    00605 StatusCode
    00606 THistSvc::getTHists(TDirectory *td, TList & tl, bool rcs, bool reg) {
    00607
    00608   GlobalDirectoryRestore restore;
    00609
    00610   gErrorIgnoreLevel = kBreak;
    00611
    00612   if (!td->cd()) {
    00613     m_log << MSG::ERROR << "getTHists: No such TDirectory \"" << td->GetPath()
    00614           << "\"" << endmsg;
    00615     return StatusCode::FAILURE;
    00616   }
    00617
    00618   if (m_log.level() <= MSG::DEBUG)
    00619     m_log << MSG::DEBUG << "getTHists: \"" << td->GetPath() << "\": found "
    00620           << td->GetListOfKeys()->GetSize() << " keys" << endmsg;
    00621
    00622   TIter nextkey(td->GetListOfKeys());
    00623   while (TKey *key = (TKey*)nextkey()) {
    00624     if (m_log.level() <= MSG::DEBUG)
    00625       m_log << MSG::DEBUG << "  key: " << key->GetName();
    00626     TObject *obj = key->ReadObj();
    00627     if (obj != 0 && obj->IsA()->InheritsFrom("TDirectory")) {
    00628       if (m_log.level() <= MSG::DEBUG)
    00629         m_log << " (" << obj->IsA()->GetName() << ")";
    00630     } else if (obj != 0 && obj->IsA()->InheritsFrom("TH1")) {
    00631       if (m_log.level() <= MSG::DEBUG)
    00632         m_log << " (" << obj->IsA()->GetName() << ")";
    00633       tl.Add(obj);
    00634       if (reg && m_curstream != "") {
    00635         string dir = td->GetPath();
    00636         string fil = td->GetFile()->GetName();
    00637         dir.erase(0,fil.length()+1);
    00638         string id = "/" + m_curstream;
    00639         if ( dir == "/" ) {
    00640           id = id + "/" + key->GetName();
    00641         } else {
    00642           id = id + dir + "/" + key->GetName();
    00643         }
    00644         if (!exists(id)) {
    00645           if (m_log.level() <= MSG::DEBUG)
    00646             m_log << "  reg as \"" << id << "\"";
    00647           regHist(id).ignore();
    00648         } else {
    00649           if (m_log.level() <= MSG::DEBUG)
    00650             m_log << "  already registered";
    00651         }
    00652       }
    00653     } else if (obj != 0) {
    00654       if (m_log.level() <= MSG::DEBUG)
    00655         m_log << " [" << obj->IsA()->GetName() << "]";
    00656     }
    00657     if (m_log.level() <= MSG::DEBUG)
    00658       m_log << endmsg;
    00659   }
    00660
    00661   // operate recursively
    00662   if (rcs) {
    00663     nextkey = td->GetListOfKeys();
    00664     while (TKey *key = (TKey*)nextkey()) {
    00665       TObject *obj = key->ReadObj();
    00666       if (obj != 0 && obj->IsA()->InheritsFrom("TDirectory")) {
    00667           TDirectory *tt = dynamic_cast<TDirectory*>(obj);
    00668           getTHists(tt, tl, rcs, reg);
    00669       }
    00670     }
    00671   }
    00672
    00673   return StatusCode::SUCCESS;
    00674
    00675 }
    00676
    00677 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00678
    00679 StatusCode
    00680 THistSvc::getTHists(const std::string& dir, TList & tl, bool rcs, bool reg) {
    00681
    00682   GlobalDirectoryRestore restore;
    00683
    00684   gErrorIgnoreLevel = kBreak;
    00685
    00686   StatusCode sc;
    00687
    00688   std::string stream,rem,r2;
    00689   parseString(dir,stream,rem);
    00690
    00691   map< string,pair<TFile*,Mode> >::const_iterator itr = m_files.find(stream);
    00692   if (itr != m_files.end()) {
    00693     r2 = itr->second.first->GetName();
    00694     r2 += ":/";
    00695     r2 += rem;
    00696
    00697     if (m_log.level() <= MSG::DEBUG)
    00698       m_log << MSG::DEBUG << "getTHists: \"" << dir
    00699             << "\" looks like a stream name."  << " associated TFile: \""
    00700             << itr->second.first->GetName() << "\"" << endmsg;
    00701
    00702     if (gDirectory->cd(r2.c_str())) {
    00703       m_curstream = stream;
    00704       sc = getTHists(gDirectory,tl,rcs,reg);
    00705       m_curstream = "";
    00706       return sc;
    00707     } else {
    00708       if (m_log.level() <= MSG::DEBUG)
    00709         m_log << MSG::DEBUG << "getTHists: no such TDirectory \""
    00710               << r2 << "\"" << endmsg;
    00711     }
    00712
    00713   } else {
    00714     if (m_log.level() <= MSG::DEBUG)
    00715       m_log << MSG::DEBUG << "getTHists: stream \"" << stream << "\" not found"
    00716             << endmsg;
    00717   }
    00718
    00719   if (!gDirectory->cd(dir.c_str())) {
    00720     m_log << MSG::ERROR << "getTHists: No such TDirectory/stream \"" << dir
    00721           << "\"" << endmsg;
    00722     sc = StatusCode::FAILURE;
    00723   } else {
    00724     if (reg) {
    00725       m_log << MSG::WARNING << "Unable to register histograms automatically "
    00726             << "without a valid stream name" << endmsg;
    00727       reg = false;
    00728     }
    00729     sc = getTHists(gDirectory,tl,rcs,reg);
    00730   }
    00731
    00732   return sc;
    00733
    00734 }
    00735 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00736
    00737 StatusCode
    00738 THistSvc::getTTrees(TDirectory *td, TList & tl, bool rcs, bool reg) {
    00739
    00740   GlobalDirectoryRestore restore;
    00741
    00742   gErrorIgnoreLevel = kBreak;
    00743
    00744   if (!td->cd()) {
    00745     m_log << MSG::ERROR << "getTTrees: No such TDirectory \""
    00746           << td->GetPath() << "\"" << endmsg;
    00747     return StatusCode::FAILURE;
    00748   }
    00749
    00750   if (m_log.level() <= MSG::DEBUG)
    00751     m_log << MSG::DEBUG << "getTHists: \"" << td->GetPath() << "\": found "
    00752           << td->GetListOfKeys()->GetSize() << " keys" << endmsg;
    00753
    00754   TIter nextkey(td->GetListOfKeys());
    00755   while (TKey *key = (TKey*)nextkey()) {
    00756     if (m_log.level() <= MSG::DEBUG)
    00757       m_log << MSG::DEBUG << "  key: " << key->GetName();
    00758     TObject *obj = key->ReadObj();
    00759     if (obj != 0 && obj->IsA()->InheritsFrom("TDirectory")) {
    00760       if (m_log.level() <= MSG::DEBUG)
    00761         m_log << " (" << obj->IsA()->GetName() << ")";
    00762     } else if (obj != 0 && obj->IsA()->InheritsFrom("TTree")) {
    00763       if (m_log.level() <= MSG::DEBUG)
    00764         m_log << " (" << obj->IsA()->GetName() << ")";
    00765       tl.Add(obj);
    00766       if (reg && m_curstream != "") {
    00767         string dir = td->GetPath();
    00768         string fil = td->GetFile()->GetName();
    00769         dir.erase(0,fil.length()+1);
    00770         string id = "/" + m_curstream;
    00771         if ( dir == "/" ) {
    00772           id = id + "/" + key->GetName();
    00773         } else {
    00774           id = id + dir + "/" + key->GetName();
    00775         }
    00776         if (!exists(id)) {
    00777           if (m_log.level() <= MSG::DEBUG)
    00778             m_log << "  reg as \"" << id << "\"";
    00779           regHist(id).ignore();
    00780         } else {
    00781           if (m_log.level() <= MSG::DEBUG)
    00782             m_log << "  already registered";
    00783         }
    00784       }
    00785     } else if (obj != 0) {
    00786       if (m_log.level() <= MSG::DEBUG)
    00787         m_log << " [" << obj->IsA()->GetName() << "]";
    00788     }
    00789     if (m_log.level() <= MSG::DEBUG)
    00790       m_log << endmsg;
    00791   }
    00792
    00793   // operate recursively
    00794   if (rcs) {
    00795     nextkey = td->GetListOfKeys();
    00796     while (TKey *key = (TKey*)nextkey()) {
    00797       TObject *obj = key->ReadObj();
    00798       if (obj != 0 && obj->IsA()->InheritsFrom("TDirectory")) {
    00799           TDirectory *tt = dynamic_cast<TDirectory*>(obj);
    00800           getTTrees(tt, tl, rcs, reg);
    00801       }
    00802     }
    00803   }
    00804
    00805   return StatusCode::SUCCESS;
    00806
    00807 }
    00808
    00809 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00810
    00811 StatusCode
    00812 THistSvc::getTTrees(const std::string& dir, TList & tl, bool rcs, bool reg) {
    00813
    00814   GlobalDirectoryRestore restore;
    00815
    00816   gErrorIgnoreLevel = kBreak;
    00817
    00818   StatusCode sc;
    00819
    00820   std::string stream,rem,r2;
    00821   parseString(dir,stream,rem);
    00822
    00823   map< string,pair<TFile*,Mode> >::const_iterator itr = m_files.find(stream);
    00824   if (itr != m_files.end()) {
    00825     r2 = itr->second.first->GetName();
    00826     r2 += ":/";
    00827     r2 += rem;
    00828
    00829     if (m_log.level() <= MSG::DEBUG)
    00830       m_log << MSG::DEBUG << "getTTrees: \"" << dir
    00831             << "\" looks like a stream name."  << " associated TFile: \""
    00832             << itr->second.first->GetName() << "\"" << endmsg;
    00833
    00834     if (gDirectory->cd(r2.c_str())) {
    00835       return getTTrees(gDirectory,tl,rcs,reg);
    00836     } else {
    00837       if (m_log.level() <= MSG::DEBUG)
    00838         m_log << MSG::DEBUG << "getTTrees: no such TDirectory \""
    00839               << r2 << "\"" << endmsg;
    00840     }
    00841
    00842   } else {
    00843     if (m_log.level() <= MSG::DEBUG)
    00844       m_log << MSG::DEBUG << "getTTrees: stream \"" << stream << "\" not found"
    00845             << endmsg;
    00846   }
    00847
    00848   if (!gDirectory->cd(dir.c_str())) {
    00849     m_log << MSG::ERROR << "getTTrees: No such TDirectory/stream \"" << dir
    00850           << "\"" << endmsg;
    00851     sc = StatusCode::FAILURE;
    00852   } else {
    00853     sc = getTTrees(gDirectory,tl,rcs,reg);
    00854   }
    00855
    00856   return sc;
    00857
    00858 }
    00859
    00860 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00861
    00862 StatusCode
    00863 THistSvc::deReg(TObject* obj) {
    00864
    00865   objMap::iterator itr = m_tobjs.find(obj);
    00866   if (itr != m_tobjs.end()) {
    00867     THistID hid = itr->second;
    00868
    00869     uidMap::iterator itr2 = m_uids.find(hid.id);
    00870     if (itr2 == m_uids.end()) {
    00871       m_log << MSG::ERROR << "Problems deregistering TObject \""
    00872             << obj->GetName()
    00873             << "\" with id \"" << hid.id << "\"" << endmsg;
    00874       return StatusCode::FAILURE;
    00875     }
    00876
    00877     std::string id,root,rem;
    00878     parseString(hid.id, root, rem);
    00879
    00880     idMap::iterator itr3;
    00881     bool found(false);
    00882
    00883     std::pair<idMap::iterator, idMap::iterator> mitr = m_ids.equal_range(rem);
    00884     if (mitr.first == mitr.second) {
    00885       m_log << MSG::ERROR << "Problems deregistering TObject \""
    00886             << obj->GetName()
    00887             << "\" with id \"" << hid.id << "\"" << endmsg;
    00888       return StatusCode::FAILURE;
    00889     } else {
    00890       for (itr3 = mitr.first; itr3 != mitr.second; ++itr3) {
    00891         if (itr3->second.obj == obj) {
    00892           found = true;
    00893           break;
    00894         }
    00895       }
    00896       if (!found) {
    00897         m_log << MSG::ERROR << "Problems deregistering TObject \""
    00898               << obj->GetName()
    00899               << "\" with id \"" << hid.id << "\"" << endmsg;
    00900       }
    00901     }
    00902
    00903     m_tobjs.erase(itr);
    00904     m_uids.erase(itr2);
    00905     m_ids.erase(itr3);
    00906
    00907     return StatusCode::SUCCESS;
    00908
    00909   } else {
    00910     m_log << MSG::ERROR << "Cannot unregister TObject \"" << obj->GetName()
    00911           << "\": not known to THistSvc" << endmsg;
    00912     return StatusCode::FAILURE;
    00913   }
    00914
    00915 }
    00916
    00917
    00918 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00919
    00920 StatusCode
    00921 THistSvc::deReg(const std::string& id) {
    00922
    00923   uidMap::iterator itr = m_uids.find(id);
    00924   if (itr == m_uids.end()) {
    00925     m_log << MSG::ERROR << "Problems deregistering id \""
    00926           << id << "\"" << endmsg;
    00927     return StatusCode::FAILURE;
    00928   }
    00929
    00930   TObject* obj = itr->second.obj;
    00931
    00932   return deReg(obj);
    00933 }
    00934
    00935 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00936
    00937 StatusCode
    00938 THistSvc::regHist(const std::string& id) {
    00939
    00940   TH1 *hist(0);
    00941
    00942   return regHist_i(hist, id);
    00943 }
    00944
    00945 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00946
    00947 StatusCode
    00948 THistSvc::regHist(const std::string& id, TH1* hist) {
    00949   return regHist_i(hist, id);
    00950 }
    00951
    00952 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00953
    00954 StatusCode
    00955 THistSvc::regHist(const std::string& id, TH2* hist) {
    00956   return regHist_i(hist, id);
    00957 }
    00958
    00959 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00960
    00961 StatusCode
    00962 THistSvc::regHist(const std::string& id, TH3* hist) {
    00963   return regHist_i(hist, id);
    00964 }
    00965
    00966 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00967
    00968 StatusCode
    00969 THistSvc::regTree(const std::string& id) {
    00970   TTree *hist(0);
    00971   return regHist_i(hist, id);
    00972 }
    00973
    00974 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00975
    00976 StatusCode
    00977 THistSvc::regTree(const std::string& id, TTree* hist) {
    00978   StatusCode sc = regHist_i(hist, id);
    00979   if (hist != 0 && sc.isSuccess()) {
    00980     if (m_autoSave != 0)
    00981       hist->SetAutoSave(m_autoSave);
    00982     hist->SetAutoFlush(m_autoFlush);
    00983   }
    00984   return sc;
    00985 }
    00986
    00987 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00988
    00989 StatusCode
    00990 THistSvc::regGraph(const std::string& id) {
    00991   TGraph *hist(0);
    00992   return regHist_i(hist, id);
    00993 }
    00994
    00995 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    00996
    00997 StatusCode
    00998 THistSvc::regGraph(const std::string& id, TGraph* hist) {
    00999   if ( strcmp(hist->GetName(),"Graph") == 0 ) {
    01000
    01001     std::string id2(id);
    01002     string::size_type i = id2.rfind("/");
    01003     if (i != string::npos) {
    01004       id2.erase(0,i+1);
    01005     }
    01006
    01007     m_log << MSG::INFO << "setting name of TGraph id: \"" << id << "\" to \""
    01008           << id2 << "\" since it is unset" << endmsg;
    01009     hist->SetName(id2.c_str());
    01010   }
    01011
    01012   return regHist_i(hist, id);
    01013 }
    01014
    01015 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    01016
    01017 StatusCode
    01018 THistSvc::getHist(const std::string& id, TH1*& hist) const {
    01019   return getHist_i(id, hist);
    01020 }
    01021
    01022 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    01023
    01024 StatusCode
    01025 THistSvc::getHist(const std::string& id, TH2*& hist) const {
    01026   return getHist_i(id, hist);
    01027 }
    01028
    01029 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    01030
    01031 StatusCode
    01032 THistSvc::getHist(const std::string& id, TH3*& hist) const {
    01033   return getHist_i(id, hist);
    01034 }
    01035
    01036 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    01037
    01038 std::vector<std::string>
    01039 THistSvc::getHists() const {
    01040
    01041   std::vector<std::string> names;
    01042   names.reserve(m_uids.size());
    01043
    01044   uidMap::const_iterator itr;
    01045   for (itr = m_uids.begin(); itr != m_uids.end(); ++itr) {
    01046     THistID tid = itr->second;
    01047
    01048     if (tid.obj->IsA()->InheritsFrom("TH1")) {
    01049       names.push_back(itr->first);
    01050     }
    01051
    01052   }
    01053
    01054   return names;
    01055
    01056 }
    01057 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    01058
    01059 StatusCode
    01060 THistSvc::getTree(const std::string& id, TTree*& hist) const {
    01061   return getHist_i(id, hist);
    01062 }
    01063
    01064 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    01065
    01066 std::vector<std::string>
    01067 THistSvc::getTrees() const {
    01068
    01069   std::vector<std::string> names;
    01070   names.reserve(m_uids.size());
    01071
    01072   uidMap::const_iterator itr;
    01073   for (itr = m_uids.begin(); itr != m_uids.end(); ++itr) {
    01074     THistID tid = itr->second;
    01075
    01076     if (tid.obj->IsA()->InheritsFrom("TTree")) {
    01077       names.push_back(itr->first);
    01078     }
    01079
    01080   }
    01081
    01082   return names;
    01083
    01084 }
    01085 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    01086
    01087 StatusCode
    01088 THistSvc::getGraph(const std::string& id, TGraph*& hist) const {
    01089   return getHist_i(id, hist);
    01090 }
    01091
    01092 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    01093
    01094 std::vector<std::string>
    01095 THistSvc::getGraphs() const {
    01096
    01097   std::vector<std::string> names;
    01098   names.reserve(m_uids.size());
    01099
    01100   uidMap::const_iterator itr;
    01101   for (itr = m_uids.begin(); itr != m_uids.end(); ++itr) {
    01102     THistID tid = itr->second;
    01103
    01104     if (tid.obj->IsA()->InheritsFrom("TGraph")) {
    01105       names.push_back(itr->first);
    01106     }
    01107
    01108   }
    01109
    01110   return names;
    01111
    01112 }
    01113 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    01114
    01115 StatusCode
    01116 THistSvc::readHist(const std::string& id, TH1*& hist) const {
    01117   return readHist_i(id, hist);
    01118 }
    01119
    01120 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    01121
    01122 StatusCode
    01123 THistSvc::readHist(const std::string& id, TH2*& hist) const {
    01124   return readHist_i(id, hist);
    01125 }
    01126
    01127 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    01128
    01129 StatusCode
    01130 THistSvc::readHist(const std::string& id, TH3*& hist) const {
    01131   return readHist_i(id, hist);
    01132 }
    01133
    01134 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    01135
    01136 StatusCode
    01137 THistSvc::readTree(const std::string& id, TTree*& hist) const {
    01138   return readHist_i(id, hist);
    01139 }
    01140
    01141 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    01142
    01143 bool
    01144 THistSvc::findStream(const string& id, string& stream, string& rem,
    01145                    TFile*& file) const {
    01146
    01147   string::size_type pos = id.find("/");
    01148
    01149   if (pos == string::npos) {
    01150     stream = "temp";
    01151     rem = id;
    01152   } else if (pos != 0) {
    01153     stream = "temp";
    01154     rem = id;
    01155   } else {
    01156
    01157     string::size_type pos2 = id.find("/",pos+1);
    01158
    01159     if (pos2 == string::npos) {
    01160       m_log << MSG::ERROR << "badly formed Hist/Tree id: \"" << id << "\""
    01161             << endmsg;
    01162       return false;
    01163     }
    01164
    01165     parseString(id,stream,rem);
    01166
    01167   }
    01168
    01169   if (stream == "temp") {
    01170     file = 0;
    01171     return true;
    01172   }
    01173
    01174   map< string,pair<TFile*,Mode> >::const_iterator itr = m_files.find(stream);
    01175   if (itr != m_files.end()) {
    01176     file = itr->second.first;
    01177   } else {
    01178     file = 0;
    01179     m_log << MSG::WARNING << "no stream \"" << stream
    01180           << "\" associated with id: \"" << id << "\""
    01181           << endmsg;
    01182   }
    01183
    01184   return true;
    01185
    01186 }
    01187
    01188 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    01189
    01190 void
    01191 THistSvc::parseString(const string& id, string& root, string& rem) const {
    01192   string::size_type pos = id.find("/");
    01193
    01194   if (pos == string::npos) {
    01195     root = "";
    01196     rem = id;
    01197     return;
    01198   }
    01199
    01200   if (pos == 0) {
    01201     parseString(id.substr(1,id.length()),root,rem);
    01202   } else {
    01203     root = id.substr(0,pos);
    01204     rem = id.substr(pos+1,id.length());
    01205   }
    01206
    01207 }
    01208
    01209 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    01210
    01211 void
    01212 THistSvc::setupCompressionLevel( Property& /* cl */ )
    01213 {
    01214
    01215   m_log << MSG::WARNING << "\"CompressionLevel\" Property has been deprecated. "
    01216         << "Set it via the \"CL=\" parameter in the \"Output\" Property"
    01217         << endmsg;
    01218
    01219 }
    01220
    01221
    01222 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    01223
    01224 void
    01225 THistSvc::setupInputFile( Property& /*m_inputfile*/ )
    01226 {
    01227   StatusCode sc = StatusCode::SUCCESS;
    01228
    01229   typedef std::vector<std::string> Strings_t;
    01230   for ( Strings_t::const_iterator
    01231           itr  = m_inputfile.value().begin(),
    01232           iEnd = m_inputfile.value().end();
    01233         itr != iEnd;
    01234         ++itr ) {
    01235     if ( m_alreadyConnectedInFiles.end() ==
    01236          m_alreadyConnectedInFiles.find( *itr ) ) {
    01237       if ( connect(*itr).isFailure() ) {
    01238         sc = StatusCode::FAILURE;
    01239       } else {
    01240         m_alreadyConnectedInFiles.insert( *itr );
    01241       }
    01242     }
    01243   }
    01244
    01245   if ( !sc.isSuccess() ) {
    01246     throw GaudiException( "Problem connecting inputfile !!", name(),
    01247                           StatusCode::FAILURE );
    01248   }
    01249   return;
    01250 }
    01251
    01252 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    01253
    01254 void
    01255 THistSvc::setupOutputFile( Property& /*m_outputfile*/ )
    01256 {
    01257   StatusCode sc = StatusCode::SUCCESS;
    01258
    01259   typedef std::vector<std::string> Strings_t;
    01260   for ( Strings_t::const_iterator
    01261           itr  = m_outputfile.value().begin(),
    01262           iEnd = m_outputfile.value().end();
    01263         itr != iEnd;
    01264         ++itr ) {
    01265     if ( m_alreadyConnectedOutFiles.end() ==
    01266          m_alreadyConnectedOutFiles.find( *itr ) ) {
    01267       if ( connect(*itr).isFailure() ) {
    01268         sc = StatusCode::FAILURE;
    01269       } else {
    01270         m_alreadyConnectedOutFiles.insert( *itr );
    01271       }
    01272     }
    01273   }
    01274
    01275   if ( !sc.isSuccess() ) {
    01276     throw GaudiException( "Problem connecting outputfile !!", name(),
    01277                           StatusCode::FAILURE );
    01278   }
    01279   return;
    01280 }
    01281
    01282 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    01283
    01284 void
    01285 THistSvc::updateFiles() {
    01286
    01287   // If TTrees grow beyond TTree::fgMaxFileSize, a new file is
    01288   // automatically created by root, and the old one closed. We
    01289   // need to migrate all the UIDs over to show the correct file
    01290   // pointer. This is ugly.
    01291
    01292   uidMap::iterator uitr, uitr2;
    01293   for (uitr=m_uids.begin(); uitr != m_uids.end(); ++uitr) {
    01294     TObject* to = uitr->second.obj;
    01295     TFile* oldFile = uitr->second.file;
    01296     if (to->IsA()->InheritsFrom("TTree")) {
    01297       TTree* tr = dynamic_cast<TTree*>(to);
    01298       TFile* newFile = tr->GetCurrentFile();
    01299
    01300       if (oldFile != newFile) {
    01301         std::string newFileName = newFile->GetName();
    01302         std::string oldFileName(""), streamName, rem;
    01303         TFile* dummy;
    01304         findStream(uitr->second.id, streamName, rem, dummy);
    01305
    01306         map<string, pair<TFile*,Mode> >::iterator itr;
    01307         for (itr=m_files.begin(); itr!= m_files.end(); ++itr) {
    01308           if (itr->second.first == oldFile) {
    01309             itr->second.first = newFile;
    01310
    01311           }
    01312         }
    01313
    01314         uitr2 = uitr;
    01315         for (; uitr2 != m_uids.end(); ++uitr2) {
    01316           if (uitr2->second.file == oldFile) {
    01317             uitr2->second.file = newFile;
    01318           }
    01319         }
    01320
    01321         streamMap::iterator sitr;
    01322         for (sitr = m_fileStreams.begin(); sitr!=m_fileStreams.end(); ++sitr) {
    01323           if (sitr->second == streamName) {
    01324             oldFileName = sitr->first;
    01325             break;
    01326           }
    01327         }
    01328
    01329
    01330 #ifndef NDEBUG
    01331       if (m_log.level() <= MSG::DEBUG)
    01332         m_log << MSG::DEBUG << "migrating uid: " << uitr->second.id
    01333               << "   stream: " << streamName
    01334               << "   oldFile: " << oldFileName
    01335               << "   newFile: " << newFileName
    01336               << endmsg;
    01337 #endif
    01338
    01339
    01340         if (oldFileName != "") {
    01341           while ( (sitr=m_fileStreams.find(oldFileName)) != m_fileStreams.end() ) {
    01342
    01343 #ifndef NDEBUG
    01344             if (m_log.level() <= MSG::DEBUG)
    01345               m_log << MSG::DEBUG << "changing filename \"" << oldFileName
    01346                     << "\" to \"" << newFileName << "\" for stream \""
    01347                     << sitr->second << "\"" << endmsg;
    01348 #endif
    01349             m_fileStreams.erase(sitr);
    01350             m_fileStreams.insert( make_pair<std::string,std::string>(newFileName,streamName) );
    01351           }
    01352
    01353
    01354         } else {
    01355           m_log << MSG::ERROR
    01356                 << "Problems updating fileStreams with new file name" << endmsg;
    01357         }
    01358
    01359       }
    01360
    01361     }
    01362   }
    01363
    01364 }
    01365
    01366 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    01367
    01368 StatusCode
    01369 THistSvc::write() {
    01370
    01371   updateFiles();
    01372
    01373   map<string, pair<TFile*,Mode> >::const_iterator itr;
    01374   for (itr=m_files.begin(); itr!= m_files.end(); ++itr) {
    01375     if (itr->second.second == WRITE || itr->second.second == UPDATE
    01376         ||itr->second.second==SHARE) {
    01377       itr->second.first->Write("",TObject::kOverwrite);
    01378     } else if (itr->second.second == APPEND) {
    01379       itr->second.first->Write("");
    01380     }
    01381   }
    01382
    01383
    01384   if (m_log.level() <= MSG::DEBUG)
    01385     m_log << MSG::DEBUG << "THistSvc::write()::List of Files connected in ROOT "
    01386           << endmsg;
    01387
    01388   TSeqCollection *filelist=gROOT->GetListOfFiles();
    01389   for (int ii=0; ii<filelist->GetEntries(); ii++) {
    01390     if (m_log.level() <= MSG::DEBUG)
    01391       m_log << MSG::DEBUG
    01392             << "THistSvc::write()::List of Files connected in ROOT: \""
    01393             << filelist->At(ii)->GetName()<<"\""<<endmsg;
    01394   }
    01395
    01396   return StatusCode::SUCCESS;
    01397
    01398 }
    01399
    01400 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    01401
    01402 StatusCode
    01403 THistSvc::connect(const std::string& ident) {
    01404
    01405   Tokenizer tok(true);
    01406
    01407   string::size_type loc = ident.find(" ");
    01408   string stream = ident.substr(0,loc);
    01409   char typ(0);
    01410   typedef std::pair<std::string,std::string>      Prop;
    01411   std::vector<Prop> props;
    01412   string val,VAL,TAG,filename,db_typ("ROOT");
    01413   int cl(1);
    01414
    01415   tok.analyse(ident.substr(loc+1,ident.length()), " ", "", "", "=", "'", "'");
    01416
    01417   for ( Tokenizer::Items::iterator i = tok.items().begin(); i != tok.items().end(); i++)    {
    01418     const std::string& tag = (*i).tag();
    01419     TAG = tag;
    01420     toupper(TAG);
    01421
    01422     val = (*i).value();
    01423     VAL = val;
    01424     toupper(VAL);
    01425
    01426     if (TAG == "FILE" || TAG == "DATAFILE") {
    01427       filename = val;
    01428       removeDoubleSlash( filename );
    01429     } else if ( TAG == "OPT" ) {
    01430       if ( VAL == "APPEND" || VAL == "UPDATE" ) {
    01431         typ = 'A';
    01432       } else if ( VAL == "CREATE" || VAL == "NEW" || VAL == "WRITE" ) {
    01433         typ = 'N';
    01434       } else if ( VAL == "RECREATE" ) {
    01435         typ = 'R';
    01436       } else if (VAL == "SHARE") {
    01437         typ = 'S';
    01438       } else if ( VAL == "OLD" || VAL == "READ" ) {
    01439         typ = 'O';
    01440       } else {
    01441         m_log << MSG::ERROR << "Unknown OPT: \"" << (*i).value() << "\""
    01442             << endmsg;
    01443         typ = 0;
    01444       }
    01445     } else if (TAG == "TYP") {
    01446       db_typ = (*i).value();
    01447     } else if (TAG == "CL") {
    01448       cl = atoi(val.c_str());
    01449     } else {
    01450       props.push_back( Prop((*i).tag(), (*i).value()));
    01451     }
    01452
    01453   }
    01454
    01455   if (stream == "temp") {
    01456     m_log << MSG::ERROR << "in JobOption \"" << ident
    01457           << "\": stream name \"temp\" reserved."
    01458           << endmsg;
    01459     return StatusCode::FAILURE;
    01460   }
    01461
    01462   if (db_typ != "ROOT") {
    01463     m_log << MSG::ERROR << "in JobOption \"" << ident
    01464           << "\": technology type \"" << db_typ << "\" not supported."
    01465           << endmsg;
    01466     return StatusCode::FAILURE;
    01467   }
    01468
    01469
    01470   if (m_files.find(stream) != m_files.end()) {
    01471     m_log << MSG::ERROR << "in JobOption \"" << ident
    01472           << "\":\n stream \"" << stream << "\" already connected to file: \""
    01473           << m_files[stream].first->GetName() << "\""
    01474           << endmsg;
    01475     return StatusCode::FAILURE;
    01476   }
    01477
    01478   Mode newMode;
    01479   if (typ == 'O') {
    01480     newMode = THistSvc::READ;
    01481   } else if (typ == 'N') {
    01482     newMode = THistSvc::WRITE;
    01483   } else if (typ == 'A') {
    01484     newMode = THistSvc::APPEND;
    01485   } else if (typ == 'R') {
    01486     newMode = THistSvc::UPDATE;
    01487   } else if (typ == 'S') {
    01488     newMode = THistSvc::SHARE;
    01489   } else {
    01490     // something else?
    01491     m_log << MSG::ERROR << "No OPT= specified or unknown access mode in: "
    01492           << ident << endmsg;
    01493     return StatusCode::FAILURE;
    01494   }
    01495
    01496   // Is this file already connected to another stream?
    01497   if (m_fileStreams.find(filename) != m_fileStreams.end()) {
    01498     std::pair<streamMap::iterator, streamMap::iterator> fitr =
    01499       m_fileStreams.equal_range(filename);
    01500
    01501     std::string oldstream = (fitr.first)->second;
    01502
    01503     std::pair<TFile*,Mode> f_info = m_files[oldstream];
    01504
    01505     if (newMode != f_info.second) {
    01506       m_log << MSG::ERROR << "in JobOption \"" << ident
    01507             << "\":\n file \"" << filename << "\" already opened by stream: \""
    01508             << oldstream << "\" with different access mode."
    01509             << endmsg;
    01510       return StatusCode::FAILURE;
    01511     } else {
    01512       TFile *f2 = f_info.first;
    01513       m_files[stream] = make_pair<TFile*,Mode>(f2,newMode);
    01514       if (m_log.level() <= MSG::DEBUG)
    01515         m_log << MSG::DEBUG << "Connecting stream: \"" << stream
    01516               << "\" to previously opened TFile: \"" << filename << "\""
    01517               << endmsg;
    01518       return StatusCode::SUCCESS;
    01519     }
    01520   }
    01521
    01522
    01523   IIncidentSvc *pi(0);
    01524   if (service("IncidentSvc",pi).isFailure()) {
    01525     m_log << MSG::ERROR << "Unable to get the IncidentSvc" << endmsg;
    01526     return StatusCode::FAILURE;
    01527   }
    01528
    01529   TFile *f(0) ;
    01530   if (newMode == THistSvc::READ) {
    01531     // old file
    01532
    01533     try {
    01534       f = TFile::Open(filename.c_str(),"READ");
    01535     } catch (const std::exception& Exception) {
    01536       m_log << MSG::ERROR << "exception caught while trying to open root"
    01537             << " file for reading: " << Exception.what() << std::endl
    01538             << "  -> file probably corrupt." << endmsg;
    01539       pi->fireIncident(FileIncident(name(), IncidentType::FailInputFile,
    01540                                     filename));
    01541       return StatusCode::FAILURE;
    01542     } catch (...) {
    01543       m_log << MSG::ERROR << "Problems opening input file  \"" << filename
    01544             << "\": probably corrupt" << endmsg;
    01545       pi->fireIncident(FileIncident(name(), IncidentType::FailInputFile,
    01546                                     filename));
    01547       return StatusCode::FAILURE;
    01548     }
    01549
    01550     if (!f->IsOpen()) {
    01551       m_log << MSG::ERROR << "Unable to open input file \"" << filename
    01552             << "\": file does not exist" << endmsg;
    01553       pi->fireIncident(FileIncident(name(), IncidentType::FailInputFile,
    01554                                     filename));
    01555       return StatusCode::FAILURE;
    01556     }
    01557
    01558     // FIX ME!
    01559     pi->fireIncident(FileIncident(name(), "BeginHistFile",
    01560                                   filename));
    01561
    01562
    01563   } else if (newMode == THistSvc::WRITE) {
    01564     // new file
    01565
    01566     f = TFile::Open(filename.c_str(),"NEW",stream.c_str(),cl);
    01567     if (!f->IsOpen()) {
    01568       m_log << MSG::ERROR << "Unable to create new output file \"" << filename
    01569             << "\" for writing: file already exists" << endmsg;
    01570       pi->fireIncident(FileIncident(name(), IncidentType::FailOutputFile,
    01571                                     filename));
    01572       return StatusCode::FAILURE;
    01573     }
    01574
    01575     // FIX ME!
    01576     pi->fireIncident(FileIncident(name(), "BeginHistFile",
    01577                                   filename));
    01578
    01579   } else if (newMode == THistSvc::APPEND) {
    01580     // update file
    01581
    01582     try {
    01583       f =  TFile::Open(filename.c_str(),"UPDATE",stream.c_str(),cl);
    01584     } catch (const std::exception& Exception) {
    01585       m_log << MSG::ERROR << "exception caught while trying to open root"
    01586             << " file for appending: " << Exception.what() << std::endl
    01587             << "  -> file probably corrupt." << endmsg;
    01588       pi->fireIncident(FileIncident(name(), IncidentType::FailOutputFile,
    01589                                     filename));
    01590       return StatusCode::FAILURE;
    01591     } catch (...) {
    01592       m_log << MSG::ERROR << "Problems opening output file  \"" << filename
    01593             << "\" for append: probably corrupt" << endmsg;
    01594       pi->fireIncident(FileIncident(name(), IncidentType::FailOutputFile,
    01595                                     filename));
    01596       return StatusCode::FAILURE;
    01597     }
    01598
    01599     if (!f->IsOpen()) {
    01600       m_log << MSG::ERROR << "Unable to open output file \"" << filename
    01601             << "\" for appending" << endmsg;
    01602       pi->fireIncident(FileIncident(name(), IncidentType::FailOutputFile,
    01603                                     filename));
    01604       return StatusCode::FAILURE;
    01605     }
    01606     pi->fireIncident(FileIncident(name(), IncidentType::BeginOutputFile,
    01607                                   filename));
    01608
    01609   } else if (newMode == THistSvc::SHARE) {
    01610     // SHARE file type
    01611     //For SHARE files, all data will be stored in a temp file and will be merged into the target file
    01612     //in write() when finalize(), this help to solve some confliction. e.g. with storegate
    01613
    01614     static int ishared = 0;
    01615     stringstream out;
    01616     string realfilename=filename;
    01617     out << ishared++;
    01618     filename = string("tmp_THistSvc_")+out.str()+string(".root");
    01619
    01620     if (m_log.level() <= MSG::DEBUG)
    01621       m_log << MSG::DEBUG << "Creating temp file \"" << filename
    01622             << "\" and realfilename="<<realfilename << endmsg;
    01623     m_sharedFiles[stream]=realfilename;
    01624
    01625     try {
    01626       f = TFile::Open(filename.c_str(),"NEW",stream.c_str(),cl);
    01627     } catch (const std::exception& Exception) {
    01628       m_log << MSG::ERROR << "exception caught while trying to open root"
    01629             << " file for appending: " << Exception.what() << std::endl
    01630             << "  -> file probably corrupt." << endmsg;
    01631       pi->fireIncident(FileIncident(name(), IncidentType::FailOutputFile,
    01632                                     filename));
    01633       return StatusCode::FAILURE;
    01634     } catch (...) {
    01635       m_log << MSG::ERROR << "Problems opening output file  \"" << filename
    01636             << "\" for append: probably corrupt" << endmsg;
    01637       pi->fireIncident(FileIncident(name(), IncidentType::FailOutputFile,
    01638                                     filename));
    01639       return StatusCode::FAILURE;
    01640     }
    01641
    01642     if (!f->IsOpen()) {
    01643       m_log << MSG::ERROR << "Unable to open output file \"" << filename
    01644             << "\" for appending" << endmsg;
    01645       pi->fireIncident(FileIncident(name(), IncidentType::FailOutputFile,
    01646                                     filename));
    01647       return StatusCode::FAILURE;
    01648     }
    01649     pi->fireIncident(FileIncident(name(), IncidentType::BeginOutputFile,
    01650                                   filename));
    01651
    01652   } else if (newMode == THistSvc::UPDATE) {
    01653     // update file
    01654
    01655     try {
    01656       f =  TFile::Open(filename.c_str(),"RECREATE",stream.c_str(),cl);
    01657     } catch (const std::exception& Exception) {
    01658       m_log << MSG::ERROR << "exception caught while trying to open root"
    01659             << " file for updating: " << Exception.what() << std::endl
    01660             << "  -> file probably corrupt." << endmsg;
    01661       pi->fireIncident(FileIncident(name(), IncidentType::FailOutputFile,
    01662                                     filename));
    01663       return StatusCode::FAILURE;
    01664     } catch (...) {
    01665       m_log << MSG::ERROR << "Problems opening output file  \"" << filename
    01666             << "\" for update: probably corrupt" << endmsg;
    01667       pi->fireIncident(FileIncident(name(), IncidentType::FailOutputFile,
    01668                                     filename));
    01669       return StatusCode::FAILURE;
    01670     }
    01671
    01672     if (!f->IsOpen()) {
    01673       m_log << MSG::ERROR << "Unable to open output file \"" << filename
    01674             << "\" for updating" << endmsg;
    01675       pi->fireIncident(FileIncident(name(), IncidentType::FailOutputFile,
    01676                                     filename));
    01677       return StatusCode::FAILURE;
    01678     }
    01679     pi->fireIncident(FileIncident(name(), IncidentType::BeginOutputFile,
    01680                                   filename));
    01681
    01682   }
    01683
    01684   m_files[stream] = make_pair<TFile*,Mode>(f,newMode);
    01685   m_fileStreams.insert(make_pair<std::string,std::string>(filename,stream));
    01686
    01687   if (m_log.level() <= MSG::DEBUG)
    01688     m_log << MSG::DEBUG << "Opening TFile \"" << filename << "\"  stream: \""
    01689           << stream << "\"  mode: \"" << typ << "\"" << " comp level: " << cl
    01690           << endmsg;
    01691
    01692   return StatusCode::SUCCESS;
    01693 }
    01694
    01695 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    01696
    01697 TDirectory*
    01698 THistSvc::changeDir(const THistSvc::THistID& hid) const {
    01699
    01700   string uid = hid.id;
    01701   TFile* file = hid.file;
    01702   string stream, fdir, bdir, dir, id;
    01703
    01704   if (file != 0) {
    01705     file->cd("/");
    01706   } else {
    01707     gROOT->cd();
    01708   }
    01709
    01710   fdir = uid;
    01711   bdir = dirname(fdir);
    01712
    01713   while ( (dir = dirname(fdir)) != "") {
    01714     if (! gDirectory->GetKey(dir.c_str())) {
    01715       gDirectory->mkdir(dir.c_str());
    01716     }
    01717     gDirectory->cd(dir.c_str());
    01718   }
    01719
    01720   return gDirectory;
    01721
    01722 }
    01723
    01724 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    01725
    01726 std::string
    01727 THistSvc::dirname(std::string& dir) const {
    01728
    01729
    01730   string::size_type i = dir.find("/");
    01731
    01732   if (i == string::npos) {
    01733     return "";
    01734   }
    01735
    01736   if ( i == 0 ) {
    01737     dir.erase(0,1);
    01738     return dirname(dir);
    01739   }
    01740
    01741   string root = dir.substr(0,i);
    01742   dir.erase(0,i);
    01743
    01744   return root;
    01745
    01746 }
    01747
    01748 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    01749
    01750 THistSvc::GlobalDirectoryRestore::GlobalDirectoryRestore() {
    01751   m_gd = gDirectory;
    01752   m_gf = gFile;
    01753   m_ge = gErrorIgnoreLevel;
    01754 }
    01755
    01756 THistSvc::GlobalDirectoryRestore::~GlobalDirectoryRestore() {
    01757   gDirectory = m_gd;
    01758   gFile = m_gf;
    01759   gErrorIgnoreLevel = m_ge;
    01760 }
    01761
    01762 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    01763
    01764 void
    01765 THistSvc::removeDoubleSlash(std::string& id) const {
    01766
    01767   while (id.find("//") != std::string::npos) {
    01768     id.replace(id.find("//"),2,"/");
    01769   }
    01770
    01771 }
    01772
    01773 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    01774
    01775 void THistSvc::MergeRootFile(TDirectory *target, TDirectory *source) {
    01776
    01777   if (m_log.level() <= MSG::DEBUG)
    01778     m_log <<MSG::DEBUG << "Target path: " << target->GetPath() << endmsg;
    01779   TString path( (char*)strstr(target->GetPath(), ":") );
    01780   path.Remove( 0, 2);
    01781
    01782   source->cd(path);
    01783   TDirectory *current_sourcedir = gDirectory;
    01784
    01785   // loop over all keys in this directory
    01786   TList *lkeys=current_sourcedir->GetListOfKeys();
    01787   int nkeys=lkeys->GetEntries();
    01788   TKey *key;
    01789   for (int jj=0; jj<nkeys; jj++) {
    01790     key=(TKey*) lkeys->At(jj);
    01791     string pathnameinsource=current_sourcedir->GetPath()+string("/")+key->GetName();
    01792     if (m_log.level() <= MSG::DEBUG)
    01793       m_log <<MSG::DEBUG << "Reading Key:" << pathnameinsource << endmsg;
    01794     //key->Dump();
    01795     //TObject *obj=key->ReadObj();
    01796     TObject *obj=source->Get(pathnameinsource.c_str());
    01797
    01798     if (obj->IsA()->InheritsFrom("TDirectory") ) {
    01799       // it's a subdirectory
    01800
    01801       if (m_log.level() <= MSG::DEBUG)
    01802         m_log <<MSG::DEBUG << "Found subdirectory " << obj->GetName()
    01803               << endmsg;
    01804
    01805       // create a new subdir of same name and title in the target file
    01806       target->cd();
    01807       TDirectory *newtargetdir =
    01808         target->mkdir(obj->GetName(), obj->GetTitle() );
    01809
    01810       MergeRootFile(newtargetdir, source);
    01811
    01812     } else if (obj->IsA()->InheritsFrom("TTree")) {
    01813       if (m_log.level() <= MSG::DEBUG)
    01814         m_log <<MSG::DEBUG << "Found TTree " << obj->GetName() << endmsg;
    01815       TTree *mytree=dynamic_cast<TTree*>(obj);
    01816       int nentries=(int) mytree->GetEntries();
    01817       mytree->SetBranchStatus("*",1);
    01818
    01819       if (m_log.level() <= MSG::DEBUG)
    01820         m_log <<MSG::DEBUG << "Dumping TTree " << nentries <<" entries"
    01821               << endmsg;
    01822       //mytree->Print();
    01823       //for (int ij=0; ij<nentries; ij++) {
    01824       //m_log <<MSG::DEBUG << "Dumping TTree Show( " << ij <<" )"
    01825       //<< endmsg;
    01826       //mytree->Show(ij);
    01827       //}
    01828       target->cd();
    01829       mytree->CloneTree();
    01830
    01831       //m_log <<MSG::DEBUG << "Writing TTree to target file: ( "
    01832       //<< mycopiedtree->Write(key->GetName()) <<" ) bytes written"
    01833       //<< endmsg;
    01834
    01835     } else if (obj) {
    01836       target->cd();
    01837       obj->Write(key->GetName() );
    01838     }
    01839
    01840   } // while ( ( TKey *key = (TKey*)nextkey() ) )
    01841
    01842   // save modifications to target file
    01843
    01844 }
    01845
    01846 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    01847
    01848 bool
    01849 THistSvc::exists( const std::string& name ) const {
    01850
    01851   TH1* h;
    01852
    01853   return getHist_i(name,h,true).isSuccess();
    01854
    01855
    01856 }
    01857
    01858 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
    01859
    01860 void
    01861 THistSvc::handle( const Incident& /* inc */ ) {
    01862
    01863   if (signaledStop) return ;
    01864
    01865   // convert to bytes.
    01866   Long64_t mfs = (Long64_t)m_maxFileSize.value() * (Long64_t)1048576;
    01867   Long64_t mfs_warn = mfs * 95 / 100;
    01868
    01869   updateFiles();
    01870
    01871   map<string, pair<TFile*,Mode> >::const_iterator itr;
    01872   for (itr=m_files.begin(); itr!= m_files.end(); ++itr) {
    01873     TFile* tf = itr->second.first;
    01874
    01875 #ifndef NDEBUG
    01876     if (m_log.level() <= MSG::DEBUG)
    01877       m_log << MSG::DEBUG << "stream: " << itr->first << "  name: "
    01878             << tf->GetName() << "  size: " << tf->GetSize()
    01879             << endmsg;
    01880 #endif
    01881
    01882     // Signal job to terminate if output file is too large
    01883     if (tf->GetSize() > mfs) {
    01884
    01885       signaledStop = true;
    01886
    01887       m_log << MSG::FATAL << "file \"" << tf->GetName()
    01888             << "\" associated with stream \"" << itr->first
    01889             << "\" has exceeded the max file size of "
    01890             << m_maxFileSize.value() << "MB. Terminating Job."
    01891             << endmsg;
    01892
    01893       IEventProcessor* evt(0);
    01894       if (service("ApplicationMgr", evt, true).isSuccess()) {
    01895         evt->stopRun();
    01896         evt->release();
    01897       } else {
    01898         abort();
    01899       }
    01900     } else if (tf->GetSize() > mfs_warn) {
    01901       m_log << MSG::WARNING << "file \"" << tf->GetName()
    01902             << "\" associated with stream \"" << itr->first
    01903             << "\" is at 95% of its maximum allowable file size of "
    01904             << m_maxFileSize.value() << "MB"
    01905             << endmsg;
    01906     }
    01907   }
    01908 }

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines