19#include <boost/algorithm/string/case_conv.hpp> 
   23#include <TDirectory.h> 
   59  template <
typename InputIterator, 
typename OutputIterator, 
typename UnaryOperation, 
typename UnaryPredicate>
 
   60  OutputIterator transform_if( InputIterator first, InputIterator last, OutputIterator result, UnaryOperation op,
 
   61                               UnaryPredicate pred ) {
 
   62    while ( first != last ) {
 
   63      if ( pred( *first ) ) *result++ = op( *first );
 
   69  constexpr struct select1st_t {
 
   70    template <
typename T, 
typename S>
 
   71    const T& operator()( 
const std::pair<T, S>& p )
 const {
 
  110    static TROOT root( 
"root", 
"ROOT I/O" );
 
  116  if ( 
p_incSvc.retrieve().isFailure() ) {
 
  117    error() << 
"unable to get the IncidentSvc" << 
endmsg;
 
  120    p_incSvc->addListener( 
this, 
"EndEvent", 100, 
true );
 
  123  if ( 
p_fileMgr.retrieve().isFailure() ) {
 
  131  using namespace std::placeholders;
 
  134    error() << 
"unable to register ROOT file open action with FileMgr" << 
endmsg;
 
  136  auto bea = [
this]( 
const Io::FileAttr* fa, 
const std::string& caller ) {
 
  140    error() << 
"unable to register ROOT file open Error action with FileMgr" << 
endmsg;
 
  154    error() << 
"unable to get the IoComponentMgr" << 
endmsg;
 
  157    if ( !iomgr->io_register( 
this ).isSuccess() ) {
 
  158      error() << 
"could not register with the I/O component manager !" << 
endmsg;
 
  161      bool all_good = 
true;
 
  163      for ( 
const auto& reg : 
m_files ) {
 
  164        const std::string&                  fname = reg.second.first->GetName();
 
  167        if ( !iomgr->io_register( 
this, iomode, fname ).isSuccess() ) {
 
  168          warning() << 
"could not register file [" << fname << 
"] with the I/O component manager..." << 
endmsg;
 
  171          info() << 
"registered file [" << fname << 
"]... [ok]" << 
endmsg;
 
  175        error() << 
"problem while registering input/output files with " 
  176                << 
"the I/O component manager !" << 
endmsg;
 
 
  203    const std::map<uidMap_t::key_type, uidMap_t::mapped_type> sorted_uids{ begin( 
m_uids ), end( 
m_uids ) };
 
  204    for ( 
const auto& itr : sorted_uids ) {
 
  205      THistID& thid = itr.second->at( 0 );
 
  206      TObject* tobj = thid.
obj;
 
  208      std::string dirname( 
"none" );
 
  210        TTree* tree = 
dynamic_cast<TTree*
>( tobj );
 
  211        if ( tree->GetDirectory() != 0 ) { dirname = tree->GetDirectory()->GetPath(); }
 
  214          dirname = thid.
file->GetPath();
 
  215          std::string id2( thid.
id );
 
  216          id2.erase( 0, id2.find( 
"/", 1 ) );
 
  217          id2.erase( id2.rfind( 
"/" ), id2.length() );
 
  218          if ( id2.starts_with( 
"/" ) ) { id2.erase( 0, 1 ); }
 
  224        TH1* th = 
dynamic_cast<TH1*
>( tobj );
 
  225        if ( th == 
nullptr ) {
 
  226          error() << 
"Couldn't dcast: " << itr.first << 
endmsg;
 
  228          if ( th->GetDirectory() != 0 ) { dirname = th->GetDirectory()->GetPath(); }
 
  230      } 
else if ( !tobj ) {
 
  241  std::vector<TFile*> deleted_files;
 
  243    if ( std::find( deleted_files.begin(), deleted_files.end(), itr.second.first ) == deleted_files.end() ) {
 
  244      deleted_files.push_back( itr.second.first );
 
  248        debug() << 
"finalizing stream/file " << itr.first << 
":" << itr.second.first->GetName() << 
endmsg;
 
  259      info() << 
"==> File: " << itr.second.first->GetName() << 
"  stream: " << itr.first << 
endmsg;
 
  261      itr.second.first->Print( 
"base" );
 
  264    std::string tmpfn = itr.second.first->GetName();
 
  268    if ( itr.second.second == 
SHARE ) {
 
  270      void* vfile = 
nullptr;
 
  279      TFile* outputfile = (TFile*)vfile;
 
  288        error() << 
"unable to open temporary file: \"" << tmpfn << 
endmsg;
 
  292      TFile* inputfile = (TFile*)vfile;
 
  294      outputfile->SetCompressionLevel( inputfile->GetCompressionLevel() );
 
  304      std::remove( tmpfn.c_str() );
 
  306    delete itr.second.first;
 
  319    if ( obj.second.second == 0 ) {
 
  320      delete obj.second.first; 
 
 
  331  std::unique_ptr<TH1> hist = 
nullptr;
 
  332  return regHist_i( std::move( hist ), 
id, 
false );
 
 
  336  return regHist_i( std::move( hist ), 
id, 
false );
 
 
  340  std::unique_ptr<TH1> hist( hist_ptr );
 
  341  return regHist_i( std::move( hist ), 
id, 
false );
 
 
  346  if ( hist != 
nullptr ) {
 
 
  355  if ( hist != 
nullptr ) {
 
 
  364  if ( hist != 
nullptr ) {
 
 
  372  std::unique_ptr<TTree> tree = 
nullptr;
 
  373  return regHist_i( std::move( tree ), 
id, 
false );
 
 
  387  std::unique_ptr<TTree> tree( tree_ptr );
 
 
  399  if ( tree != 
nullptr ) {
 
 
  407  std::unique_ptr<TGraph> graph = std::make_unique<TGraph>();
 
  408  return regHist_i( std::move( graph ), 
id, 
false );
 
 
  412  if ( strcmp( graph->GetName(), 
"Graph" ) == 0 ) {
 
  413    std::string            id2( 
id );
 
  414    std::string::size_type i = id2.rfind( 
"/" );
 
  415    if ( i != std::string::npos ) { id2.erase( 0, i + 1 ); }
 
  417    info() << 
"setting name of TGraph id: \"" << 
id << 
"\" to \"" << id2 << 
"\" since it is unset" << 
endmsg;
 
  418    graph->SetName( id2.c_str() );
 
  421  return regHist_i( std::move( graph ), 
id, 
false );
 
 
  425  std::unique_ptr<TGraph> graph( graph_ptr );
 
  426  if ( strcmp( graph->GetName(), 
"Graph" ) == 0 ) {
 
  427    std::string            id2( 
id );
 
  428    std::string::size_type i = id2.rfind( 
"/" );
 
  429    if ( i != std::string::npos ) { id2.erase( 0, i + 1 ); }
 
  431    info() << 
"setting name of TGraph id: \"" << 
id << 
"\" to \"" << id2 << 
"\" since it is unset" << 
endmsg;
 
  432    graph->SetName( id2.c_str() );
 
  435  return regHist_i( std::move( graph ), 
id, 
false );
 
 
  440  if ( graph != 
nullptr ) {
 
 
  448  std::unique_ptr<TEfficiency> eff = 
nullptr;
 
  449  return regHist_i( std::move( eff ), 
id, 
false );
 
 
  453  return regHist_i( std::move( eff ), 
id, 
false );
 
 
  457  std::unique_ptr<TEfficiency> eff( eff_ptr );
 
  458  return regHist_i( std::move( eff ), 
id, 
false );
 
 
  463  if ( eff != 
nullptr ) {
 
 
  562  auto itr = 
m_uids.find( 
id );
 
  563  if ( itr == 
m_uids.end() ) {
 
  564    error() << 
"Problem deregistering id \"" << 
id << 
"\": not found in registry" << 
endmsg;
 
  571    debug() << 
"will deregister " << vh->size() << 
" elements of id \"" << 
id << 
"\"" << 
endmsg;
 
  575  size_t vh_size = vh->size();
 
  576  while ( vh_size-- ) {
 
  579      error() << 
"Problems deRegistering " << vh->size() << 
" element of id \"" << 
id << 
"\"" << 
endmsg;
 
 
  588  objMap_t::iterator obj_itr = 
m_tobjs.find( obj );
 
  589  if ( obj_itr != 
m_tobjs.end() ) {
 
  590    vhid_t* vhid = obj_itr->second.first;
 
  591    THistID hid  = obj_itr->second.first->at( obj_itr->second.second );
 
  593    auto uid_itr = 
m_uids.find( hid.
id );
 
  594    if ( uid_itr == 
m_uids.end() ) {
 
  595      error() << 
"Problems deregistering TObject \"" << obj->GetName() << 
"\" with id \"" << hid.
id 
  596              << 
"\": not in uidMap" << 
endmsg;
 
  600    if ( vhid->size() == 1 ) {
 
  604      std::string root, rem;
 
  607      auto mitr   = 
m_ids.equal_range( rem );
 
  608      auto id_itr = std::find_if( mitr.first, mitr.second,
 
  609                                  [&]( idMap_t::const_reference i ) { return i.second->at( 0 ).obj == obj; } );
 
  610      if ( id_itr == mitr.second ) {
 
  611        error() << 
"Problems deregistering TObject \"" << obj->GetName() << 
"\" with id \"" << hid.
id 
  612                << 
"\": not in idMap" << 
endmsg;
 
  616      auto hlist_itr = std::find( 
m_hlist.begin(), 
m_hlist.end(), vhid );
 
  617      if ( hlist_itr == 
m_hlist.end() ) {
 
  618        error() << 
"Problems deregistering TObject \"" << obj->GetName() << 
"\" with id \"" << hid.
id 
  619                << 
"\": not in hlist" << 
endmsg;
 
  623      vhid->erase( vhid->begin() + obj_itr->second.second );
 
  627      m_ids.erase( id_itr );
 
  632    } 
else if ( vhid->size() > 1 ) {
 
  633      vhid->erase( vhid->begin() + obj_itr->second.second );
 
  638      error() << 
"Deregistration failed unexpectedly. (bug in THistSvc?)" << 
endmsg;
 
  642    error() << 
"Cannot unregister TObject \"" << obj->GetName() << 
"\": not known to THistSvc" << 
endmsg;
 
 
  649  if ( itr == 
m_uids.end() ) {
 
  654  return merge( itr->second );
 
 
  658  objMap_t::iterator itr = 
m_tobjs.find( obj );
 
  660    return merge( itr->second.first );
 
  662    error() << 
"merge: unknown object " << obj << 
endmsg;
 
 
  682  std::vector<std::string> names;
 
  683  names.reserve( 
m_uids.size() );
 
  684  transform_if( std::begin( 
m_uids ), std::end( 
m_uids ), std::back_inserter( names ), select1st,
 
  685                []( uidMap_t::const_reference i ) { 
return i.second->at( 0 ).type == 
ObjectType::TH1; } );
 
 
  690  std::vector<std::string> names;
 
  691  names.reserve( 
m_uids.size() );
 
  692  transform_if( std::begin( 
m_uids ), std::end( 
m_uids ), std::back_inserter( names ), select1st,
 
  693                []( uidMap_t::const_reference i ) { 
return i.second->at( 0 ).type == 
ObjectType::TTREE; } );
 
 
  698  std::vector<std::string> names;
 
  699  names.reserve( 
m_uids.size() );
 
  700  transform_if( std::begin( 
m_uids ), std::end( 
m_uids ), std::back_inserter( names ), select1st,
 
  701                []( uidMap_t::const_reference i ) { 
return i.second->at( 0 ).type == 
ObjectType::TGRAPH; } );
 
 
  706  std::vector<std::string> names;
 
  707  names.reserve( 
m_uids.size() );
 
  708  transform_if( std::begin( 
m_uids ), std::end( 
m_uids ), std::back_inserter( names ), select1st,
 
 
  716  gErrorIgnoreLevel = kBreak;
 
  719    error() << 
"getTHists: No such TDirectory \"" << td->GetPath() << 
"\"" << 
endmsg;
 
  724    debug() << 
"getTHists: \"" << td->GetPath() << 
"\": found " << td->GetListOfKeys()->GetSize() << 
" keys" << 
endmsg;
 
  727  TIter nextkey( td->GetListOfKeys() );
 
  728  while ( TKey* key = (TKey*)nextkey() ) {
 
  731    TObject* obj = key->ReadObj();
 
  732    if ( obj != 0 && obj->IsA()->InheritsFrom( 
"TDirectory" ) ) {
 
  734    } 
else if ( obj != 0 && obj->IsA()->InheritsFrom( 
"TH1" ) ) {
 
  737    } 
else if ( obj != 0 ) {
 
  745    nextkey = td->GetListOfKeys();
 
  746    while ( TKey* key = (TKey*)nextkey() ) {
 
  747      TObject* obj = key->ReadObj();
 
  748      if ( obj && obj->IsA()->InheritsFrom( 
"TDirectory" ) ) {
 
  749        TDirectory* tt = 
dynamic_cast<TDirectory*
>( obj );
 
 
  762  gErrorIgnoreLevel = kBreak;
 
  766  std::string stream, rem, r2;
 
  769  auto itr = 
m_files.find( stream );
 
  771    r2 = itr->second.first->GetName();
 
  776      debug() << 
"getTHists: \"" << dir << 
"\" looks like a stream name." 
  777              << 
" associated TFile: \"" << itr->second.first->GetName() << 
"\"" << 
endmsg;
 
  780    if ( gDirectory->cd( r2.c_str() ) ) {
 
  793  if ( !gDirectory->cd( dir.c_str() ) ) {
 
  794    error() << 
"getTHists: No such TDirectory/stream \"" << dir << 
"\"" << 
endmsg;
 
 
  806  gErrorIgnoreLevel = kBreak;
 
  809    error() << 
"getTHists: No such TDirectory \"" << td->GetPath() << 
"\"" << 
endmsg;
 
  814    debug() << 
"getTHists: \"" << td->GetPath() << 
"\": found " << td->GetListOfKeys()->GetSize() << 
" keys" << 
endmsg;
 
  817  TIter nextkey( td->GetListOfKeys() );
 
  818  while ( TKey* key = (TKey*)nextkey() ) {
 
  821    TObject* obj = key->ReadObj();
 
  822    if ( obj && obj->IsA()->InheritsFrom( 
"TDirectory" ) ) {
 
  824    } 
else if ( obj && obj->IsA()->InheritsFrom( 
"TH1" ) ) {
 
  828        std::string dir = td->GetPath();
 
  829        std::string fil = td->GetFile()->GetName();
 
  830        dir.erase( 0, fil.length() + 1 );
 
  833          id = 
id + 
"/" + key->GetName();
 
  835          id = 
id + dir + 
"/" + key->GetName();
 
  852    nextkey = td->GetListOfKeys();
 
  853    while ( TKey* key = (TKey*)nextkey() ) {
 
  854      TObject* obj = key->ReadObj();
 
  855      if ( obj && obj->IsA()->InheritsFrom( 
"TDirectory" ) ) {
 
  856        TDirectory* tt = 
dynamic_cast<TDirectory*
>( obj );
 
 
  868  gErrorIgnoreLevel = kBreak;
 
  872  std::string stream, rem, r2;
 
  875  auto itr = 
m_files.find( stream );
 
  877    r2 = itr->second.first->GetName();
 
  882      debug() << 
"getTHists: \"" << dir << 
"\" looks like a stream name." 
  883              << 
" associated TFile: \"" << itr->second.first->GetName() << 
"\"" << 
endmsg;
 
  886    if ( gDirectory->cd( r2.c_str() ) ) {
 
  888      sc          = 
getTHists( gDirectory, tl, rcs, reg );
 
  897  if ( !gDirectory->cd( dir.c_str() ) ) {
 
  898    error() << 
"getTHists: No such TDirectory/stream \"" << dir << 
"\"" << 
endmsg;
 
  902      warning() << 
"Unable to register histograms automatically " 
  903                << 
"without a valid stream name" << 
endmsg;
 
  906    sc = 
getTHists( gDirectory, tl, rcs, reg );
 
 
  915  gErrorIgnoreLevel = kBreak;
 
  918    error() << 
"getTTrees: No such TDirectory \"" << td->GetPath() << 
"\"" << 
endmsg;
 
  923    debug() << 
"getTHists: \"" << td->GetPath() << 
"\": found " << td->GetListOfKeys()->GetSize() << 
" keys" << 
endmsg;
 
  926  TIter nextkey( td->GetListOfKeys() );
 
  927  while ( TKey* key = (TKey*)nextkey() ) {
 
  930    TObject* obj = key->ReadObj();
 
  931    if ( obj != 0 && obj->IsA()->InheritsFrom( 
"TDirectory" ) ) {
 
  933    } 
else if ( obj != 0 && obj->IsA()->InheritsFrom( 
"TTree" ) ) {
 
  936    } 
else if ( obj != 0 ) {
 
  944    nextkey = td->GetListOfKeys();
 
  945    while ( TKey* key = (TKey*)nextkey() ) {
 
  946      TObject* obj = key->ReadObj();
 
  947      if ( obj && obj->IsA()->InheritsFrom( 
"TDirectory" ) ) {
 
  948        TDirectory* tt = 
dynamic_cast<TDirectory*
>( obj );
 
 
  960  gErrorIgnoreLevel = kBreak;
 
  964  std::string stream, rem, r2;
 
  967  auto itr = 
m_files.find( stream );
 
  969    r2 = itr->second.first->GetName();
 
  974      debug() << 
"getTTrees: \"" << dir << 
"\" looks like a stream name." 
  975              << 
" associated TFile: \"" << itr->second.first->GetName() << 
"\"" << 
endmsg;
 
  978    if ( gDirectory->cd( r2.c_str() ) ) { 
return getTTrees( gDirectory, tl, rcs ); }
 
  984  if ( !gDirectory->cd( dir.c_str() ) ) {
 
  985    error() << 
"getTTrees: No such TDirectory/stream \"" << dir << 
"\"" << 
endmsg;
 
 
  996  gErrorIgnoreLevel = kBreak;
 
  999    error() << 
"getTTrees: No such TDirectory \"" << td->GetPath() << 
"\"" << 
endmsg;
 
 1004    debug() << 
"getTHists: \"" << td->GetPath() << 
"\": found " << td->GetListOfKeys()->GetSize() << 
" keys" << 
endmsg;
 
 1007  TIter nextkey( td->GetListOfKeys() );
 
 1008  while ( TKey* key = (TKey*)nextkey() ) {
 
 1009    auto& log = 
debug();
 
 1011    TObject* obj = key->ReadObj();
 
 1012    if ( obj && obj->IsA()->InheritsFrom( 
"TDirectory" ) ) {
 
 1014    } 
else if ( obj && obj->IsA()->InheritsFrom( 
"TTree" ) ) {
 
 1018        std::string dir = td->GetPath();
 
 1019        std::string fil = td->GetFile()->GetName();
 
 1020        dir.erase( 0, fil.length() + 1 );
 
 1023          id = 
id + 
"/" + key->GetName();
 
 1025          id = 
id + dir + 
"/" + key->GetName();
 
 1034    } 
else if ( obj != 0 ) {
 
 1042    nextkey = td->GetListOfKeys();
 
 1043    while ( TKey* key = (TKey*)nextkey() ) {
 
 1044      TObject* obj = key->ReadObj();
 
 1045      if ( obj && obj->IsA()->InheritsFrom( 
"TDirectory" ) ) {
 
 1046        TDirectory* tt = 
dynamic_cast<TDirectory*
>( obj );
 
 
 1058  gErrorIgnoreLevel = kBreak;
 
 1062  std::string stream, rem, r2;
 
 1065  auto itr = 
m_files.find( stream );
 
 1067    r2 = itr->second.first->GetName();
 
 1072      debug() << 
"getTTrees: \"" << dir << 
"\" looks like a stream name." 
 1073              << 
" associated TFile: \"" << itr->second.first->GetName() << 
"\"" << 
endmsg;
 
 1076    if ( gDirectory->cd( r2.c_str() ) ) {
 
 1077      return getTTrees( gDirectory, tl, rcs, reg );
 
 1085  if ( !gDirectory->cd( dir.c_str() ) ) {
 
 1086    error() << 
"getTTrees: No such TDirectory/stream \"" << dir << 
"\"" << 
endmsg;
 
 1090  return getTTrees( gDirectory, tl, rcs, reg );
 
 
 1096  gErrorIgnoreLevel = kBreak;
 
 1099    error() << 
"getTEfficiencies: No such TDirectory \"" << td->GetPath() << 
"\"" << 
endmsg;
 
 1104    debug() << 
"getTEfficiencies: \"" << td->GetPath() << 
"\": found " << td->GetListOfKeys()->GetSize() << 
" keys" 
 1108  TIter nextkey( td->GetListOfKeys() );
 
 1109  while ( TKey* key = (TKey*)nextkey() ) {
 
 1110    auto& log = 
debug();
 
 1112    TObject* obj = key->ReadObj();
 
 1113    if ( obj != 0 && obj->IsA()->InheritsFrom( 
"TDirectory" ) ) {
 
 1115    } 
else if ( obj != 0 && obj->IsA()->InheritsFrom( 
"TEfficiency" ) ) {
 
 1118    } 
else if ( obj != 0 ) {
 
 1126    nextkey = td->GetListOfKeys();
 
 1127    while ( TKey* key = (TKey*)nextkey() ) {
 
 1128      TObject* obj = key->ReadObj();
 
 1129      if ( obj && obj->IsA()->InheritsFrom( 
"TDirectory" ) ) {
 
 1130        TDirectory* tt = 
dynamic_cast<TDirectory*
>( obj );
 
 
 1143  gErrorIgnoreLevel = kBreak;
 
 1147  std::string stream, rem, r2;
 
 1150  auto itr = 
m_files.find( stream );
 
 1152    r2 = itr->second.first->GetName();
 
 1157      debug() << 
"getTEfficiencies: \"" << dir << 
"\" looks like a stream name." 
 1158              << 
" associated TFile: \"" << itr->second.first->GetName() << 
"\"" << 
endmsg;
 
 1161    if ( gDirectory->cd( r2.c_str() ) ) {
 
 1174  if ( !gDirectory->cd( dir.c_str() ) ) {
 
 1175    error() << 
"getTEfficiencies: No such TDirectory/stream \"" << dir << 
"\"" << 
endmsg;
 
 
 1187  gErrorIgnoreLevel = kBreak;
 
 1190    error() << 
"getTEfficiencies: No such TDirectory \"" << td->GetPath() << 
"\"" << 
endmsg;
 
 1195    debug() << 
"getTEfficiencies: \"" << td->GetPath() << 
"\": found " << td->GetListOfKeys()->GetSize() << 
" keys" 
 1199  TIter nextkey( td->GetListOfKeys() );
 
 1200  while ( TKey* key = (TKey*)nextkey() ) {
 
 1201    auto& log = 
debug();
 
 1203    TObject* obj = key->ReadObj();
 
 1204    if ( obj && obj->IsA()->InheritsFrom( 
"TDirectory" ) ) {
 
 1206    } 
else if ( obj && obj->IsA()->InheritsFrom( 
"TEfficiency" ) ) {
 
 1210        std::string dir = td->GetPath();
 
 1211        std::string fil = td->GetFile()->GetName();
 
 1212        dir.erase( 0, fil.length() + 1 );
 
 1215          id = 
id + 
"/" + key->GetName();
 
 1217          id = 
id + dir + 
"/" + key->GetName();
 
 1234    nextkey = td->GetListOfKeys();
 
 1235    while ( TKey* key = (TKey*)nextkey() ) {
 
 1236      TObject* obj = key->ReadObj();
 
 1237      if ( obj && obj->IsA()->InheritsFrom( 
"TDirectory" ) ) {
 
 1238        TDirectory* tt = 
dynamic_cast<TDirectory*
>( obj );
 
 
 1250  gErrorIgnoreLevel = kBreak;
 
 1254  std::string stream, rem, r2;
 
 1257  auto itr = 
m_files.find( stream );
 
 1259    r2 = itr->second.first->GetName();
 
 1264      debug() << 
"getTEfficiencies: \"" << dir << 
"\" looks like a stream name." 
 1265              << 
" associated TFile: \"" << itr->second.first->GetName() << 
"\"" << 
endmsg;
 
 1268    if ( gDirectory->cd( r2.c_str() ) ) {
 
 1279  if ( !gDirectory->cd( dir.c_str() ) ) {
 
 1280    error() << 
"getTEfficiencies: No such TDirectory/stream \"" << dir << 
"\"" << 
endmsg;
 
 1284      warning() << 
"Unable to register histograms automatically " 
 1285                << 
"without a valid stream name" << 
endmsg;
 
 
 1301  Long64_t mfs      = (Long64_t)
m_maxFileSize.value() * (Long64_t)1048576;
 
 1302  Long64_t mfs_warn = mfs * 95 / 100;
 
 1306  for ( 
const auto& f : 
m_files ) {
 
 1307    TFile* tf = f.second.first;
 
 1311      debug() << 
"stream: " << f.first << 
"  name: " << tf->GetName() << 
"  size: " << tf->GetSize() << 
endmsg;
 
 1316    if ( tf->GetSize() > mfs ) {
 
 1319      throw GaudiException( std::format( 
"file \"{}\" associated with stream \"{}\" has exceeded the max " 
 1320                                         "file size of {} MB. Terminating Job.",
 
 1324    } 
else if ( tf->GetSize() > mfs_warn ) {
 
 1325      warning() << 
"file \"" << tf->GetName() << 
"\" associated with stream \"" << f.first
 
 1326                << 
"\" is at 95% of its maximum allowable file size of " << 
m_maxFileSize.value() << 
"MB" << 
endmsg;
 
 
 1335  bool all_good = 
true;
 
 1342    error() << 
"could not retrieve I/O component manager !" << 
endmsg;
 
 1349  gErrorIgnoreLevel = kFatal;
 
 1351  for ( 
auto& ifile : 
m_files ) {
 
 1352    TFile*      f     = ifile.second.first;
 
 1353    std::string fname = f->GetName();
 
 1355      debug() << 
"file [" << fname << 
"] mode: [" << f->GetOption() << 
"] r:" << f->GetFileBytesRead()
 
 1356              << 
" w:" << f->GetFileBytesWritten() << 
" cnt:" << f->GetFileCounter() << 
endmsg;
 
 1359    if ( ifile.second.second == 
READ ) {
 
 1364    if ( !iomgr->io_retrieve( 
this, fname ).isSuccess() ) {
 
 1365      error() << 
"could not retrieve new name for [" << fname << 
"] !!" << 
endmsg;
 
 1368    } 
else if ( fname.empty() ) {
 
 1376    Option_t* opts = f->GetOption();
 
 1379      error() << 
"unable to open file \"" << fname << 
"\" for writing" << 
endmsg;
 
 1382    TFile* newfile = (TFile*)vf;
 
 1383    newfile->SetOption( opts );
 
 1387      ifile.second.first = newfile;
 
 1391    for ( 
auto& uid : 
m_uids ) {
 
 1392      for ( 
auto& hid : *uid.second ) {
 
 1393        if ( hid.file != f ) 
continue;
 
 1394        TDirectory* olddir = this->
changeDir( hid );
 
 1397        TDirectory* newdir = this->
changeDir( hid );
 
 1398        TClass*     cl     = hid.obj->IsA();
 
 1403          TTree& tree = 
dynamic_cast<TTree&
>( *hid.obj );
 
 1404          tree.SetDirectory( newdir );
 
 1407          TH1& hist = 
dynamic_cast<TH1&
>( *hid.obj );
 
 1408          hist.SetDirectory( newdir );
 
 1411          dynamic_cast<TEfficiency&
>( *hid.obj ).SetDirectory( newdir );
 
 1413          olddir->Remove( hid.obj );
 
 1414          newdir->Append( hid.obj );
 
 1416          error() << 
"id: \"" << hid.id << 
"\" is not a inheriting from a class " 
 1417                  << 
"we know how to handle (received [" << cl->GetName() << 
"], " 
 1418                  << 
"expected [TTree, TH1, TGraph or TEfficiency]) !" << 
endmsg << 
"attaching to current dir [" 
 1419                  << newdir->GetPath() << 
"] " 
 1420                  << 
"nonetheless..." << 
endmsg;
 
 1421          olddir->Remove( hid.obj );
 
 1422          newdir->Append( hid.obj );
 
 1426    f->ReOpen( 
"READ" );
 
 
 1450template <
typename T>
 
 1466  for ( 
auto uitr = 
m_uids.begin(); uitr != 
m_uids.end(); ++uitr ) {
 
 1467    for ( 
auto& hid : *( uitr->second ) ) {
 
 1470      if ( hid.type != 
ObjectType::TTREE || hid.temp || hid.mode == 
READ || hid.obj == 
nullptr ) 
continue;
 
 1473        verbose() << 
" update: " << uitr->first << 
" " << hid.id << 
" " << hid.mode << 
endmsg;
 
 1475      TTree* tr      = 
dynamic_cast<TTree*
>( hid.obj );
 
 1476      TFile* oldFile = hid.file;
 
 1477      TFile* newFile = tr->GetCurrentFile();
 
 1479      if ( oldFile != newFile ) {
 
 1480        std::string newFileName = newFile->GetName();
 
 1481        std::string oldFileName, streamName, rem;
 
 1482        TFile*      dummy = 
nullptr;
 
 1483        findStream( hid.id, streamName, rem, dummy );
 
 1486          if ( itr.second.first == oldFile ) { itr.second.first = newFile; }
 
 1489        for ( 
auto uitr2 = uitr; uitr2 != 
m_uids.end(); ++uitr2 ) {
 
 1490          for ( 
auto& hid2 : *( uitr2->second ) ) {
 
 1491            if ( hid2.file == oldFile ) { hid2.file = newFile; }
 
 1496                                  [&]( streamMap::const_reference s ) { 
return s.second == streamName; } );
 
 1497        if ( sitr != std::end( 
m_fileStreams ) ) oldFileName = sitr->first;
 
 1501          debug() << 
"migrating uid: " << hid.id << 
"   stream: " << streamName << 
"   oldFile: " << oldFileName
 
 1502                  << 
"   newFile: " << newFileName << 
endmsg;
 
 1506        if ( !oldFileName.empty() ) {
 
 1508          while ( i != std::end( 
m_fileStreams ) && i->first == oldFileName ) {
 
 1511              debug() << 
"changing filename \"" << i->first << 
"\" to \"" << newFileName << 
"\" for stream \"" 
 1512                      << i->second << 
"\"" << 
endmsg;
 
 1515            std::string nm = std::move( i->second );
 
 1520          error() << 
"Problems updating fileStreams with new file name" << 
endmsg;
 
 
 1530  std::for_each( 
m_files.begin(), 
m_files.end(), []( std::pair<
const std::string, std::pair<TFile*, Mode>>& i ) {
 
 1531    auto mode = i.second.second;
 
 1532    auto file = i.second.first;
 
 1533    if ( mode == WRITE || mode == UPDATE || mode == SHARE ) {
 
 1534      file->Write( 
"", TObject::kOverwrite );
 
 1535    } 
else if ( mode == 
APPEND ) {
 
 1541    debug() << 
"THistSvc::writeObjectsToFile()::List of Files connected in ROOT " << 
endmsg;
 
 1542    TSeqCollection* filelist = gROOT->GetListOfFiles();
 
 1543    for ( 
int ii = 0; ii < filelist->GetEntries(); ii++ ) {
 
 1544      debug() << 
"THistSvc::writeObjectsToFile()::List of Files connected in ROOT: \"" << filelist->At( ii )->GetName()
 
 
 1553  auto                                        loc    = ident.find( 
" " );
 
 1554  std::string                                 stream = ident.substr( 0, loc );
 
 1556  typedef std::pair<std::string, std::string> Prop;
 
 1557  std::vector<Prop>                           props;
 
 1558  std::string                                 filename, db_typ( 
"ROOT" );
 
 1561  if ( loc != std::string::npos ) {
 
 1563    for ( 
auto attrib : Parser( ident.substr( loc + 1 ) ) ) {
 
 1567      auto TAG = attrib.tag;
 
 1568      auto VAL = attrib.value;
 
 1569      boost::algorithm::to_upper( TAG );
 
 1570      boost::algorithm::to_upper( VAL );
 
 1572      if ( TAG == 
"FILE" || TAG == 
"DATAFILE" ) {
 
 1573        filename = attrib.value;
 
 1575      } 
else if ( TAG == 
"OPT" ) {
 
 1576        if ( VAL == 
"APPEND" || VAL == 
"UPDATE" ) {
 
 1578        } 
else if ( VAL == 
"CREATE" || VAL == 
"NEW" || VAL == 
"WRITE" ) {
 
 1580        } 
else if ( VAL == 
"RECREATE" ) {
 
 1582        } 
else if ( VAL == 
"SHARE" ) {
 
 1584        } 
else if ( VAL == 
"OLD" || VAL == 
"READ" ) {
 
 1587          error() << 
"Unknown OPT: \"" << attrib.value << 
"\"" << 
endmsg;
 
 1590      } 
else if ( TAG == 
"TYP" ) {
 
 1591        db_typ = std::move( attrib.value );
 
 1592      } 
else if ( TAG == 
"CL" ) {
 
 1593        cl = std::stoi( attrib.value );
 
 1595        props.emplace_back( attrib.tag, attrib.value );
 
 1600  if ( stream == 
"temp" ) {
 
 1601    error() << 
"in JobOption \"" << ident << 
"\": stream name \"temp\" reserved." << 
endmsg;
 
 1605  if ( db_typ != 
"ROOT" ) {
 
 1606    error() << 
"in JobOption \"" << ident << 
"\": technology type \"" << db_typ << 
"\" not supported." << 
endmsg;
 
 1611    error() << 
"in JobOption \"" << ident << 
"\":\n stream \"" << stream << 
"\" already connected to file: \"" 
 1618    error() << 
"No OPT= specified or unknown access mode in: " << ident << 
endmsg;
 
 1626    const std::string& oldstream = fitr.first->second;
 
 1628    const auto& f_info = 
m_files[oldstream];
 
 1630    if ( newMode != f_info.second ) {
 
 1631      error() << 
"in JobOption \"" << ident << 
"\":\n file \"" << filename << 
"\" already opened by stream: \"" 
 1632              << oldstream << 
"\" with different access mode." << 
endmsg;
 
 1635      TFile* f2       = f_info.first;
 
 1636      m_files[stream] = std::make_pair( f2, newMode );
 
 1638        debug() << 
"Connecting stream: \"" << stream << 
"\" to previously opened TFile: \"" << filename << 
"\"" 
 1652      error() << 
"Unable to open ROOT file " << filename << 
" for reading" << 
endmsg;
 
 1666      error() << 
"Unable to open ROOT file " << filename << 
" for writing" << 
endmsg;
 
 1676      error() << 
"unable to open file \"" << filename << 
"\" for appending" << 
endmsg;
 
 1687    static int  ishared      = 0;
 
 1688    std::string realfilename = filename;
 
 1689    filename                 = 
"tmp_THistSvc_" + std::to_string( ishared++ ) + 
".root";
 
 1692      debug() << 
"Creating temp file \"" << filename << 
"\" and realfilename=" << realfilename << 
endmsg;
 
 1699      error() << 
"Unable to open ROOT file " << filename << 
" for writing" << 
endmsg;
 
 1710      error() << 
"Unable to open ROOT file " << filename << 
" for appending" << 
endmsg;
 
 1717  m_files[stream] = std::make_pair( f, newMode );
 
 1721    debug() << 
"Opening TFile \"" << filename << 
"\"  stream: \"" << stream << 
"\"  mode: \"" << typ << 
"\"" 
 1722            << 
" comp level: " << cl << 
endmsg;
 
 
 1729  std::string uid  = hid.
id;
 
 1730  TFile*      file = hid.
file;
 
 1731  std::string stream, fdir, bdir, dir, id;
 
 1743    if ( !gDirectory->GetKey( dir.c_str() ) ) { gDirectory->mkdir( dir.c_str() ); }
 
 1744    gDirectory->cd( dir.c_str() );
 
 
 1751  std::string::size_type i = dir.find( 
"/" );
 
 1753  if ( i == std::string::npos ) 
return {};
 
 1760  std::string root = dir.substr( 0, i );
 
 
 1767  while ( 
id.find( 
"//" ) != std::string::npos ) { 
id.replace( 
id.find( 
"//" ), 2, 
"/" ); }
 
 
 1772  TString path( (
char*)strstr( target->GetPath(), 
":" ) );
 
 1773  path.Remove( 0, 2 );
 
 1776  TDirectory* current_sourcedir = gDirectory;
 
 1779  TList* lkeys = current_sourcedir->GetListOfKeys();
 
 1780  int    nkeys = lkeys->GetEntries();
 
 1781  TKey*  key   = 
nullptr;
 
 1782  for ( 
int jj = 0; jj < nkeys; jj++ ) {
 
 1783    key                          = (TKey*)lkeys->At( jj );
 
 1784    std::string pathnameinsource = current_sourcedir->GetPath() + std::string( 
"/" ) + key->GetName();
 
 1786    TObject* obj = source->Get( pathnameinsource.c_str() );
 
 1789      if ( obj->IsA()->InheritsFrom( 
"TDirectory" ) ) {
 
 1795        TDirectory* newtargetdir = target->mkdir( obj->GetName(), obj->GetTitle() );
 
 1799      } 
else if ( obj->IsA()->InheritsFrom( 
"TTree" ) ) {
 
 1801        TTree* mytree   = 
dynamic_cast<TTree*
>( obj );
 
 1802        int    nentries = (int)mytree->GetEntries();
 
 1803        mytree->SetBranchStatus( 
"*", 1 );
 
 1807        mytree->CloneTree();
 
 1811        obj->Write( key->GetName() );
 
 
 1818  auto pos = 
id.find( 
"/" );
 
 1820  if ( pos == std::string::npos ) {
 
 1824  } 
else if ( pos != 0 ) {
 
 1831    auto pos2 = 
id.find( 
"/", pos + 1 );
 
 1833    if ( pos2 == std::string::npos ) {
 
 1835      error() << 
"badly formed Hist/Tree id: \"" << 
id << 
"\"" << 
endmsg;
 
 1841  if ( stream == 
"temp" ) {
 
 1846  auto itr = 
m_files.find( stream );
 
 1847  file     = ( itr != 
m_files.end() ? itr->second.first : 
nullptr );
 
 1848  if ( !file ) { 
warning() << 
"no stream \"" << stream << 
"\" associated with id: \"" << 
id << 
"\"" << 
endmsg; }
 
 
 1854  auto pos = 
id.find( 
"/" );
 
 1856  if ( pos == std::string::npos ) {
 
 1859  } 
else if ( pos == 0 ) {
 
 1862    root = 
id.substr( 0, pos );
 
 1863    rem  = 
id.substr( pos + 1 );
 
 
 1869    debug() << 
"Delaying connection of Input Files until Initialize" 
 1874    debug() << 
"Now connecting of Input Files" << 
endmsg;
 
 1880      if ( 
connect( itr ).isFailure() ) {
 
 
 1893    debug() << 
"Delaying connection of Output Files until Initialize" 
 1900      if ( 
connect( itr ).isFailure() ) {
 
 
 1913    debug() << 
"copyFileLayout() to destination path: " << destination->GetPath() << 
endmsg;
 
 1917  TString path( (
char*)strstr( destination->GetPath(), 
":" ) );
 
 1918  path.Remove( 0, 2 );
 
 1921  TDirectory* current_source_dir = gDirectory;
 
 1924  TList* key_list = current_source_dir->GetListOfKeys();
 
 1925  int    n        = key_list->GetEntries();
 
 1926  for ( 
int j = 0; j < n; ++j ) {
 
 1927    TKey*             k               = (TKey*)key_list->At( j );
 
 1928    const std::string source_pathname = current_source_dir->GetPath() + std::string( 
"/" ) + k->GetName();
 
 1929    TObject*          o               = source->Get( source_pathname.c_str() );
 
 1931    if ( o && o->IsA()->InheritsFrom( 
"TDirectory" ) ) {
 
 1935      TDirectory* destination_dir = destination->mkdir( o->GetName(), o->GetTitle() );
 
 1936      if ( destination_dir == 
nullptr ) destination_dir = destination->GetDirectory( o->GetName() );
 
 
 1946  std::string idr( 
id );
 
 1951  if ( idr.starts_with( 
"/" ) ) {
 
 1953    auto itr = 
m_uids.find( idr );
 
 1954    if ( itr == 
m_uids.end() ) {
 
 1959      if ( index >= itr->second->size() ) {
 
 1960        error() << 
"no index " << index << 
" found for Hist " << idr << 
endmsg;
 
 1963      hid = &( itr->second->at( index ) );
 
 1968    auto mitr = 
m_ids.equal_range( idr );
 
 1969    if ( mitr.first == mitr.second ) {
 
 1972    } 
else if ( distance( mitr.first, mitr.second ) == 1 ) {
 
 1974      if ( index >= mitr.first->second->size() ) {
 
 1975        error() << 
"no index " << index << 
" found for Hist " << idr << 
endmsg;
 
 1978      hid = &( mitr.first->second->at( 0 ) );
 
 1982      hid = &( mitr.first->second->at( 0 ) );
 
 1983      return distance( mitr.first, mitr.second );
 
 
 1989  std::ostringstream ost;
 
 1992  ost << 
"m_hlist:  size: " << 
m_hlist.size() << 
"\n";
 
 1994    ost << 
" - " << vh->at( 0 ) << 
" :: [" << vh << 
"] " << vh->size() << 
" {";
 
 1995    for ( 
auto& e : *vh ) {
 
 1997      ost << 
"[" << o << 
"]";
 
 2004      << 
"m_uids: " << 
m_uids.size() << 
"\n";
 
 2005  for ( 
auto& e : 
m_uids ) { ost << 
" - " << e.first << 
"  [" << e.second << 
"]" << std::endl; }
 
 2009      << 
"m_ids: " << 
m_ids.size() << 
"\n";
 
 2010  for ( 
auto& e : 
m_ids ) { ost << 
" - " << e.first << 
"  [" << e.second << 
"]" << std::endl; }
 
 2014      << 
"m_tobjs: " << 
m_tobjs.size() << 
"\n";
 
 2016    TObject* o = e.first;
 
 2017    THistID& i = e.second.first->at( e.second.second );
 
 2018    ost << 
" - " << o << 
" -> " << i << std::endl;
 
 2021  debug() << 
"dumping THistSvc contents\n" << ost.str() << 
endmsg;
 
 
 2027  const std::string& 
name = vh->at( 0 ).id;
 
 2028  if ( vh->size() == 1 ) {
 
 2029    debug() << 
"merge: id: \"" << 
name << 
"\" is size 1. nothing to do" << 
endmsg;
 
 2034    error() << 
"merge: id \"" << 
name << 
"\" is not a THn. Cannot merge" << 
endmsg;
 
 2038  TList* l = 
new TList();
 
 2039  for ( 
size_t i = 1; i < vh->size(); ++i ) {
 
 2040    debug() << 
"merge: id: \"" << 
name << 
"\" (" << vh->at( i ).obj << 
") adding index " << i << 
endmsg;
 
 2041    l->Add( vh->at( i ).obj );
 
 2044  TH1* t0 = 
dynamic_cast<TH1*
>( vh->at( 0 ).obj );
 
 2046    error() << 
"merge: could not dcast " << 
name << 
"(" << t0 << 
") index " << 0 << 
" to TH1" << 
endmsg;
 
 2050  Long64_t n = t0->Merge( l );
 
 2052  debug() << 
"merge: id: \"" << 
name << 
"\" merged " << n << 
" entries" << 
endmsg;
 
 2054  for ( 
size_t i = 1; i < vh->size(); ++i ) {
 
 2055    TH1* th = 
dynamic_cast<TH1*
>( vh->at( i ).obj );
 
 2057      debug() << 
"clearing index " << i << 
"(" << th << 
")" << 
endmsg;
 
 2058      th->SetDirectory( 
nullptr );
 
 2061      error() << 
"merge: could not dcast " << 
name << 
" index " << i << 
" to TH1" << 
endmsg;
 
 
This file contains the class definition for the FileIncident class.
 
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
 
#define DECLARE_COMPONENT(type)
 
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
 
MsgStream & verbose() const
shortcut for the method msgStream(MSG::VERBOSE)
 
MsgStream & warning() const
shortcut for the method msgStream(MSG::WARNING)
 
MsgStream & fatal() const
shortcut for the method msgStream(MSG::FATAL)
 
MsgStream & err() const
shortcut for the method msgStream(MSG::ERROR)
 
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
 
MsgStream & info() const
shortcut for the method msgStream(MSG::INFO)
 
MSG::Level msgLevel() const
 
This class is the FileIncident.
 
Parse attribute strings allowing iteration over the various attributes.
 
Define general base for Gaudi exception.
 
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
 
Base class for all Incidents (computing events).
 
const std::string & desc() const
 
const std::string & name() const
 
Provides automatic lock/unlock access to a class upon deref of ptr.
 
Gaudi::StateMachine::State FSMState() const override
 
StatusCode finalize() override
 
const std::string & name() const override
Retrieve name of the service.
 
SmartIF< IFace > service(const std::string &name, bool createIf=true) const
 
StatusCode initialize() override
 
This class is used for returning status codes from appropriate routines.
 
const StatusCode & ignore() const
Allow discarding a StatusCode without warning.
 
constexpr static const auto SUCCESS
 
constexpr static const auto FAILURE
 
Helper class that manages ROOts global directory and file.
 
TDirectory * m_gDirectory
 
~GlobalDirectoryRestore()
 
GlobalDirectoryRestore(THistSvcMutex_t &mut)
 
std::lock_guard< THistSvcMutex_t > m_lock
 
StatusCode finalize() override
 
std::recursive_mutex THistSvcMutex_t
 
LockedHandle< T > regShared_i(const std::string &id, std::unique_ptr< T > hist)
 
StatusCode io_reinit() override
callback method to reinitialize the internal state of the component for I/O purposes (e....
 
StatusCode initialize() override
 
bool existsHist(const std::string &name) const override
Check if histogram with given name is managed by THistSvcMT.
 
T * getHist_i(const std::string &name, const size_t &ind=0, bool quiet=false) const
 
T * readHist_i(const std::string &name) const
 
Gaudi::Property< int > m_maxFileSize
 
StatusCode regShared(const std::string &name, std::unique_ptr< TH1 >, LockedHandle< TH1 > &) override
Register shared object of type TH1 and return LockedHandle for that object.
 
ServiceHandle< IIncidentSvc > p_incSvc
 
size_t findHistID(const std::string &id, const THistID *&hid, const size_t &index=0) const
 
StatusCode getHist(const std::string &name, TH1 *&, size_t index=0) const override
Return histogram with given name as TH1*, THistSvcMT still owns object.
 
T * readHist(const std::string &name) const
 
StatusCode getTTrees(TDirectory *td, TList &, bool recurse=false) const override
 
void setupOutputFile()
call-back method to handle output stream property
 
std::map< std::string, std::pair< TFile *, Mode > > m_files
 
bool exists(const std::string &name) const override
Check if object with given name is managed by THistSvcMT exists calls existsHist and only works for T...
 
void setupInputFile()
call-back method to handle input stream property
 
StatusCode connect(const std::string &)
 
StatusCode regHist_i(std::unique_ptr< T > hist, const std::string &name, bool shared)
 
Gaudi::Property< std::vector< std::string > > m_inputfile
 
std::vector< THistID > vhid_t
 
std::vector< std::string > getEfficiencies() const override
 
std::vector< std::string > getHists() const override
 
StatusCode regTree(const std::string &name) override
Register a new TTree with a given name.
 
ServiceHandle< IFileMgr > p_fileMgr
 
bool existsEfficiency(const std::string &name) const override
Check if TEfficiency with given name is managed by THistSvcMT.
 
TDirectory * changeDir(const THistSvc::THistID &hid) const
 
void MergeRootFile(TDirectory *, TDirectory *)
 
Gaudi::Property< std::vector< std::string > > m_outputfile
 
std::string stripDirectoryName(std::string &dir) const
 
static Mode charToMode(const char typ)
Convert a char to a Mode enum.
 
TTree * readTree(const std::string &name) const
 
StatusCode merge(const std::string &id) override
Merge all clones for object with a given id.
 
Gaudi::Property< int > m_autoSave
 
StatusCode deReg(const std::string &name) override
Deregister object with given name and give up ownership (without deletion!)
 
void handle(const Incident &) override
 
void copyFileLayout(TDirectory *, TDirectory *)
helper function to recursively copy the layout of a TFile into a new TFile
 
StatusCode getShared(const std::string &name, LockedHandle< TH1 > &) const override
Retrieve shared object with given name as TH1 through LockedHandle.
 
std::map< std::string, std::string > m_sharedFiles
 
void parseString(const std::string &id, std::string &root, std::string &rem) const
 
StatusCode writeObjectsToFile()
 
Gaudi::Property< int > m_autoFlush
 
void removeDoubleSlash(std::string &) const
 
StatusCode rootOpenAction(FILEMGR_CALLBACK_ARGS)
 
Gaudi::Property< bool > m_print
 
void updateFiles()
Handle case where TTree grows beyond TTree::fgMaxTreeSize.
 
LockedHandle< T > getShared_i(const std::string &name) const
 
std::vector< std::string > getTrees() const override
 
std::set< std::string > m_alreadyConnectedOutFiles
list of already connected files.
 
StatusCode regEfficiency(const std::string &name) override
Register a new TEfficiency with a given name.
 
StatusCode reinitialize() override
 
std::vector< std::string > getGraphs() const override
 
bool findStream(const std::string &name, std::string &root, std::string &rem, TFile *&file) const
 
StatusCode getEfficiency(const std::string &name, TEfficiency *&) const override
Return TEfficiency with given name.
 
bool existsGraph(const std::string &name) const override
Check if graph with given name is managed by THistSvcMT.
 
bool existsTree(const std::string &name) const override
Check if tree with given name is managed by THistSvcMT.
 
std::set< std::string > m_alreadyConnectedInFiles
list of already connected files.
 
StatusCode rootOpenErrAction(FILEMGR_CALLBACK_ARGS)
 
StatusCode getTree(const std::string &name, TTree *&) const override
Return TTree with given name.
 
StatusCode regGraph(const std::string &name) override
Register a new TGraph with a given name.
 
StatusCode getTHists(TDirectory *td, TList &, bool recurse=false) const override
 
StatusCode regHist(const std::string &name) override
Register a new ROOT histogram TH*X with a name.
 
StatusCode getTEfficiencies(TDirectory *td, TList &, bool recurse=false) const override
 
StatusCode getGraph(const std::string &name, TGraph *&) const override
Return TGraph with given name.
 
THistSvc(const std::string &name, ISvcLocator *svcloc)
 
Helper struct that bundles the histogram ID with a mutex, TFile and TObject*.