Gaudi Framework, version v22r2

Home   Generated: Tue May 10 2011
Classes | Public Member Functions | Protected Member Functions | Private Types | Private Member Functions | Private Attributes

THistSvc Class Reference

#include <THistSvc.h>

Inheritance diagram for THistSvc:
Inheritance graph
[legend]
Collaboration diagram for THistSvc:
Collaboration graph
[legend]

List of all members.

Classes

class  GlobalDirectoryRestore
struct  THistID

Public Member Functions

virtual StatusCode initialize ()
virtual StatusCode reinitialize ()
virtual StatusCode finalize ()
virtual StatusCode regHist (const std::string &name)
virtual StatusCode regHist (const std::string &name, TH1 *)
virtual StatusCode regHist (const std::string &name, TH2 *)
virtual StatusCode regHist (const std::string &name, TH3 *)
virtual StatusCode getHist (const std::string &name, TH1 *&) const
virtual StatusCode getHist (const std::string &name, TH2 *&) const
virtual StatusCode getHist (const std::string &name, TH3 *&) const
virtual StatusCode regTree (const std::string &name)
virtual StatusCode regTree (const std::string &name, TTree *)
virtual StatusCode getTree (const std::string &name, TTree *&) const
virtual StatusCode regGraph (const std::string &name)
virtual StatusCode regGraph (const std::string &name, TGraph *)
virtual StatusCode getGraph (const std::string &name, TGraph *&) const
virtual StatusCode deReg (TObject *obj)
virtual StatusCode deReg (const std::string &name)
virtual std::vector< std::stringgetHists () const
virtual std::vector< std::stringgetTrees () const
virtual std::vector< std::stringgetGraphs () const
virtual StatusCode getTHists (TDirectory *td, TList &, bool recurse=false) const
virtual StatusCode getTHists (const std::string &name, TList &, bool recurse=false) const
virtual StatusCode getTHists (TDirectory *td, TList &tl, bool recurse=false, bool reg=false)
virtual StatusCode getTHists (const std::string &name, TList &tl, bool recurse=false, bool reg=false)
virtual StatusCode getTTrees (TDirectory *td, TList &, bool recurse=false) const
virtual StatusCode getTTrees (const std::string &name, TList &, bool recurse=false) const
virtual StatusCode getTTrees (TDirectory *td, TList &tl, bool recurse=false, bool reg=false)
virtual StatusCode getTTrees (const std::string &name, TList &tl, bool recurse=false, bool reg=false)
virtual bool exists (const std::string &name) const
 THistSvc (const std::string &name, ISvcLocator *svc)
void handle (const Incident &)

Protected Member Functions

virtual ~THistSvc ()

Private Types

enum  Mode {
  READ, WRITE, UPDATE, APPEND,
  SHARE
}
typedef std::map< std::string,
THistID
uidMap
typedef std::multimap
< std::string, THistID
idMap
typedef std::map< TObject
*, THistID
objMap
typedef std::multimap
< std::string, std::string
streamMap

Private Member Functions

template<typename T >
StatusCode regHist_i (T *hist, const std::string &name)
template<typename T >
StatusCode getHist_i (const std::string &name, T *&hist, bool quiet=false) const
template<typename T >
StatusCode readHist_i (const std::string &name, T *&hist) const
StatusCode readHist (const std::string &name, TH1 *&) const
StatusCode readHist (const std::string &name, TH2 *&) const
StatusCode readHist (const std::string &name, TH3 *&) const
StatusCode readTree (const std::string &name, TTree *&) const
void updateFiles ()
StatusCode write ()
StatusCode connect (const std::string &)
TDirectory * changeDir (const THistSvc::THistID &hid) const
std::string dirname (std::string &dir) const
void removeDoubleSlash (std::string &) const
bool browseTDir (TDirectory *dir) const
bool findStream (const std::string &name, std::string &root, std::string &rem, TFile *&file) const
void parseString (const std::string &id, std::string &root, std::string &rem) const
void setupInputFile (Property &inputfile)
 call-back method to handle input stream property
void setupOutputFile (Property &outputfile)
 call-back method to handle output stream property
void setupCompressionLevel (Property &cmp)
void MergeRootFile (TDirectory *target, TDirectory *source)

Private Attributes

MsgStream m_log
StringArrayProperty m_inputfile
StringArrayProperty m_outputfile
std::vector< std::stringm_Rstream
std::vector< std::stringm_Wstream
IntegerProperty m_autoSave
IntegerProperty m_autoFlush
IntegerProperty m_compressionLevel
IntegerProperty m_maxFileSize
BooleanProperty m_print
std::set< std::stringm_alreadyConnectedInFiles
 list of already connected files.
std::set< std::stringm_alreadyConnectedOutFiles
 list of already connected files.
uidMap m_uids
idMap m_ids
objMap m_tobjs
std::map< std::string,
std::pair< TFile *, Mode > > 
m_files
streamMap m_fileStreams
std::map< std::string,
std::string
m_sharedFiles
bool signaledStop
std::string m_curstream

Detailed Description

Definition at line 26 of file THistSvc.h.


Member Typedef Documentation

Definition at line 129 of file THistSvc.h.

typedef std::map<TObject*, THistID> THistSvc::objMap [private]

Definition at line 130 of file THistSvc.h.

Definition at line 131 of file THistSvc.h.

Definition at line 128 of file THistSvc.h.


Member Enumeration Documentation

enum THistSvc::Mode [private]
Enumerator:
READ 
WRITE 
UPDATE 
APPEND 
SHARE 

Definition at line 118 of file THistSvc.h.


Constructor & Destructor Documentation

THistSvc::THistSvc ( const std::string name,
ISvcLocator svc 
)

Definition at line 45 of file THistSvc.cpp.

  : base_class(name, svc), m_log(msgSvc(), name ), signaledStop(false) {

  declareProperty ("AutoSave", m_autoSave=0 );
  declareProperty ("AutoFlush", m_autoFlush=0 );
  declareProperty ("PrintAll", m_print=false);
  declareProperty ("MaxFileSize", m_maxFileSize=10240,
                   "maximum file size in MB. if exceeded, will cause an abort");
  declareProperty ("CompressionLevel", m_compressionLevel=1 )->declareUpdateHandler( &THistSvc::setupCompressionLevel, this );
  declareProperty ("Output", m_outputfile )->declareUpdateHandler( &THistSvc::setupOutputFile, this );
  declareProperty ("Input", m_inputfile )->declareUpdateHandler ( &THistSvc::setupInputFile,  this );


}
THistSvc::~THistSvc (  ) [protected, virtual]

Definition at line 62 of file THistSvc.cpp.

                    {

}

Member Function Documentation

bool THistSvc::browseTDir ( TDirectory *  dir ) const [private]

Definition at line 347 of file THistSvc.cpp.

                                          {

  if (dir == 0) {
    std::cerr << "TDirectory == 0" << std::endl;
    return false;
  }

  GlobalDirectoryRestore restore;

  dir->cd();


  cout << "-> " << dir->GetPath() << "  "
       << dir->GetListOfKeys()->GetSize() << endl;

  //  TIter nextkey(dir->GetListOfKeys());
  TIter nextkey(dir->GetList());
  while (TKey *key = (TKey*)nextkey()) {

    TObject *obj = key->ReadObj();
    if (obj == 0) { cout << key->GetName() << " obj==0"<< endl; continue; }
    //    if (obj->IsA()->InheritsFrom("TDirectory")) {
      cout << "  Key: " << key->GetName() << "   "
           << " tit: " << obj->GetTitle() << "   "
           << " (" << key->GetClassName() << ")" << endl;
      //    }
  }

  nextkey = dir->GetListOfKeys();
  while (TKey *key = (TKey*)nextkey()) {

    TObject *obj = key->ReadObj();
    if (obj == 0) { cout << key->GetName() << " obj==0"<< endl; continue; }
    if (obj->IsA()->InheritsFrom("TDirectory")) {
      TDirectory *tt = dynamic_cast<TDirectory*>(obj);
      browseTDir(tt);
    }
  }

  return true;
}
TDirectory * THistSvc::changeDir ( const THistSvc::THistID hid ) const [private]

Definition at line 1698 of file THistSvc.cpp.

                                                    {

  string uid = hid.id;
  TFile* file = hid.file;
  string stream, fdir, bdir, dir, id;

  if (file != 0) {
    file->cd("/");
  } else {
    gROOT->cd();
  }

  fdir = uid;
  bdir = dirname(fdir);

  while ( (dir = dirname(fdir)) != "") {
    if (! gDirectory->GetKey(dir.c_str())) {
      gDirectory->mkdir(dir.c_str());
    }
    gDirectory->cd(dir.c_str());
  }

  return gDirectory;

}
StatusCode THistSvc::connect ( const std::string ident ) [private]

Definition at line 1403 of file THistSvc.cpp.

                                        {

  Tokenizer tok(true);

  string::size_type loc = ident.find(" ");
  string stream = ident.substr(0,loc);
  char typ(0);
  typedef std::pair<std::string,std::string>      Prop;
  std::vector<Prop> props;
  string val,VAL,TAG,filename,db_typ("ROOT");
  int cl(1);

  tok.analyse(ident.substr(loc+1,ident.length()), " ", "", "", "=", "'", "'");

  for ( Tokenizer::Items::iterator i = tok.items().begin(); i != tok.items().end(); i++)    {
    const std::string& tag = (*i).tag();
    TAG = tag;
    toupper(TAG);

    val = (*i).value();
    VAL = val;
    toupper(VAL);

    if (TAG == "FILE" || TAG == "DATAFILE") {
      filename = val;
      removeDoubleSlash( filename );
    } else if ( TAG == "OPT" ) {
      if ( VAL == "APPEND" || VAL == "UPDATE" ) {
        typ = 'A';
      } else if ( VAL == "CREATE" || VAL == "NEW" || VAL == "WRITE" ) {
        typ = 'N';
      } else if ( VAL == "RECREATE" ) {
        typ = 'R';
      } else if (VAL == "SHARE") {
        typ = 'S';
      } else if ( VAL == "OLD" || VAL == "READ" ) {
        typ = 'O';
      } else {
        m_log << MSG::ERROR << "Unknown OPT: \"" << (*i).value() << "\""
            << endmsg;
        typ = 0;
      }
    } else if (TAG == "TYP") {
      db_typ = (*i).value();
    } else if (TAG == "CL") {
      cl = atoi(val.c_str());
    } else {
      props.push_back( Prop((*i).tag(), (*i).value()));
    }

  }

  if (stream == "temp") {
    m_log << MSG::ERROR << "in JobOption \"" << ident
          << "\": stream name \"temp\" reserved."
          << endmsg;
    return StatusCode::FAILURE;
  }

  if (db_typ != "ROOT") {
    m_log << MSG::ERROR << "in JobOption \"" << ident
          << "\": technology type \"" << db_typ << "\" not supported."
          << endmsg;
    return StatusCode::FAILURE;
  }


  if (m_files.find(stream) != m_files.end()) {
    m_log << MSG::ERROR << "in JobOption \"" << ident
          << "\":\n stream \"" << stream << "\" already connected to file: \""
          << m_files[stream].first->GetName() << "\""
          << endmsg;
    return StatusCode::FAILURE;
  }

  Mode newMode;
  if (typ == 'O') {
    newMode = THistSvc::READ;
  } else if (typ == 'N') {
    newMode = THistSvc::WRITE;
  } else if (typ == 'A') {
    newMode = THistSvc::APPEND;
  } else if (typ == 'R') {
    newMode = THistSvc::UPDATE;
  } else if (typ == 'S') {
    newMode = THistSvc::SHARE;
  } else {
    // something else?
    m_log << MSG::ERROR << "No OPT= specified or unknown access mode in: "
          << ident << endmsg;
    return StatusCode::FAILURE;
  }

  // Is this file already connected to another stream?
  if (m_fileStreams.find(filename) != m_fileStreams.end()) {
    std::pair<streamMap::iterator, streamMap::iterator> fitr =
      m_fileStreams.equal_range(filename);

    std::string oldstream = (fitr.first)->second;

    std::pair<TFile*,Mode> f_info = m_files[oldstream];

    if (newMode != f_info.second) {
      m_log << MSG::ERROR << "in JobOption \"" << ident
            << "\":\n file \"" << filename << "\" already opened by stream: \""
            << oldstream << "\" with different access mode."
            << endmsg;
      return StatusCode::FAILURE;
    } else {
      TFile *f2 = f_info.first;
      m_files[stream] = make_pair<TFile*,Mode>(f2,newMode);
      if (m_log.level() <= MSG::DEBUG)
        m_log << MSG::DEBUG << "Connecting stream: \"" << stream
              << "\" to previously opened TFile: \"" << filename << "\""
              << endmsg;
      return StatusCode::SUCCESS;
    }
  }


  IIncidentSvc *pi(0);
  if (service("IncidentSvc",pi).isFailure()) {
    m_log << MSG::ERROR << "Unable to get the IncidentSvc" << endmsg;
    return StatusCode::FAILURE;
  }

  TFile *f(0) ;
  if (newMode == THistSvc::READ) {
    // old file

    try {
      f = TFile::Open(filename.c_str(),"READ");
    } catch (const std::exception& Exception) {
      m_log << MSG::ERROR << "exception caught while trying to open root"
            << " file for reading: " << Exception.what() << std::endl
            << "  -> file probably corrupt." << endmsg;
      pi->fireIncident(FileIncident(name(), IncidentType::FailInputFile,
                                    filename));
      return StatusCode::FAILURE;
    } catch (...) {
      m_log << MSG::ERROR << "Problems opening input file  \"" << filename
            << "\": probably corrupt" << endmsg;
      pi->fireIncident(FileIncident(name(), IncidentType::FailInputFile,
                                    filename));
      return StatusCode::FAILURE;
    }

    if (!f->IsOpen()) {
      m_log << MSG::ERROR << "Unable to open input file \"" << filename
            << "\": file does not exist" << endmsg;
      pi->fireIncident(FileIncident(name(), IncidentType::FailInputFile,
                                    filename));
      return StatusCode::FAILURE;
    }

    // FIX ME!
    pi->fireIncident(FileIncident(name(), "BeginHistFile",
                                  filename));


  } else if (newMode == THistSvc::WRITE) {
    // new file

    f = TFile::Open(filename.c_str(),"NEW",stream.c_str(),cl);
    if (!f->IsOpen()) {
      m_log << MSG::ERROR << "Unable to create new output file \"" << filename
            << "\" for writing: file already exists" << endmsg;
      pi->fireIncident(FileIncident(name(), IncidentType::FailOutputFile,
                                    filename));
      return StatusCode::FAILURE;
    }

    // FIX ME!
    pi->fireIncident(FileIncident(name(), "BeginHistFile",
                                  filename));

  } else if (newMode == THistSvc::APPEND) {
    // update file

    try {
      f =  TFile::Open(filename.c_str(),"UPDATE",stream.c_str(),cl);
    } catch (const std::exception& Exception) {
      m_log << MSG::ERROR << "exception caught while trying to open root"
            << " file for appending: " << Exception.what() << std::endl
            << "  -> file probably corrupt." << endmsg;
      pi->fireIncident(FileIncident(name(), IncidentType::FailOutputFile,
                                    filename));
      return StatusCode::FAILURE;
    } catch (...) {
      m_log << MSG::ERROR << "Problems opening output file  \"" << filename
            << "\" for append: probably corrupt" << endmsg;
      pi->fireIncident(FileIncident(name(), IncidentType::FailOutputFile,
                                    filename));
      return StatusCode::FAILURE;
    }

    if (!f->IsOpen()) {
      m_log << MSG::ERROR << "Unable to open output file \"" << filename
            << "\" for appending" << endmsg;
      pi->fireIncident(FileIncident(name(), IncidentType::FailOutputFile,
                                    filename));
      return StatusCode::FAILURE;
    }
    pi->fireIncident(FileIncident(name(), IncidentType::BeginOutputFile,
                                  filename));

  } else if (newMode == THistSvc::SHARE) {
    // SHARE file type
    //For SHARE files, all data will be stored in a temp file and will be merged into the target file
    //in write() when finalize(), this help to solve some confliction. e.g. with storegate

    static int ishared = 0;
    stringstream out;
    string realfilename=filename;
    out << ishared++;
    filename = string("tmp_THistSvc_")+out.str()+string(".root");

    if (m_log.level() <= MSG::DEBUG)
      m_log << MSG::DEBUG << "Creating temp file \"" << filename
            << "\" and realfilename="<<realfilename << endmsg;
    m_sharedFiles[stream]=realfilename;

    try {
      f = TFile::Open(filename.c_str(),"NEW",stream.c_str(),cl);
    } catch (const std::exception& Exception) {
      m_log << MSG::ERROR << "exception caught while trying to open root"
            << " file for appending: " << Exception.what() << std::endl
            << "  -> file probably corrupt." << endmsg;
      pi->fireIncident(FileIncident(name(), IncidentType::FailOutputFile,
                                    filename));
      return StatusCode::FAILURE;
    } catch (...) {
      m_log << MSG::ERROR << "Problems opening output file  \"" << filename
            << "\" for append: probably corrupt" << endmsg;
      pi->fireIncident(FileIncident(name(), IncidentType::FailOutputFile,
                                    filename));
      return StatusCode::FAILURE;
    }

    if (!f->IsOpen()) {
      m_log << MSG::ERROR << "Unable to open output file \"" << filename
            << "\" for appending" << endmsg;
      pi->fireIncident(FileIncident(name(), IncidentType::FailOutputFile,
                                    filename));
      return StatusCode::FAILURE;
    }
    pi->fireIncident(FileIncident(name(), IncidentType::BeginOutputFile,
                                  filename));

  } else if (newMode == THistSvc::UPDATE) {
    // update file

    try {
      f =  TFile::Open(filename.c_str(),"RECREATE",stream.c_str(),cl);
    } catch (const std::exception& Exception) {
      m_log << MSG::ERROR << "exception caught while trying to open root"
            << " file for updating: " << Exception.what() << std::endl
            << "  -> file probably corrupt." << endmsg;
      pi->fireIncident(FileIncident(name(), IncidentType::FailOutputFile,
                                    filename));
      return StatusCode::FAILURE;
    } catch (...) {
      m_log << MSG::ERROR << "Problems opening output file  \"" << filename
            << "\" for update: probably corrupt" << endmsg;
      pi->fireIncident(FileIncident(name(), IncidentType::FailOutputFile,
                                    filename));
      return StatusCode::FAILURE;
    }

    if (!f->IsOpen()) {
      m_log << MSG::ERROR << "Unable to open output file \"" << filename
            << "\" for updating" << endmsg;
      pi->fireIncident(FileIncident(name(), IncidentType::FailOutputFile,
                                    filename));
      return StatusCode::FAILURE;
    }
    pi->fireIncident(FileIncident(name(), IncidentType::BeginOutputFile,
                                  filename));

  }

  m_files[stream] = make_pair<TFile*,Mode>(f,newMode);
  m_fileStreams.insert(make_pair<std::string,std::string>(filename,stream));

  if (m_log.level() <= MSG::DEBUG)
    m_log << MSG::DEBUG << "Opening TFile \"" << filename << "\"  stream: \""
          << stream << "\"  mode: \"" << typ << "\"" << " comp level: " << cl
          << endmsg;

  return StatusCode::SUCCESS;
}
StatusCode THistSvc::deReg ( const std::string name ) [virtual]

Definition at line 921 of file THistSvc.cpp.

                                   {

  uidMap::iterator itr = m_uids.find(id);
  if (itr == m_uids.end()) {
    m_log << MSG::ERROR << "Problems deregistering id \""
          << id << "\"" << endmsg;
    return StatusCode::FAILURE;
  }

  TObject* obj = itr->second.obj;

  return deReg(obj);
}
StatusCode THistSvc::deReg ( TObject *  obj ) [virtual]

Definition at line 863 of file THistSvc.cpp.

                            {

  objMap::iterator itr = m_tobjs.find(obj);
  if (itr != m_tobjs.end()) {
    THistID hid = itr->second;

    uidMap::iterator itr2 = m_uids.find(hid.id);
    if (itr2 == m_uids.end()) {
      m_log << MSG::ERROR << "Problems deregistering TObject \""
            << obj->GetName()
            << "\" with id \"" << hid.id << "\"" << endmsg;
      return StatusCode::FAILURE;
    }

    std::string id,root,rem;
    parseString(hid.id, root, rem);

    idMap::iterator itr3;
    bool found(false);

    std::pair<idMap::iterator, idMap::iterator> mitr = m_ids.equal_range(rem);
    if (mitr.first == mitr.second) {
      m_log << MSG::ERROR << "Problems deregistering TObject \""
            << obj->GetName()
            << "\" with id \"" << hid.id << "\"" << endmsg;
      return StatusCode::FAILURE;
    } else {
      for (itr3 = mitr.first; itr3 != mitr.second; ++itr3) {
        if (itr3->second.obj == obj) {
          found = true;
          break;
        }
      }
      if (!found) {
        m_log << MSG::ERROR << "Problems deregistering TObject \""
              << obj->GetName()
              << "\" with id \"" << hid.id << "\"" << endmsg;
      }
    }

    m_tobjs.erase(itr);
    m_uids.erase(itr2);
    m_ids.erase(itr3);

    return StatusCode::SUCCESS;

  } else {
    m_log << MSG::ERROR << "Cannot unregister TObject \"" << obj->GetName()
          << "\": not known to THistSvc" << endmsg;
    return StatusCode::FAILURE;
  }

}
std::string THistSvc::dirname ( std::string dir ) const [private]

Definition at line 1727 of file THistSvc.cpp.

                                      {


  string::size_type i = dir.find("/");

  if (i == string::npos) {
    return "";
  }

  if ( i == 0 ) {
    dir.erase(0,1);
    return dirname(dir);
  }

  string root = dir.substr(0,i);
  dir.erase(0,i);

  return root;

}
bool THistSvc::exists ( const std::string name ) const [virtual]

Definition at line 1849 of file THistSvc.cpp.

                                              {

  TH1* h;

  return getHist_i(name,h,true).isSuccess();


}
StatusCode THistSvc::finalize ( void   ) [virtual]

Reimplemented from Service.

Definition at line 166 of file THistSvc.cpp.

                   {

  GlobalDirectoryRestore restore;

  if (m_log.level() <= MSG::DEBUG)
    m_log << MSG::DEBUG << "THistSvc::finalize" << endmsg;

  uidMap::const_iterator uitr;
  for (uitr=m_uids.begin(); uitr != m_uids.end(); ++uitr) {

    TObject* to = uitr->second.obj;

    string dirname("none");
    if (to->IsA()->InheritsFrom("TTree")) {
      TTree* tr = dynamic_cast<TTree*>(to);
      if (tr->GetDirectory() != 0) {
        dirname = tr->GetDirectory()->GetPath();
      }
    } else if (to->IsA()->InheritsFrom("TGraph")) {
      if (!uitr->second.temp) {
        dirname = uitr->second.file->GetPath();
        string id2(uitr->second.id);
        id2.erase(0,id2.find("/",1));
        id2.erase(id2.rfind("/"), id2.length());
        if (id2.find("/") == 0) {
          id2.erase(0,1);
        }
        dirname += id2;
      } else {
        dirname = "/tmp";
      }
    } else if (to->IsA()->InheritsFrom("TH1")) {
      TH1* th = dynamic_cast<TH1*>(to);
      if (th == 0) {
        m_log << MSG::ERROR << "Couldn't dcast: " << uitr->first << endmsg;
      } else {
        if (th->GetDirectory() != 0) {
          dirname = th->GetDirectory()->GetPath();
        }
      }
    }

#ifndef NDEBUG
    if (m_log.level() <= MSG::DEBUG)
      m_log << MSG::DEBUG << "uid: \"" << uitr->first << "\"  temp: "
            << uitr->second.temp << "  dir: " << dirname
            << endmsg;
#endif


//     if (uitr->second.temp == true) {
//       log << MSG::INFO << "Deleting \"" << uitr->first << "\"" << endmsg;
//       delete uitr->second.obj;
//     }
  }

  StatusCode sc = write();
  if (sc.isFailure()) {
    m_log << MSG::ERROR << "problems writing histograms" << endmsg;
  }

  if (m_print) {
    m_log << MSG::INFO << "Listing contents of ROOT files: " << endmsg;
  }
  vector<TFile*> deleted_files;
  map<string, pair<TFile*,Mode> >::const_iterator itr;
  for (itr = m_files.begin(); itr != m_files.end(); ++itr) {

    if (find(deleted_files.begin(), deleted_files.end(), itr->second.first) ==
        deleted_files.end()) {
      deleted_files.push_back(itr->second.first);

#ifndef NDEBUG
      if (m_log.level() <= MSG::DEBUG)
        m_log << MSG::DEBUG << "finalizing stream/file " << itr->first << ":"
              << itr->second.first->GetName()
              << endmsg;
#endif
    } else {
#ifndef NDEBUG
      if (m_log.level() <= MSG::DEBUG)
        m_log << MSG::DEBUG << "already finalized stream " << itr->first << endmsg;
#endif
      continue;
    }


    if (m_print && m_log.level() <= MSG::INFO) {

      m_log << MSG::INFO;
      m_log << "==> File: " << itr->second.first->GetName()
            << "  stream: " << itr->first << endmsg;

      itr->second.first->Print("base");
    }

    string tmpfn=itr->second.first->GetName();

    itr->second.first->Close();

    IIncidentSvc *pi(0);
    if (service("IncidentSvc",pi).isFailure()) {
      m_log << MSG::ERROR << "Unable to get the IncidentSvc" << endmsg;
      return StatusCode::FAILURE;
    }

    if (itr->second.second==SHARE) {
      TFile *outputfile;
      //Merge File
      try {
        if (m_log.level() <= MSG::DEBUG)
          m_log << MSG::DEBUG << "Opening Final Output File: " <<m_sharedFiles[itr->first].c_str()<<endmsg;
        outputfile = new TFile(m_sharedFiles[itr->first].c_str(), "UPDATE");
      } catch (const std::exception& Exception) {
        m_log << MSG::ERROR << "exception caught while trying to open root"
              << " file for appending: " << Exception.what() << std::endl
              << "  -> file probably corrupt." << endmsg;
        pi->fireIncident(FileIncident(name(), IncidentType::FailOutputFile,
                                      m_sharedFiles[itr->first]));
        return StatusCode::FAILURE;
      } catch (...) {
        m_log << MSG::ERROR << "Problems opening output file  \""
              << m_sharedFiles[itr->first]
              << "\" for append: probably corrupt" << endmsg;
        pi->fireIncident(FileIncident(name(), IncidentType::FailOutputFile,
                                      m_sharedFiles[itr->first]));
        return StatusCode::FAILURE;
      }

      pi->fireIncident(FileIncident(name(), IncidentType::WroteToOutputFile,
                                    m_sharedFiles[itr->first]));

      if (m_log.level() <= MSG::DEBUG)
        m_log << MSG::DEBUG << "THistSvc::write()::Merging Rootfile "<<endmsg;
      TFile *inputfile;
      try {
        if (m_log.level() <= MSG::DEBUG)
          m_log << MSG::DEBUG << "Openning again Temporary File: " <<tmpfn.c_str()<<endmsg;
        inputfile=new TFile(tmpfn.c_str(),"READ");
      } catch (const std::exception& Exception) {
        m_log << MSG::ERROR << "exception caught while trying to open root"
              << " file for appending: " << Exception.what() << std::endl
              << "  -> file probably corrupt." << endmsg;
        return StatusCode::FAILURE;
      } catch (...) {
        m_log << MSG::ERROR << "Problems opening output file  \""
              << tmpfn.c_str()
              << "\" for append: probably corrupt" << endmsg;
        return StatusCode::FAILURE;
      }

      outputfile->SetCompressionLevel( inputfile->GetCompressionLevel() );

      MergeRootFile(outputfile, inputfile);

      outputfile->Write();
      outputfile->Close();
      inputfile->Close();

      if (m_log.level() <= MSG::DEBUG)
        m_log << MSG::DEBUG << "Trying to remove temporary file \"" << tmpfn
              << "\""<<endmsg;

      std::remove(tmpfn.c_str());
    }
    delete itr->second.first;
  }

  m_sharedFiles.clear();
  m_fileStreams.clear();
  m_files.clear();
  m_uids.clear();
  m_ids.clear();
  m_tobjs.clear();

  return Service::finalize();
}
bool THistSvc::findStream ( const std::string name,
std::string root,
std::string rem,
TFile *&  file 
) const [private]

Definition at line 1144 of file THistSvc.cpp.

                                       {

  string::size_type pos = id.find("/");

  if (pos == string::npos) {
    stream = "temp";
    rem = id;
  } else if (pos != 0) {
    stream = "temp";
    rem = id;
  } else {

    string::size_type pos2 = id.find("/",pos+1);

    if (pos2 == string::npos) {
      m_log << MSG::ERROR << "badly formed Hist/Tree id: \"" << id << "\""
            << endmsg;
      return false;
    }

    parseString(id,stream,rem);

  }

  if (stream == "temp") {
    file = 0;
    return true;
  }

  map< string,pair<TFile*,Mode> >::const_iterator itr = m_files.find(stream);
  if (itr != m_files.end()) {
    file = itr->second.first;
  } else {
    file = 0;
    m_log << MSG::WARNING << "no stream \"" << stream
          << "\" associated with id: \"" << id << "\""
          << endmsg;
  }

  return true;

}
StatusCode THistSvc::getGraph ( const std::string name,
TGraph *&  hist 
) const [virtual]

Definition at line 1088 of file THistSvc.cpp.

                                                           {
  return getHist_i(id, hist);
}
std::vector< std::string > THistSvc::getGraphs (  ) const [virtual]

Definition at line 1095 of file THistSvc.cpp.

                          {

  std::vector<std::string> names;
  names.reserve(m_uids.size());

  uidMap::const_iterator itr;
  for (itr = m_uids.begin(); itr != m_uids.end(); ++itr) {
    THistID tid = itr->second;

    if (tid.obj->IsA()->InheritsFrom("TGraph")) {
      names.push_back(itr->first);
    }

  }

  return names;

}
StatusCode THistSvc::getHist ( const std::string name,
TH1 *&  hist 
) const [virtual]

Definition at line 1018 of file THistSvc.cpp.

                                                       {
  return getHist_i(id, hist);
}
StatusCode THistSvc::getHist ( const std::string name,
TH2 *&  hist 
) const [virtual]

Definition at line 1025 of file THistSvc.cpp.

                                                       {
  return getHist_i(id, hist);
}
StatusCode THistSvc::getHist ( const std::string name,
TH3 *&  hist 
) const [virtual]

Definition at line 1032 of file THistSvc.cpp.

                                                       {
  return getHist_i(id, hist);
}
template<typename T >
StatusCode THistSvc::getHist_i ( const std::string name,
T *&  hist,
bool  quiet = false 
) const [private]
std::vector< std::string > THistSvc::getHists (  ) const [virtual]

Definition at line 1039 of file THistSvc.cpp.

                         {

  std::vector<std::string> names;
  names.reserve(m_uids.size());

  uidMap::const_iterator itr;
  for (itr = m_uids.begin(); itr != m_uids.end(); ++itr) {
    THistID tid = itr->second;

    if (tid.obj->IsA()->InheritsFrom("TH1")) {
      names.push_back(itr->first);
    }

  }

  return names;

}
StatusCode THistSvc::getTHists ( TDirectory *  td,
TList &  tl,
bool  recurse = false 
) const [virtual]

Definition at line 393 of file THistSvc.cpp.

                                                              {
  GlobalDirectoryRestore restore;

  gErrorIgnoreLevel = kBreak;

  if (!td->cd()) {
    m_log << MSG::ERROR << "getTHists: No such TDirectory \"" << td->GetPath()
          << "\"" << endmsg;
    return StatusCode::FAILURE;
  }

  if (m_log.level() <= MSG::DEBUG)
    m_log << MSG::DEBUG << "getTHists: \"" << td->GetPath() << "\": found "
          << td->GetListOfKeys()->GetSize() << " keys" << endmsg;

  TIter nextkey(td->GetListOfKeys());
  while (TKey *key = (TKey*)nextkey()) {
    if (m_log.level() <= MSG::DEBUG)
      m_log << MSG::DEBUG << "  key: " << key->GetName();
    TObject *obj = key->ReadObj();
    if (obj != 0 && obj->IsA()->InheritsFrom("TDirectory")) {
      if (m_log.level() <= MSG::DEBUG)
        m_log << " (" << obj->IsA()->GetName() << ")";
    } else if (obj != 0 && obj->IsA()->InheritsFrom("TH1")) {
      if (m_log.level() <= MSG::DEBUG)
        m_log << " (" << obj->IsA()->GetName() << ")";
      tl.Add(obj);
    } else if (obj != 0) {
      if (m_log.level() <= MSG::DEBUG)
        m_log << " [" << obj->IsA()->GetName() << "]";
    }
    if (m_log.level() <= MSG::DEBUG)
      m_log << endmsg;
  }

  // operate recursively
  if (rcs) {
    nextkey = td->GetListOfKeys();
    while (TKey *key = (TKey*)nextkey()) {
      TObject *obj = key->ReadObj();
      if (obj != 0 && obj->IsA()->InheritsFrom("TDirectory")) {
          TDirectory *tt = dynamic_cast<TDirectory*>(obj);
          getTHists(tt, tl, rcs);
      }
    }
  }

  return StatusCode::SUCCESS;


}
StatusCode THistSvc::getTHists ( const std::string name,
TList &  tl,
bool  recurse = false 
) const [virtual]

Definition at line 448 of file THistSvc.cpp.

                                                                    {

  GlobalDirectoryRestore restore;

  gErrorIgnoreLevel = kBreak;

  StatusCode sc;

  std::string stream,rem,r2;
  parseString(dir,stream,rem);

  map< string,pair<TFile*,Mode> >::const_iterator itr = m_files.find(stream);
  if (itr != m_files.end()) {
    r2 = itr->second.first->GetName();
    r2 += ":/";
    r2 += rem;

    if (m_log.level() <= MSG::DEBUG)
      m_log << MSG::DEBUG << "getTHists: \"" << dir
            << "\" looks like a stream name."  << " associated TFile: \""
            << itr->second.first->GetName() << "\"" << endmsg;

    if (gDirectory->cd(r2.c_str())) {
      m_curstream = stream;
      sc = getTHists(gDirectory,tl,rcs);
      m_curstream = "";
      return sc;
    } else {
      if (m_log.level() <= MSG::DEBUG)
        m_log << MSG::DEBUG << "getTHists: no such TDirectory \""
              << r2 << "\"" << endmsg;
    }

  } else {
    if (m_log.level() <= MSG::DEBUG)
      m_log << MSG::DEBUG << "getTHists: stream \"" << stream << "\" not found"
            << endmsg;
  }

  if (!gDirectory->cd(dir.c_str())) {
    m_log << MSG::ERROR << "getTHists: No such TDirectory/stream \"" << dir
          << "\"" << endmsg;
    sc = StatusCode::FAILURE;
  } else {
    sc = getTHists(gDirectory,tl,rcs);
  }

  return sc;

}
StatusCode THistSvc::getTHists ( const std::string name,
TList &  tl,
bool  recurse = false,
bool  reg = false 
) [virtual]

Definition at line 680 of file THistSvc.cpp.

                                                                        {

  GlobalDirectoryRestore restore;

  gErrorIgnoreLevel = kBreak;

  StatusCode sc;

  std::string stream,rem,r2;
  parseString(dir,stream,rem);

  map< string,pair<TFile*,Mode> >::const_iterator itr = m_files.find(stream);
  if (itr != m_files.end()) {
    r2 = itr->second.first->GetName();
    r2 += ":/";
    r2 += rem;

    if (m_log.level() <= MSG::DEBUG)
      m_log << MSG::DEBUG << "getTHists: \"" << dir
            << "\" looks like a stream name."  << " associated TFile: \""
            << itr->second.first->GetName() << "\"" << endmsg;

    if (gDirectory->cd(r2.c_str())) {
      m_curstream = stream;
      sc = getTHists(gDirectory,tl,rcs,reg);
      m_curstream = "";
      return sc;
    } else {
      if (m_log.level() <= MSG::DEBUG)
        m_log << MSG::DEBUG << "getTHists: no such TDirectory \""
              << r2 << "\"" << endmsg;
    }

  } else {
    if (m_log.level() <= MSG::DEBUG)
      m_log << MSG::DEBUG << "getTHists: stream \"" << stream << "\" not found"
            << endmsg;
  }

  if (!gDirectory->cd(dir.c_str())) {
    m_log << MSG::ERROR << "getTHists: No such TDirectory/stream \"" << dir
          << "\"" << endmsg;
    sc = StatusCode::FAILURE;
  } else {
    if (reg) {
      m_log << MSG::WARNING << "Unable to register histograms automatically "
            << "without a valid stream name" << endmsg;
      reg = false;
    }
    sc = getTHists(gDirectory,tl,rcs,reg);
  }

  return sc;

}
StatusCode THistSvc::getTHists ( TDirectory *  td,
TList &  tl,
bool  recurse = false,
bool  reg = false 
) [virtual]

Definition at line 606 of file THistSvc.cpp.

                                                                  {

  GlobalDirectoryRestore restore;

  gErrorIgnoreLevel = kBreak;

  if (!td->cd()) {
    m_log << MSG::ERROR << "getTHists: No such TDirectory \"" << td->GetPath()
          << "\"" << endmsg;
    return StatusCode::FAILURE;
  }

  if (m_log.level() <= MSG::DEBUG)
    m_log << MSG::DEBUG << "getTHists: \"" << td->GetPath() << "\": found "
          << td->GetListOfKeys()->GetSize() << " keys" << endmsg;

  TIter nextkey(td->GetListOfKeys());
  while (TKey *key = (TKey*)nextkey()) {
    if (m_log.level() <= MSG::DEBUG)
      m_log << MSG::DEBUG << "  key: " << key->GetName();
    TObject *obj = key->ReadObj();
    if (obj != 0 && obj->IsA()->InheritsFrom("TDirectory")) {
      if (m_log.level() <= MSG::DEBUG)
        m_log << " (" << obj->IsA()->GetName() << ")";
    } else if (obj != 0 && obj->IsA()->InheritsFrom("TH1")) {
      if (m_log.level() <= MSG::DEBUG)
        m_log << " (" << obj->IsA()->GetName() << ")";
      tl.Add(obj);
      if (reg && m_curstream != "") {
        string dir = td->GetPath();
        string fil = td->GetFile()->GetName();
        dir.erase(0,fil.length()+1);
        string id = "/" + m_curstream;
        if ( dir == "/" ) {
          id = id + "/" + key->GetName();
        } else {
          id = id + dir + "/" + key->GetName();
        }
        if (!exists(id)) {
          if (m_log.level() <= MSG::DEBUG)
            m_log << "  reg as \"" << id << "\"";
          regHist(id).ignore();
        } else {
          if (m_log.level() <= MSG::DEBUG)
            m_log << "  already registered";
        }
      }
    } else if (obj != 0) {
      if (m_log.level() <= MSG::DEBUG)
        m_log << " [" << obj->IsA()->GetName() << "]";
    }
    if (m_log.level() <= MSG::DEBUG)
      m_log << endmsg;
  }

  // operate recursively
  if (rcs) {
    nextkey = td->GetListOfKeys();
    while (TKey *key = (TKey*)nextkey()) {
      TObject *obj = key->ReadObj();
      if (obj != 0 && obj->IsA()->InheritsFrom("TDirectory")) {
          TDirectory *tt = dynamic_cast<TDirectory*>(obj);
          getTHists(tt, tl, rcs, reg);
      }
    }
  }

  return StatusCode::SUCCESS;

}
StatusCode THistSvc::getTree ( const std::string name,
TTree *&  hist 
) const [virtual]

Definition at line 1060 of file THistSvc.cpp.

                                                         {
  return getHist_i(id, hist);
}
std::vector< std::string > THistSvc::getTrees (  ) const [virtual]

Definition at line 1067 of file THistSvc.cpp.

                         {

  std::vector<std::string> names;
  names.reserve(m_uids.size());

  uidMap::const_iterator itr;
  for (itr = m_uids.begin(); itr != m_uids.end(); ++itr) {
    THistID tid = itr->second;

    if (tid.obj->IsA()->InheritsFrom("TTree")) {
      names.push_back(itr->first);
    }

  }

  return names;

}
StatusCode THistSvc::getTTrees ( TDirectory *  td,
TList &  tl,
bool  recurse = false 
) const [virtual]

Definition at line 501 of file THistSvc.cpp.

                                                              {
  GlobalDirectoryRestore restore;

  gErrorIgnoreLevel = kBreak;

  if (!td->cd()) {
    m_log << MSG::ERROR << "getTTrees: No such TDirectory \""
          << td->GetPath() << "\"" << endmsg;
    return StatusCode::FAILURE;
  }

  if (m_log.level() <= MSG::DEBUG)
    m_log << MSG::DEBUG << "getTHists: \"" << td->GetPath() << "\": found "
          << td->GetListOfKeys()->GetSize() << " keys" << endmsg;

  TIter nextkey(td->GetListOfKeys());
  while (TKey *key = (TKey*)nextkey()) {
    if (m_log.level() <= MSG::DEBUG)
      m_log << MSG::DEBUG << "  key: " << key->GetName();
    TObject *obj = key->ReadObj();
    if (obj != 0 && obj->IsA()->InheritsFrom("TDirectory")) {
      if (m_log.level() <= MSG::DEBUG)
        m_log << " (" << obj->IsA()->GetName() << ")";
    } else if (obj != 0 && obj->IsA()->InheritsFrom("TTree")) {
      if (m_log.level() <= MSG::DEBUG)
        m_log << " (" << obj->IsA()->GetName() << ")";
      tl.Add(obj);
    } else if (obj != 0) {
      if (m_log.level() <= MSG::DEBUG)
        m_log << " [" << obj->IsA()->GetName() << "]";
    }
    m_log << endmsg;
  }

  // operate recursively
  if (rcs) {
    nextkey = td->GetListOfKeys();
    while (TKey *key = (TKey*)nextkey()) {
      TObject *obj = key->ReadObj();
      if (obj != 0 && obj->IsA()->InheritsFrom("TDirectory")) {
          TDirectory *tt = dynamic_cast<TDirectory*>(obj);
          getTTrees(tt, tl, rcs);
      }
    }
  }

  return StatusCode::SUCCESS;

}
StatusCode THistSvc::getTTrees ( const std::string name,
TList &  tl,
bool  recurse = false 
) const [virtual]

Definition at line 554 of file THistSvc.cpp.

                                                                    {
  GlobalDirectoryRestore restore;

  gErrorIgnoreLevel = kBreak;

  StatusCode sc;

  std::string stream,rem,r2;
  parseString(dir,stream,rem);

  map< string,pair<TFile*,Mode> >::const_iterator itr = m_files.find(stream);
  if (itr != m_files.end()) {
    r2 = itr->second.first->GetName();
    r2 += ":/";
    r2 += rem;

    if (m_log.level() <= MSG::DEBUG)
      m_log << MSG::DEBUG << "getTTrees: \"" << dir
            << "\" looks like a stream name."  << " associated TFile: \""
            << itr->second.first->GetName() << "\"" << endmsg;

    if (gDirectory->cd(r2.c_str())) {
      return getTTrees(gDirectory,tl,rcs);
    } else {
      if (m_log.level() <= MSG::DEBUG)
        m_log << MSG::DEBUG << "getTTrees: no such TDirectory \""
              << r2 << "\"" << endmsg;
    }

  } else {
    if (m_log.level() <= MSG::DEBUG)
      m_log << MSG::DEBUG << "getTTrees: stream \"" << stream << "\" not found"
            << endmsg;
  }

  if (!gDirectory->cd(dir.c_str())) {
    m_log << MSG::ERROR << "getTTrees: No such TDirectory/stream \"" << dir
          << "\"" << endmsg;
    sc = StatusCode::FAILURE;
  } else {
    sc = getTTrees(gDirectory,tl,rcs);
  }

  return sc;


}
StatusCode THistSvc::getTTrees ( const std::string name,
TList &  tl,
bool  recurse = false,
bool  reg = false 
) [virtual]

Definition at line 812 of file THistSvc.cpp.

                                                                        {

  GlobalDirectoryRestore restore;

  gErrorIgnoreLevel = kBreak;

  StatusCode sc;

  std::string stream,rem,r2;
  parseString(dir,stream,rem);

  map< string,pair<TFile*,Mode> >::const_iterator itr = m_files.find(stream);
  if (itr != m_files.end()) {
    r2 = itr->second.first->GetName();
    r2 += ":/";
    r2 += rem;

    if (m_log.level() <= MSG::DEBUG)
      m_log << MSG::DEBUG << "getTTrees: \"" << dir
            << "\" looks like a stream name."  << " associated TFile: \""
            << itr->second.first->GetName() << "\"" << endmsg;

    if (gDirectory->cd(r2.c_str())) {
      return getTTrees(gDirectory,tl,rcs,reg);
    } else {
      if (m_log.level() <= MSG::DEBUG)
        m_log << MSG::DEBUG << "getTTrees: no such TDirectory \""
              << r2 << "\"" << endmsg;
    }

  } else {
    if (m_log.level() <= MSG::DEBUG)
      m_log << MSG::DEBUG << "getTTrees: stream \"" << stream << "\" not found"
            << endmsg;
  }

  if (!gDirectory->cd(dir.c_str())) {
    m_log << MSG::ERROR << "getTTrees: No such TDirectory/stream \"" << dir
          << "\"" << endmsg;
    sc = StatusCode::FAILURE;
  } else {
    sc = getTTrees(gDirectory,tl,rcs,reg);
  }

  return sc;

}
StatusCode THistSvc::getTTrees ( TDirectory *  td,
TList &  tl,
bool  recurse = false,
bool  reg = false 
) [virtual]

Definition at line 738 of file THistSvc.cpp.

                                                                  {

  GlobalDirectoryRestore restore;

  gErrorIgnoreLevel = kBreak;

  if (!td->cd()) {
    m_log << MSG::ERROR << "getTTrees: No such TDirectory \""
          << td->GetPath() << "\"" << endmsg;
    return StatusCode::FAILURE;
  }

  if (m_log.level() <= MSG::DEBUG)
    m_log << MSG::DEBUG << "getTHists: \"" << td->GetPath() << "\": found "
          << td->GetListOfKeys()->GetSize() << " keys" << endmsg;

  TIter nextkey(td->GetListOfKeys());
  while (TKey *key = (TKey*)nextkey()) {
    if (m_log.level() <= MSG::DEBUG)
      m_log << MSG::DEBUG << "  key: " << key->GetName();
    TObject *obj = key->ReadObj();
    if (obj != 0 && obj->IsA()->InheritsFrom("TDirectory")) {
      if (m_log.level() <= MSG::DEBUG)
        m_log << " (" << obj->IsA()->GetName() << ")";
    } else if (obj != 0 && obj->IsA()->InheritsFrom("TTree")) {
      if (m_log.level() <= MSG::DEBUG)
        m_log << " (" << obj->IsA()->GetName() << ")";
      tl.Add(obj);
      if (reg && m_curstream != "") {
        string dir = td->GetPath();
        string fil = td->GetFile()->GetName();
        dir.erase(0,fil.length()+1);
        string id = "/" + m_curstream;
        if ( dir == "/" ) {
          id = id + "/" + key->GetName();
        } else {
          id = id + dir + "/" + key->GetName();
        }
        if (!exists(id)) {
          if (m_log.level() <= MSG::DEBUG)
            m_log << "  reg as \"" << id << "\"";
          regHist(id).ignore();
        } else {
          if (m_log.level() <= MSG::DEBUG)
            m_log << "  already registered";
        }
      }
    } else if (obj != 0) {
      if (m_log.level() <= MSG::DEBUG)
        m_log << " [" << obj->IsA()->GetName() << "]";
    }
    if (m_log.level() <= MSG::DEBUG)
      m_log << endmsg;
  }

  // operate recursively
  if (rcs) {
    nextkey = td->GetListOfKeys();
    while (TKey *key = (TKey*)nextkey()) {
      TObject *obj = key->ReadObj();
      if (obj != 0 && obj->IsA()->InheritsFrom("TDirectory")) {
          TDirectory *tt = dynamic_cast<TDirectory*>(obj);
          getTTrees(tt, tl, rcs, reg);
      }
    }
  }

  return StatusCode::SUCCESS;

}
void THistSvc::handle ( const Incident  )

Definition at line 1861 of file THistSvc.cpp.

                                            {

  if (signaledStop) return ;

  // convert to bytes.
  Long64_t mfs = (Long64_t)m_maxFileSize.value() * (Long64_t)1048576;
  Long64_t mfs_warn = mfs * 95 / 100;

  updateFiles();

  map<string, pair<TFile*,Mode> >::const_iterator itr;
  for (itr=m_files.begin(); itr!= m_files.end(); ++itr) {
    TFile* tf = itr->second.first;

#ifndef NDEBUG
    if (m_log.level() <= MSG::DEBUG)
      m_log << MSG::DEBUG << "stream: " << itr->first << "  name: "
            << tf->GetName() << "  size: " << tf->GetSize()
            << endmsg;
#endif

    // Signal job to terminate if output file is too large
    if (tf->GetSize() > mfs) {

      signaledStop = true;

      m_log << MSG::FATAL << "file \"" << tf->GetName()
            << "\" associated with stream \"" << itr->first
            << "\" has exceeded the max file size of "
            << m_maxFileSize.value() << "MB. Terminating Job."
            << endmsg;

      IEventProcessor* evt(0);
      if (service("ApplicationMgr", evt, true).isSuccess()) {
        evt->stopRun();
        evt->release();
      } else {
        abort();
      }
    } else if (tf->GetSize() > mfs_warn) {
      m_log << MSG::WARNING << "file \"" << tf->GetName()
            << "\" associated with stream \"" << itr->first
            << "\" is at 95% of its maximum allowable file size of "
            << m_maxFileSize.value() << "MB"
            << endmsg;
    }
  }
}
StatusCode THistSvc::initialize (  ) [virtual]

Reimplemented from Service.

Definition at line 69 of file THistSvc.cpp.

                     {
  GlobalDirectoryRestore restore;

  m_alreadyConnectedOutFiles.clear();
  m_alreadyConnectedInFiles.clear();


  // Super ugly hack to make sure we have the OutputLevel set first, so we
  // can see DEBUG printouts in update handlers.
  IJobOptionsSvc* jos(0);
  if( serviceLocator()->service( "JobOptionsSvc", jos, true ).isSuccess() ) {
    const std::vector<const Property*> *props = jos->getProperties( name() );

    if (props != NULL) {
      for ( std::vector<const Property*>::const_iterator cur = props->begin();
            cur != props->end(); cur++) {
        if ( (*cur)->name() == "OutputLevel" ) {
          setProperty( **cur ).ignore();
          m_log.setLevel( m_outputLevel.value() );
          break;
        }
      }
    }
  }


  StatusCode status = Service::initialize();
  m_log.setLevel( m_outputLevel.value() );

  if (status.isFailure()) {
    m_log << MSG::ERROR << "initializing service" << endmsg;
    return status;
  }

  vector<string>::const_iterator itr;
  StatusCode st(StatusCode::SUCCESS);

  try {
    setupOutputFile( m_outputfile );
  } catch ( GaudiException& err ) {
    m_log << MSG::ERROR
          << "Caught: " << err << endmsg;
    st = StatusCode::FAILURE;
  }

  try {
    setupInputFile( m_inputfile );
  } catch ( GaudiException& err ) {
    m_log << MSG::ERROR
          << "Caught: " << err << endmsg;
    st = StatusCode::FAILURE;
  }

  // Protect against multiple instances of TROOT
  if ( 0 == gROOT )   {
    static TROOT root("root","ROOT I/O");
    //    gDebug = 99;
  } else {
    if (m_log.level() <= MSG::VERBOSE)
      m_log << MSG::VERBOSE << "ROOT already initialized, debug = "
            << gDebug<< endmsg;
  }

  IIncidentSvc* p_incSvc(0);

  if (service("IncidentSvc", p_incSvc, true).isFailure()) {
    m_log << MSG::ERROR << "unable to get the IncidentSvc" << endmsg;
    st = StatusCode::FAILURE;
  } else {
    p_incSvc->addListener( this, "EndEvent", 100, true);
  }

  if (st.isFailure()) {
    m_log << MSG::FATAL << "Unable to initialize THistSvc" << endmsg;
  }

  return st;

}
void THistSvc::MergeRootFile ( TDirectory *  target,
TDirectory *  source 
) [private]

Definition at line 1775 of file THistSvc.cpp.

                                                                   {

  if (m_log.level() <= MSG::DEBUG)
    m_log <<MSG::DEBUG << "Target path: " << target->GetPath() << endmsg;
  TString path( (char*)strstr(target->GetPath(), ":") );
  path.Remove( 0, 2);

  source->cd(path);
  TDirectory *current_sourcedir = gDirectory;

  // loop over all keys in this directory
  TList *lkeys=current_sourcedir->GetListOfKeys();
  int nkeys=lkeys->GetEntries();
  TKey *key;
  for (int jj=0; jj<nkeys; jj++) {
    key=(TKey*) lkeys->At(jj);
    string pathnameinsource=current_sourcedir->GetPath()+string("/")+key->GetName();
    if (m_log.level() <= MSG::DEBUG)
      m_log <<MSG::DEBUG << "Reading Key:" << pathnameinsource << endmsg;
    //key->Dump();
    //TObject *obj=key->ReadObj();
    TObject *obj=source->Get(pathnameinsource.c_str());

    if (obj->IsA()->InheritsFrom("TDirectory") ) {
      // it's a subdirectory

      if (m_log.level() <= MSG::DEBUG)
        m_log <<MSG::DEBUG << "Found subdirectory " << obj->GetName()
              << endmsg;

      // create a new subdir of same name and title in the target file
      target->cd();
      TDirectory *newtargetdir =
        target->mkdir(obj->GetName(), obj->GetTitle() );

      MergeRootFile(newtargetdir, source);

    } else if (obj->IsA()->InheritsFrom("TTree")) {
      if (m_log.level() <= MSG::DEBUG)
        m_log <<MSG::DEBUG << "Found TTree " << obj->GetName() << endmsg;
      TTree *mytree=dynamic_cast<TTree*>(obj);
      int nentries=(int) mytree->GetEntries();
      mytree->SetBranchStatus("*",1);

      if (m_log.level() <= MSG::DEBUG)
        m_log <<MSG::DEBUG << "Dumping TTree " << nentries <<" entries"
              << endmsg;
      //mytree->Print();
      //for (int ij=0; ij<nentries; ij++) {
      //m_log <<MSG::DEBUG << "Dumping TTree Show( " << ij <<" )"
      //<< endmsg;
      //mytree->Show(ij);
      //}
      target->cd();
      mytree->CloneTree();

      //m_log <<MSG::DEBUG << "Writing TTree to target file: ( "
      //<< mycopiedtree->Write(key->GetName()) <<" ) bytes written"
      //<< endmsg;

    } else if (obj) {
      target->cd();
      obj->Write(key->GetName() );
    }

  } // while ( ( TKey *key = (TKey*)nextkey() ) )

  // save modifications to target file

}
void THistSvc::parseString ( const std::string id,
std::string root,
std::string rem 
) const [private]

Definition at line 1191 of file THistSvc.cpp.

                                                                       {
  string::size_type pos = id.find("/");

  if (pos == string::npos) {
    root = "";
    rem = id;
    return;
  }

  if (pos == 0) {
    parseString(id.substr(1,id.length()),root,rem);
  } else {
    root = id.substr(0,pos);
    rem = id.substr(pos+1,id.length());
  }

}
StatusCode THistSvc::readHist ( const std::string name,
TH1 *&  hist 
) const [private]

Definition at line 1116 of file THistSvc.cpp.

                                                        {
  return readHist_i(id, hist);
}
StatusCode THistSvc::readHist ( const std::string name,
TH2 *&  hist 
) const [private]

Definition at line 1123 of file THistSvc.cpp.

                                                        {
  return readHist_i(id, hist);
}
StatusCode THistSvc::readHist ( const std::string name,
TH3 *&  hist 
) const [private]

Definition at line 1130 of file THistSvc.cpp.

                                                        {
  return readHist_i(id, hist);
}
template<typename T >
StatusCode THistSvc::readHist_i ( const std::string name,
T *&  hist 
) const [private]
StatusCode THistSvc::readTree ( const std::string name,
TTree *&  hist 
) const [private]

Definition at line 1137 of file THistSvc.cpp.

                                                          {
  return readHist_i(id, hist);
}
StatusCode THistSvc::regGraph ( const std::string name,
TGraph *  hist 
) [virtual]

Definition at line 998 of file THistSvc.cpp.

                                                    {
  if ( strcmp(hist->GetName(),"Graph") == 0 ) {

    std::string id2(id);
    string::size_type i = id2.rfind("/");
    if (i != string::npos) {
      id2.erase(0,i+1);
    }

    m_log << MSG::INFO << "setting name of TGraph id: \"" << id << "\" to \""
          << id2 << "\" since it is unset" << endmsg;
    hist->SetName(id2.c_str());
  }

  return regHist_i(hist, id);
}
StatusCode THistSvc::regGraph ( const std::string name ) [virtual]

Definition at line 990 of file THistSvc.cpp.

                                      {
  TGraph *hist(0);
  return regHist_i(hist, id);
}
StatusCode THistSvc::regHist ( const std::string name,
TH1 *  hist 
) [virtual]

Definition at line 948 of file THistSvc.cpp.

                                                {
  return regHist_i(hist, id);
}
StatusCode THistSvc::regHist ( const std::string name ) [virtual]

Definition at line 938 of file THistSvc.cpp.

                                     {

  TH1 *hist(0);

  return regHist_i(hist, id);
}
StatusCode THistSvc::regHist ( const std::string name,
TH2 *  hist 
) [virtual]

Definition at line 955 of file THistSvc.cpp.

                                                {
  return regHist_i(hist, id);
}
StatusCode THistSvc::regHist ( const std::string name,
TH3 *  hist 
) [virtual]

Definition at line 962 of file THistSvc.cpp.

                                                {
  return regHist_i(hist, id);
}
template<typename T >
StatusCode THistSvc::regHist_i ( T *  hist,
const std::string name 
) [private]
StatusCode THistSvc::regTree ( const std::string name ) [virtual]

Definition at line 969 of file THistSvc.cpp.

                                     {
  TTree *hist(0);
  return regHist_i(hist, id);
}
StatusCode THistSvc::regTree ( const std::string name,
TTree *  hist 
) [virtual]

Definition at line 977 of file THistSvc.cpp.

                                                  {
  StatusCode sc = regHist_i(hist, id);
  if (hist != 0 && sc.isSuccess()) {
    if (m_autoSave != 0) 
      hist->SetAutoSave(m_autoSave);
    hist->SetAutoFlush(m_autoFlush);
  }
  return sc;
}
StatusCode THistSvc::reinitialize (  ) [virtual]

Reimplemented from Service.

Definition at line 152 of file THistSvc.cpp.

                       {

  GlobalDirectoryRestore restore;

  m_log << MSG::WARNING << "reinitialize not implemented" << endmsg;


  return StatusCode::SUCCESS;

}
void THistSvc::removeDoubleSlash ( std::string id ) const [private]

Definition at line 1765 of file THistSvc.cpp.

                                               {

  while (id.find("//") != std::string::npos) {
    id.replace(id.find("//"),2,"/");
  }

}
void THistSvc::setupCompressionLevel ( Property cmp ) [private]

Definition at line 1212 of file THistSvc.cpp.

{

  m_log << MSG::WARNING << "\"CompressionLevel\" Property has been deprecated. "
        << "Set it via the \"CL=\" parameter in the \"Output\" Property"
        << endmsg;

}
void THistSvc::setupInputFile ( Property inputfile ) [private]

call-back method to handle input stream property

Definition at line 1225 of file THistSvc.cpp.

{
  StatusCode sc = StatusCode::SUCCESS;

  typedef std::vector<std::string> Strings_t;
  for ( Strings_t::const_iterator
          itr  = m_inputfile.value().begin(),
          iEnd = m_inputfile.value().end();
        itr != iEnd;
        ++itr ) {
    if ( m_alreadyConnectedInFiles.end() ==
         m_alreadyConnectedInFiles.find( *itr ) ) {
      if ( connect(*itr).isFailure() ) {
        sc = StatusCode::FAILURE;
      } else {
        m_alreadyConnectedInFiles.insert( *itr );
      }
    }
  }

  if ( !sc.isSuccess() ) {
    throw GaudiException( "Problem connecting inputfile !!", name(),
                          StatusCode::FAILURE );
  }
  return;
}
void THistSvc::setupOutputFile ( Property outputfile ) [private]

call-back method to handle output stream property

Definition at line 1255 of file THistSvc.cpp.

{
  StatusCode sc = StatusCode::SUCCESS;

  typedef std::vector<std::string> Strings_t;
  for ( Strings_t::const_iterator
          itr  = m_outputfile.value().begin(),
          iEnd = m_outputfile.value().end();
        itr != iEnd;
        ++itr ) {
    if ( m_alreadyConnectedOutFiles.end() ==
         m_alreadyConnectedOutFiles.find( *itr ) ) {
      if ( connect(*itr).isFailure() ) {
        sc = StatusCode::FAILURE;
      } else {
        m_alreadyConnectedOutFiles.insert( *itr );
      }
    }
  }

  if ( !sc.isSuccess() ) {
    throw GaudiException( "Problem connecting outputfile !!", name(),
                          StatusCode::FAILURE );
  }
  return;
}
void THistSvc::updateFiles (  ) [private]

Definition at line 1285 of file THistSvc.cpp.

                      {

  // If TTrees grow beyond TTree::fgMaxFileSize, a new file is
  // automatically created by root, and the old one closed. We
  // need to migrate all the UIDs over to show the correct file
  // pointer. This is ugly.

  uidMap::iterator uitr, uitr2;
  for (uitr=m_uids.begin(); uitr != m_uids.end(); ++uitr) {
    TObject* to = uitr->second.obj;
    TFile* oldFile = uitr->second.file;
    if (to->IsA()->InheritsFrom("TTree")) {
      TTree* tr = dynamic_cast<TTree*>(to);
      TFile* newFile = tr->GetCurrentFile();

      if (oldFile != newFile) {
        std::string newFileName = newFile->GetName();
        std::string oldFileName(""), streamName, rem;
        TFile* dummy;
        findStream(uitr->second.id, streamName, rem, dummy);

        map<string, pair<TFile*,Mode> >::iterator itr;
        for (itr=m_files.begin(); itr!= m_files.end(); ++itr) {
          if (itr->second.first == oldFile) {
            itr->second.first = newFile;

          }
        }

        uitr2 = uitr;
        for (; uitr2 != m_uids.end(); ++uitr2) {
          if (uitr2->second.file == oldFile) {
            uitr2->second.file = newFile;
          }
        }

        streamMap::iterator sitr;
        for (sitr = m_fileStreams.begin(); sitr!=m_fileStreams.end(); ++sitr) {
          if (sitr->second == streamName) {
            oldFileName = sitr->first;
            break;
          }
        }


#ifndef NDEBUG
      if (m_log.level() <= MSG::DEBUG)
        m_log << MSG::DEBUG << "migrating uid: " << uitr->second.id
              << "   stream: " << streamName
              << "   oldFile: " << oldFileName
              << "   newFile: " << newFileName
              << endmsg;
#endif


        if (oldFileName != "") {
          while ( (sitr=m_fileStreams.find(oldFileName)) != m_fileStreams.end() ) {

#ifndef NDEBUG
            if (m_log.level() <= MSG::DEBUG)
              m_log << MSG::DEBUG << "changing filename \"" << oldFileName
                    << "\" to \"" << newFileName << "\" for stream \""
                    << sitr->second << "\"" << endmsg;
#endif
            m_fileStreams.erase(sitr);
            m_fileStreams.insert( make_pair<std::string,std::string>(newFileName,streamName) );
          }


        } else {
          m_log << MSG::ERROR
                << "Problems updating fileStreams with new file name" << endmsg;
        }

      }

    }
  }

}
StatusCode THistSvc::write (  ) [private]

Definition at line 1369 of file THistSvc.cpp.

                {

  updateFiles();

  map<string, pair<TFile*,Mode> >::const_iterator itr;
  for (itr=m_files.begin(); itr!= m_files.end(); ++itr) {
    if (itr->second.second == WRITE || itr->second.second == UPDATE
        ||itr->second.second==SHARE) {
      itr->second.first->Write("",TObject::kOverwrite);
    } else if (itr->second.second == APPEND) {
      itr->second.first->Write("");
    }
  }


  if (m_log.level() <= MSG::DEBUG)
    m_log << MSG::DEBUG << "THistSvc::write()::List of Files connected in ROOT "
          << endmsg;

  TSeqCollection *filelist=gROOT->GetListOfFiles();
  for (int ii=0; ii<filelist->GetEntries(); ii++) {
    if (m_log.level() <= MSG::DEBUG)
      m_log << MSG::DEBUG
            << "THistSvc::write()::List of Files connected in ROOT: \""
            << filelist->At(ii)->GetName()<<"\""<<endmsg;
  }

  return StatusCode::SUCCESS;

}

Member Data Documentation

list of already connected files.

This is to keep track of files registered by the setupInputFile callback method

Definition at line 175 of file THistSvc.h.

list of already connected files.

This is to keep track of files registered by the setupOutputFile callback method

Definition at line 179 of file THistSvc.h.

Definition at line 170 of file THistSvc.h.

Definition at line 170 of file THistSvc.h.

Definition at line 170 of file THistSvc.h.

std::string THistSvc::m_curstream [mutable, private]

Definition at line 195 of file THistSvc.h.

Definition at line 187 of file THistSvc.h.

Definition at line 188 of file THistSvc.h.

Definition at line 184 of file THistSvc.h.

Definition at line 168 of file THistSvc.h.

MsgStream THistSvc::m_log [mutable, private]

Definition at line 126 of file THistSvc.h.

Definition at line 170 of file THistSvc.h.

Definition at line 168 of file THistSvc.h.

Definition at line 171 of file THistSvc.h.

Definition at line 169 of file THistSvc.h.

Definition at line 190 of file THistSvc.h.

Definition at line 185 of file THistSvc.h.

Definition at line 183 of file THistSvc.h.

Definition at line 169 of file THistSvc.h.

bool THistSvc::signaledStop [private]

Definition at line 193 of file THistSvc.h.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines

Generated at Tue May 10 2011 18:55:12 for Gaudi Framework, version v22r2 by Doxygen version 1.7.2 written by Dimitri van Heesch, © 1997-2004