18 #include "boost/algorithm/string/case_conv.hpp" 
   22 #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>
 
   85     error() << 
"initializing service" << 
endmsg;
 
   94     error() << 
"Caught: " << err << 
endmsg;
 
  101     error() << 
"Caught: " << err << 
endmsg;
 
  107     static TROOT 
root( 
"root", 
"ROOT I/O" );
 
  114     error() << 
"unable to get the IncidentSvc" << 
endmsg;
 
  121     error() << 
"unable to get the FileMgr" << 
endmsg;
 
  131     error() << 
"unable to register ROOT file open action with FileMgr" << 
endmsg;
 
  137     error() << 
"unable to register ROOT file open Error action with FileMgr" << 
endmsg;
 
  150   if ( 
service( 
"IoComponentMgr", iomgr, 
true ).isFailure() ) {
 
  151     error() << 
"unable to get the IoComponentMgr" << 
endmsg;
 
  155       error() << 
"could not register with the I/O component manager !" << 
endmsg;
 
  158       bool all_good = 
true;
 
  160       for ( 
const auto& reg : 
m_files ) {
 
  161         const std::string&                  fname = reg.second.first->GetName();
 
  165           warning() << 
"could not register file [" << fname << 
"] with the I/O component manager..." << 
endmsg;
 
  168           info() << 
"registered file [" << fname << 
"]... [ok]" << 
endmsg;
 
  172         error() << 
"problem while registering input/output files with " 
  173                 << 
"the I/O component manager !" << 
endmsg;
 
  179   if ( st.
isFailure() ) { fatal() << 
"Unable to initialize THistSvc" << 
endmsg; }
 
  186   warning() << 
"reinitialize not implemented" << 
endmsg;
 
  195     debug() << 
"THistSvc::finalize" << 
endmsg;
 
  201     for ( 
const auto& itr : sorted_uids ) {
 
  202       THistID& thid = itr.second->at( 0 );
 
  203       TObject* tobj = thid.
obj;
 
  207         TTree* tree = 
dynamic_cast<TTree*
>( tobj );
 
  208         if ( tree->GetDirectory() != 0 ) { dirname = tree->GetDirectory()->GetPath(); }
 
  211           dirname = thid.
file->GetPath();
 
  215           if ( id2.
find( 
"/" ) == 0 ) { id2.
erase( 0, 1 ); }
 
  221         TH1* th = 
dynamic_cast<TH1*
>( tobj );
 
  222         if ( th == 
nullptr ) {
 
  223           error() << 
"Couldn't dcast: " << itr.first << 
endmsg;
 
  225           if ( th->GetDirectory() != 0 ) { dirname = th->GetDirectory()->GetPath(); }
 
  227       } 
else if ( !tobj ) {
 
  228         warning() << itr.first << 
" has NULL TObject ptr" << 
endmsg;
 
  230       debug() << 
"finalize: " << thid << 
endmsg;
 
  237   if ( 
m_print ) { info() << 
"Listing contents of ROOT files: " << 
endmsg; }
 
  240     if ( 
std::find( deleted_files.
begin(), deleted_files.
end(), itr.second.first ) == deleted_files.
end() ) {
 
  241       deleted_files.
push_back( itr.second.first );
 
  245         debug() << 
"finalizing stream/file " << itr.first << 
":" << itr.second.first->GetName() << 
endmsg;
 
  256       info() << 
"==> File: " << itr.second.first->GetName() << 
"  stream: " << itr.first << 
endmsg;
 
  258       itr.second.first->Print( 
"base" );
 
  266     if ( 
service( 
"IncidentSvc", pIncidentSvc ).isFailure() ) {
 
  267       error() << 
"Unable to get the IncidentSvc" << 
endmsg;
 
  271     if ( itr.second.second == 
SHARE ) {
 
  273       void* vfile = 
nullptr;
 
  278         error() << 
"unable to open Final Output File: \"" << 
m_sharedFiles[itr.first] << 
"\" for merging" << 
endmsg;
 
  282       TFile* outputfile = (TFile*)vfile;
 
  291         error() << 
"unable to open temporary file: \"" << tmpfn << 
endmsg;
 
  295       TFile* inputfile = (TFile*)vfile;
 
  297       outputfile->SetCompressionLevel( inputfile->GetCompressionLevel() );
 
  309     delete itr.second.first;
 
  322     if ( obj.second.second == 0 ) {
 
  323       delete obj.second.first; 
 
  344   if ( hist_ptr != 
nullptr ) { hist_ptr = hist.
get(); }
 
  354   hist = getHist_i<TH1>( 
id, ind );
 
  355   if ( hist != 
nullptr ) {
 
  363   hist = getHist_i<TH2>( 
id, ind );
 
  364   if ( hist != 
nullptr ) {
 
  372   hist = getHist_i<TH3>( 
id, ind );
 
  373   if ( hist != 
nullptr ) {
 
  407   tree = getHist_i<TTree>( 
id );
 
  408   if ( tree != 
nullptr ) {
 
  421   if ( strcmp( 
graph->GetName(), 
"Graph" ) == 0 ) {
 
  423     std::string::size_type i = id2.
rfind( 
"/" );
 
  424     if ( i != std::string::npos ) { id2.
erase( 0, i + 1 ); }
 
  426     info() << 
"setting name of TGraph id: \"" << 
id << 
"\" to \"" << id2 << 
"\" since it is unset" << 
endmsg;
 
  435   if ( strcmp( 
graph->GetName(), 
"Graph" ) == 0 ) {
 
  437     std::string::size_type i = id2.
rfind( 
"/" );
 
  438     if ( i != std::string::npos ) { id2.
erase( 0, i + 1 ); }
 
  440     info() << 
"setting name of TGraph id: \"" << 
id << 
"\" to \"" << id2 << 
"\" since it is unset" << 
endmsg;
 
  448   graph = getHist_i<TGraph>( 
id );
 
  449   if ( 
graph != 
nullptr ) {
 
  471   eff = getHist_i<TEfficiency>( 
id );
 
  472   if ( eff != 
nullptr ) {
 
  480   lh = regShared_i<TH1>( 
id, 
std::move( hist ) );
 
  489   lh = regShared_i<TH2>( 
id, 
std::move( hist ) );
 
  498   lh = regShared_i<TH3>( 
id, 
std::move( hist ) );
 
  517   lh = regShared_i<TEfficiency>( 
id, 
std::move( eff ) );
 
  526   lh = getShared_i<TH1>( 
name );
 
  535   lh = getShared_i<TH2>( 
name );
 
  544   lh = getShared_i<TH3>( 
name );
 
  553   lh = getShared_i<TGraph>( 
name );
 
  562   lh = getShared_i<TEfficiency>( 
name );
 
  573     error() << 
"Problem deregistering id \"" << 
id << 
"\": not found in registry" << 
endmsg;
 
  580     debug() << 
"will deregister " << vh->
size() << 
" elements of id \"" << 
id << 
"\"" << 
endmsg;
 
  584   size_t vh_size = vh->
size();
 
  585   while ( vh_size-- ) {
 
  588       error() << 
"Problems deRegistering " << vh->
size() << 
" element of id \"" << 
id << 
"\"" << 
endmsg;
 
  599     vhid_t* vhid = obj_itr->second.first;
 
  600     THistID hid  = obj_itr->second.first->at( obj_itr->second.second );
 
  604       error() << 
"Problems deregistering TObject \"" << obj->GetName() << 
"\" with id \"" << hid.
id 
  605               << 
"\": not in uidMap" << 
endmsg;
 
  609     if ( vhid->
size() == 1 ) {
 
  618                                   [&]( idMap_t::const_reference i ) { return i.second->at( 0 ).obj == obj; } );
 
  619       if ( id_itr == mitr.second ) {
 
  620         error() << 
"Problems deregistering TObject \"" << obj->GetName() << 
"\" with id \"" << hid.
id 
  621                 << 
"\": not in idMap" << 
endmsg;
 
  627         error() << 
"Problems deregistering TObject \"" << obj->GetName() << 
"\" with id \"" << hid.
id 
  628                 << 
"\": not in hlist" << 
endmsg;
 
  632       vhid->
erase( vhid->
begin() + obj_itr->second.second );
 
  641     } 
else if ( vhid->
size() > 1 ) {
 
  643       vhid->
erase( vhid->
begin() + obj_itr->second.second );
 
  647       error() << 
"Deregistration failed unexpectedly. (bug in THistSvc?)" << 
endmsg;
 
  651     error() << 
"Cannot unregister TObject \"" << obj->GetName() << 
"\": not known to THistSvc" << 
endmsg;
 
  659     error() << 
"merge: id \"" << 
name << 
"\" not found" << 
endmsg;
 
  663   return merge( itr->second );
 
  669     return merge( itr->second.first );
 
  671     error() << 
"merge: unknown object " << obj << 
endmsg;
 
  681   return ( getHist_i<TEfficiency>( 
name, 0, 
true ) != 
nullptr );
 
  685   return ( getHist_i<TGraph>( 
name, 0, 
true ) != 
nullptr );
 
  725   gErrorIgnoreLevel = kBreak;
 
  728     error() << 
"getTHists: No such TDirectory \"" << td->GetPath() << 
"\"" << 
endmsg;
 
  733     debug() << 
"getTHists: \"" << td->GetPath() << 
"\": found " << td->GetListOfKeys()->GetSize() << 
" keys" << 
endmsg;
 
  736   TIter nextkey( td->GetListOfKeys() );
 
  737   while ( TKey* 
key = (TKey*)nextkey() ) {
 
  740     TObject* obj = 
key->ReadObj();
 
  741     if ( obj != 0 && obj->IsA()->InheritsFrom( 
"TDirectory" ) ) {
 
  743     } 
else if ( obj != 0 && obj->IsA()->InheritsFrom( 
"TH1" ) ) {
 
  746     } 
else if ( obj != 0 ) {
 
  754     nextkey = td->GetListOfKeys();
 
  755     while ( TKey* 
key = (TKey*)nextkey() ) {
 
  756       TObject* obj = 
key->ReadObj();
 
  757       if ( obj && obj->IsA()->InheritsFrom( 
"TDirectory" ) ) {
 
  758         TDirectory* tt = 
dynamic_cast<TDirectory*
>( obj );
 
  771   gErrorIgnoreLevel = kBreak;
 
  780     r2 = itr->second.first->GetName();
 
  785       debug() << 
"getTHists: \"" << dir << 
"\" looks like a stream name." 
  786               << 
" associated TFile: \"" << itr->second.first->GetName() << 
"\"" << 
endmsg;
 
  789     if ( gDirectory->cd( r2.
c_str() ) ) {
 
  802   if ( !gDirectory->cd( dir.
c_str() ) ) {
 
  803     error() << 
"getTHists: No such TDirectory/stream \"" << dir << 
"\"" << 
endmsg;
 
  815   gErrorIgnoreLevel = kBreak;
 
  818     error() << 
"getTHists: No such TDirectory \"" << td->GetPath() << 
"\"" << 
endmsg;
 
  823     debug() << 
"getTHists: \"" << td->GetPath() << 
"\": found " << td->GetListOfKeys()->GetSize() << 
" keys" << 
endmsg;
 
  826   TIter nextkey( td->GetListOfKeys() );
 
  827   while ( TKey* 
key = (TKey*)nextkey() ) {
 
  830     TObject* obj = 
key->ReadObj();
 
  831     if ( obj && obj->IsA()->InheritsFrom( 
"TDirectory" ) ) {
 
  833     } 
else if ( obj && obj->IsA()->InheritsFrom( 
"TH1" ) ) {
 
  842           id = 
id + 
"/" + 
key->GetName();
 
  844           id = 
id + dir + 
"/" + 
key->GetName();
 
  861     nextkey = td->GetListOfKeys();
 
  862     while ( TKey* 
key = (TKey*)nextkey() ) {
 
  863       TObject* obj = 
key->ReadObj();
 
  864       if ( obj && obj->IsA()->InheritsFrom( 
"TDirectory" ) ) {
 
  865         TDirectory* tt = 
dynamic_cast<TDirectory*
>( obj );
 
  877   gErrorIgnoreLevel = kBreak;
 
  886     r2 = itr->second.first->GetName();
 
  891       debug() << 
"getTHists: \"" << dir << 
"\" looks like a stream name." 
  892               << 
" associated TFile: \"" << itr->second.first->GetName() << 
"\"" << 
endmsg;
 
  895     if ( gDirectory->cd( r2.
c_str() ) ) {
 
  897       sc          = 
getTHists( gDirectory, tl, rcs, reg );
 
  906   if ( !gDirectory->cd( dir.
c_str() ) ) {
 
  907     error() << 
"getTHists: No such TDirectory/stream \"" << dir << 
"\"" << 
endmsg;
 
  911       warning() << 
"Unable to register histograms automatically " 
  912                 << 
"without a valid stream name" << 
endmsg;
 
  915     sc = 
getTHists( gDirectory, tl, rcs, reg );
 
  924   gErrorIgnoreLevel = kBreak;
 
  927     error() << 
"getTTrees: No such TDirectory \"" << td->GetPath() << 
"\"" << 
endmsg;
 
  932     debug() << 
"getTHists: \"" << td->GetPath() << 
"\": found " << td->GetListOfKeys()->GetSize() << 
" keys" << 
endmsg;
 
  935   TIter nextkey( td->GetListOfKeys() );
 
  936   while ( TKey* 
key = (TKey*)nextkey() ) {
 
  939     TObject* obj = 
key->ReadObj();
 
  940     if ( obj != 0 && obj->IsA()->InheritsFrom( 
"TDirectory" ) ) {
 
  942     } 
else if ( obj != 0 && obj->IsA()->InheritsFrom( 
"TTree" ) ) {
 
  945     } 
else if ( obj != 0 ) {
 
  953     nextkey = td->GetListOfKeys();
 
  954     while ( TKey* 
key = (TKey*)nextkey() ) {
 
  955       TObject* obj = 
key->ReadObj();
 
  956       if ( obj && obj->IsA()->InheritsFrom( 
"TDirectory" ) ) {
 
  957         TDirectory* tt = 
dynamic_cast<TDirectory*
>( obj );
 
  969   gErrorIgnoreLevel = kBreak;
 
  978     r2 = itr->second.first->GetName();
 
  983       debug() << 
"getTTrees: \"" << dir << 
"\" looks like a stream name." 
  984               << 
" associated TFile: \"" << itr->second.first->GetName() << 
"\"" << 
endmsg;
 
  987     if ( gDirectory->cd( r2.
c_str() ) ) { 
return getTTrees( gDirectory, tl, rcs ); }
 
  993   if ( !gDirectory->cd( dir.
c_str() ) ) {
 
  994     error() << 
"getTTrees: No such TDirectory/stream \"" << dir << 
"\"" << 
endmsg;
 
 1005   gErrorIgnoreLevel = kBreak;
 
 1008     error() << 
"getTTrees: No such TDirectory \"" << td->GetPath() << 
"\"" << 
endmsg;
 
 1013     debug() << 
"getTHists: \"" << td->GetPath() << 
"\": found " << td->GetListOfKeys()->GetSize() << 
" keys" << 
endmsg;
 
 1016   TIter nextkey( td->GetListOfKeys() );
 
 1017   while ( TKey* 
key = (TKey*)nextkey() ) {
 
 1018     auto& 
log = debug();
 
 1020     TObject* obj = 
key->ReadObj();
 
 1021     if ( obj && obj->IsA()->InheritsFrom( 
"TDirectory" ) ) {
 
 1023     } 
else if ( obj && obj->IsA()->InheritsFrom( 
"TTree" ) ) {
 
 1032           id = 
id + 
"/" + 
key->GetName();
 
 1034           id = 
id + dir + 
"/" + 
key->GetName();
 
 1043     } 
else if ( obj != 0 ) {
 
 1051     nextkey = td->GetListOfKeys();
 
 1052     while ( TKey* 
key = (TKey*)nextkey() ) {
 
 1053       TObject* obj = 
key->ReadObj();
 
 1054       if ( obj && obj->IsA()->InheritsFrom( 
"TDirectory" ) ) {
 
 1055         TDirectory* tt = 
dynamic_cast<TDirectory*
>( obj );
 
 1067   gErrorIgnoreLevel = kBreak;
 
 1076     r2 = itr->second.first->GetName();
 
 1081       debug() << 
"getTTrees: \"" << dir << 
"\" looks like a stream name." 
 1082               << 
" associated TFile: \"" << itr->second.first->GetName() << 
"\"" << 
endmsg;
 
 1085     if ( gDirectory->cd( r2.
c_str() ) ) {
 
 1086       return getTTrees( gDirectory, tl, rcs, reg );
 
 1094   if ( !gDirectory->cd( dir.
c_str() ) ) {
 
 1095     error() << 
"getTTrees: No such TDirectory/stream \"" << dir << 
"\"" << 
endmsg;
 
 1099   return getTTrees( gDirectory, tl, rcs, reg );
 
 1105   gErrorIgnoreLevel = kBreak;
 
 1108     error() << 
"getTEfficiencies: No such TDirectory \"" << td->GetPath() << 
"\"" << 
endmsg;
 
 1113     debug() << 
"getTEfficiencies: \"" << td->GetPath() << 
"\": found " << td->GetListOfKeys()->GetSize() << 
" keys" 
 1117   TIter nextkey( td->GetListOfKeys() );
 
 1118   while ( TKey* 
key = (TKey*)nextkey() ) {
 
 1119     auto& 
log = debug();
 
 1121     TObject* obj = 
key->ReadObj();
 
 1122     if ( obj != 0 && obj->IsA()->InheritsFrom( 
"TDirectory" ) ) {
 
 1124     } 
else if ( obj != 0 && obj->IsA()->InheritsFrom( 
"TEfficiency" ) ) {
 
 1127     } 
else if ( obj != 0 ) {
 
 1135     nextkey = td->GetListOfKeys();
 
 1136     while ( TKey* 
key = (TKey*)nextkey() ) {
 
 1137       TObject* obj = 
key->ReadObj();
 
 1138       if ( obj && obj->IsA()->InheritsFrom( 
"TDirectory" ) ) {
 
 1139         TDirectory* tt = 
dynamic_cast<TDirectory*
>( obj );
 
 1152   gErrorIgnoreLevel = kBreak;
 
 1161     r2 = itr->second.first->GetName();
 
 1166       debug() << 
"getTEfficiencies: \"" << dir << 
"\" looks like a stream name." 
 1167               << 
" associated TFile: \"" << itr->second.first->GetName() << 
"\"" << 
endmsg;
 
 1170     if ( gDirectory->cd( r2.
c_str() ) ) {
 
 1183   if ( !gDirectory->cd( dir.
c_str() ) ) {
 
 1184     error() << 
"getTEfficiencies: No such TDirectory/stream \"" << dir << 
"\"" << 
endmsg;
 
 1196   gErrorIgnoreLevel = kBreak;
 
 1199     error() << 
"getTEfficiencies: No such TDirectory \"" << td->GetPath() << 
"\"" << 
endmsg;
 
 1204     debug() << 
"getTEfficiencies: \"" << td->GetPath() << 
"\": found " << td->GetListOfKeys()->GetSize() << 
" keys" 
 1208   TIter nextkey( td->GetListOfKeys() );
 
 1209   while ( TKey* 
key = (TKey*)nextkey() ) {
 
 1210     auto& 
log = debug();
 
 1212     TObject* obj = 
key->ReadObj();
 
 1213     if ( obj && obj->IsA()->InheritsFrom( 
"TDirectory" ) ) {
 
 1215     } 
else if ( obj && obj->IsA()->InheritsFrom( 
"TEfficiency" ) ) {
 
 1224           id = 
id + 
"/" + 
key->GetName();
 
 1226           id = 
id + dir + 
"/" + 
key->GetName();
 
 1243     nextkey = td->GetListOfKeys();
 
 1244     while ( TKey* 
key = (TKey*)nextkey() ) {
 
 1245       TObject* obj = 
key->ReadObj();
 
 1246       if ( obj && obj->IsA()->InheritsFrom( 
"TDirectory" ) ) {
 
 1247         TDirectory* tt = 
dynamic_cast<TDirectory*
>( obj );
 
 1259   gErrorIgnoreLevel = kBreak;
 
 1268     r2 = itr->second.first->GetName();
 
 1273       debug() << 
"getTEfficiencies: \"" << dir << 
"\" looks like a stream name." 
 1274               << 
" associated TFile: \"" << itr->second.first->GetName() << 
"\"" << 
endmsg;
 
 1277     if ( gDirectory->cd( r2.
c_str() ) ) {
 
 1288   if ( !gDirectory->cd( dir.
c_str() ) ) {
 
 1289     error() << 
"getTEfficiencies: No such TDirectory/stream \"" << dir << 
"\"" << 
endmsg;
 
 1293       warning() << 
"Unable to register histograms automatically " 
 1294                 << 
"without a valid stream name" << 
endmsg;
 
 1312   Long64_t mfs_warn = mfs * 95 / 100;
 
 1316   for ( 
const auto& f : 
m_files ) {
 
 1317     TFile* tf = f.second.first;
 
 1321       debug() << 
"stream: " << f.first << 
"  name: " << tf->GetName() << 
"  size: " << tf->GetSize() << 
endmsg;
 
 1326     if ( tf->GetSize() > mfs ) {
 
 1330       fatal() << 
"file \"" << tf->GetName() << 
"\" associated with stream \"" << f.first
 
 1334       if ( 
service( 
"ApplicationMgr", 
evt, 
true ).isSuccess() ) {
 
 1335         evt->stopRun().ignore(  );
 
 1340     } 
else if ( tf->GetSize() > mfs_warn ) {
 
 1341       warning() << 
"file \"" << tf->GetName() << 
"\" associated with stream \"" << f.first
 
 1351   bool all_good = 
true;
 
 1358   if ( 
service( 
"IoComponentMgr", iomgr, 
true ).isFailure() ) {
 
 1359     error() << 
"could not retrieve I/O component manager !" << 
endmsg;
 
 1366   gErrorIgnoreLevel = kFatal;
 
 1368   for ( 
auto& ifile : 
m_files ) {
 
 1369     TFile*      f     = ifile.second.first;
 
 1372       debug() << 
"file [" << fname << 
"] mode: [" << f->GetOption() << 
"] r:" << f->GetFileBytesRead()
 
 1373               << 
" w:" << f->GetFileBytesWritten() << 
" cnt:" << f->GetFileCounter() << 
endmsg;
 
 1376     if ( ifile.second.second == 
READ ) {
 
 1381     if ( !iomgr->
io_retrieve( 
this, fname ).isSuccess() ) {
 
 1382       error() << 
"could not retrieve new name for [" << fname << 
"] !!" << 
endmsg;
 
 1385     } 
else if ( fname.
empty() ) {
 
 1393     Option_t* 
opts = f->GetOption();
 
 1396       error() << 
"unable to open file \"" << fname << 
"\" for writing" << 
endmsg;
 
 1399     TFile* newfile = (TFile*)vf;
 
 1400     newfile->SetOption( 
opts );
 
 1404       ifile.second.first = newfile;
 
 1408     for ( 
auto& uid : 
m_uids ) {
 
 1409       for ( 
auto& hid : *uid.second ) {
 
 1410         if ( hid.file != f ) 
continue;
 
 1411         TDirectory* olddir = this->
changeDir( hid );
 
 1414         TDirectory* newdir = this->
changeDir( hid );
 
 1415         TClass*     cl     = hid.obj->IsA();
 
 1420           TTree& tree = 
dynamic_cast<TTree&
>( *hid.obj );
 
 1421           tree.SetDirectory( newdir );
 
 1424           TH1& hist = 
dynamic_cast<TH1&
>( *hid.obj );
 
 1425           hist.SetDirectory( newdir );
 
 1428           dynamic_cast<TEfficiency&
>( *hid.obj ).SetDirectory( newdir );
 
 1430           olddir->Remove( hid.obj );
 
 1431           newdir->Append( hid.obj );
 
 1433           error() << 
"id: \"" << hid.id << 
"\" is not a inheriting from a class " 
 1434                   << 
"we know how to handle (received [" << cl->GetName() << 
"], " 
 1435                   << 
"expected [TTree, TH1, TGraph or TEfficiency]) !" << 
endmsg << 
"attaching to current dir [" 
 1436                   << newdir->GetPath() << 
"] " 
 1437                   << 
"nonetheless..." << 
endmsg;
 
 1438           olddir->Remove( hid.obj );
 
 1439           newdir->Append( hid.obj );
 
 1443     f->ReOpen( 
"READ" );
 
 1460   gDirectory        = m_gDirectory;
 
 1462   gErrorIgnoreLevel = m_gErrorIgnoreLevel;
 
 1467 template <
typename T>
 
 1469   return dynamic_cast<T*
>( readHist_i<T>( 
id ) );
 
 1484     for ( 
auto& hid : *( uitr->second ) ) {
 
 1487       if ( hid.type != 
ObjectType::TTREE || hid.temp || hid.mode == 
READ || hid.obj == 
nullptr ) 
continue;
 
 1490         verbose() << 
" update: " << uitr->first << 
" " << hid.id << 
" " << hid.mode << 
endmsg;
 
 1492       TTree* tr      = 
dynamic_cast<TTree*
>( hid.obj );
 
 1493       TFile* oldFile = hid.file;
 
 1494       TFile* newFile = tr->GetCurrentFile();
 
 1496       if ( oldFile != newFile ) {
 
 1499         TFile*      dummy = 
nullptr;
 
 1500         findStream( hid.id, streamName, rem, dummy );
 
 1503           if ( itr.second.first == oldFile ) { itr.second.first = newFile; }
 
 1506         for ( 
auto uitr2 = uitr; uitr2 != 
m_uids.
end(); ++uitr2 ) {
 
 1507           for ( 
auto& hid2 : *( uitr2->second ) ) {
 
 1508             if ( hid2.file == oldFile ) { hid2.file = newFile; }
 
 1513                                   [&]( streamMap::const_reference 
s ) { 
return s.second == streamName; } );
 
 1518           debug() << 
"migrating uid: " << hid.id << 
"   stream: " << streamName << 
"   oldFile: " << oldFileName
 
 1519                   << 
"   newFile: " << newFileName << 
endmsg;
 
 1523         if ( !oldFileName.
empty() ) {
 
 1528               debug() << 
"changing filename \"" << i->first << 
"\" to \"" << newFileName << 
"\" for stream \"" 
 1529                       << i->second << 
"\"" << 
endmsg;
 
 1537           error() << 
"Problems updating fileStreams with new file name" << 
endmsg;
 
 1548     auto mode = i.second.second;
 
 1549     auto file = i.second.first;
 
 1550     if ( mode == WRITE || mode == UPDATE || mode == SHARE ) {
 
 1551       file->Write( 
"", TObject::kOverwrite );
 
 1552     } 
else if ( mode == 
APPEND ) {
 
 1558     debug() << 
"THistSvc::writeObjectsToFile()::List of Files connected in ROOT " << 
endmsg;
 
 1559     TSeqCollection* filelist = gROOT->GetListOfFiles();
 
 1560     for ( 
int ii = 0; ii < filelist->GetEntries(); ii++ ) {
 
 1561       debug() << 
"THistSvc::writeObjectsToFile()::List of Files connected in ROOT: \"" << filelist->At( ii )->GetName()
 
 1570   auto                                        loc    = ident.
find( 
" " );
 
 1578   if ( loc != std::string::npos ) {
 
 1580     for ( 
auto attrib : Parser( ident.
substr( loc + 1 ) ) ) {
 
 1581       auto TAG = boost::algorithm::to_upper_copy( attrib.tag );
 
 1582       auto VAL = boost::algorithm::to_upper_copy( attrib.value );
 
 1584       if ( TAG == 
"FILE" || TAG == 
"DATAFILE" ) {
 
 1587       } 
else if ( TAG == 
"OPT" ) {
 
 1588         if ( VAL == 
"APPEND" || VAL == 
"UPDATE" ) {
 
 1590         } 
else if ( VAL == 
"CREATE" || VAL == 
"NEW" || VAL == 
"WRITE" ) {
 
 1592         } 
else if ( VAL == 
"RECREATE" ) {
 
 1594         } 
else if ( VAL == 
"SHARE" ) {
 
 1596         } 
else if ( VAL == 
"OLD" || VAL == 
"READ" ) {
 
 1599           error() << 
"Unknown OPT: \"" << attrib.value << 
"\"" << 
endmsg;
 
 1602       } 
else if ( TAG == 
"TYP" ) {
 
 1604       } 
else if ( TAG == 
"CL" ) {
 
 1607         props.emplace_back( attrib.tag, attrib.value );
 
 1612   if ( 
stream == 
"temp" ) {
 
 1613     error() << 
"in JobOption \"" << ident << 
"\": stream name \"temp\" reserved." << 
endmsg;
 
 1617   if ( db_typ != 
"ROOT" ) {
 
 1618     error() << 
"in JobOption \"" << ident << 
"\": technology type \"" << db_typ << 
"\" not supported." << 
endmsg;
 
 1623     error() << 
"in JobOption \"" << ident << 
"\":\n stream \"" << 
stream << 
"\" already connected to file: \"" 
 1630     error() << 
"No OPT= specified or unknown access mode in: " << ident << 
endmsg;
 
 1638     const std::string& oldstream = fitr.first->second;
 
 1640     const auto& f_info = 
m_files[oldstream];
 
 1642     if ( newMode != f_info.second ) {
 
 1643       error() << 
"in JobOption \"" << ident << 
"\":\n file \"" << 
filename << 
"\" already opened by stream: \"" 
 1644               << oldstream << 
"\" with different access mode." << 
endmsg;
 
 1647       TFile* f2       = f_info.first;
 
 1650         debug() << 
"Connecting stream: \"" << 
stream << 
"\" to previously opened TFile: \"" << 
filename << 
"\"" 
 1657   if ( 
service( 
"IncidentSvc", 
pi ).isFailure() ) {
 
 1658     error() << 
"Unable to get the IncidentSvc" << 
endmsg;
 
 1670       error() << 
"Unable to open ROOT file " << 
filename << 
" for reading" << 
endmsg;
 
 1684       error() << 
"Unable to open ROOT file " << 
filename << 
" for writing" << 
endmsg;
 
 1694       error() << 
"unable to open file \"" << 
filename << 
"\" for appending" << 
endmsg;
 
 1705     static int  ishared      = 0;
 
 1710       debug() << 
"Creating temp file \"" << 
filename << 
"\" and realfilename=" << realfilename << 
endmsg;
 
 1717       error() << 
"Unable to open ROOT file " << 
filename << 
" for writing" << 
endmsg;
 
 1728       error() << 
"Unable to open ROOT file " << 
filename << 
" for appending" << 
endmsg;
 
 1739     debug() << 
"Opening TFile \"" << 
filename << 
"\"  stream: \"" << 
stream << 
"\"  mode: \"" << typ << 
"\"" 
 1740             << 
" comp level: " << cl << 
endmsg;
 
 1748   TFile*      file = hid.
file;
 
 1761     if ( !gDirectory->GetKey( dir.
c_str() ) ) { gDirectory->mkdir( dir.
c_str() ); }
 
 1762     gDirectory->cd( dir.
c_str() );
 
 1769   std::string::size_type i = dir.
find( 
"/" );
 
 1771   if ( i == std::string::npos ) 
return {};
 
 1785   while ( 
id.find( 
"//" ) != std::string::npos ) { 
id.replace( 
id.find( 
"//" ), 2, 
"/" ); }
 
 1790   TString 
path( (
char*)strstr( target->GetPath(), 
":" ) );
 
 1791   path.Remove( 0, 2 );
 
 1794   TDirectory* current_sourcedir = gDirectory;
 
 1797   TList* lkeys = current_sourcedir->GetListOfKeys();
 
 1798   int    nkeys = lkeys->GetEntries();
 
 1799   TKey*  
key   = 
nullptr;
 
 1800   for ( 
int jj = 0; jj < nkeys; jj++ ) {
 
 1801     key                          = (TKey*)lkeys->At( jj );
 
 1804     TObject* obj = source->Get( pathnameinsource.
c_str() );
 
 1807       if ( obj->IsA()->InheritsFrom( 
"TDirectory" ) ) {
 
 1813         TDirectory* newtargetdir = target->mkdir( obj->GetName(), obj->GetTitle() );
 
 1817       } 
else if ( obj->IsA()->InheritsFrom( 
"TTree" ) ) {
 
 1819         TTree* mytree   = 
dynamic_cast<TTree*
>( obj );
 
 1820         int    nentries = (int)mytree->GetEntries();
 
 1821         mytree->SetBranchStatus( 
"*", 1 );
 
 1825         mytree->CloneTree();
 
 1829         obj->Write( 
key->GetName() );
 
 1836   auto pos = 
id.find( 
"/" );
 
 1838   if ( pos == std::string::npos ) {
 
 1842   } 
else if ( pos != 0 ) {
 
 1849     auto pos2 = 
id.
find( 
"/", pos + 1 );
 
 1851     if ( pos2 == std::string::npos ) {
 
 1853       error() << 
"badly formed Hist/Tree id: \"" << 
id << 
"\"" << 
endmsg;
 
 1859   if ( 
stream == 
"temp" ) {
 
 1866   if ( !file ) { warning() << 
"no stream \"" << 
stream << 
"\" associated with id: \"" << 
id << 
"\"" << 
endmsg; }
 
 1872   auto pos = 
id.find( 
"/" );
 
 1874   if ( pos == std::string::npos ) {
 
 1877   } 
else if ( pos == 0 ) {
 
 1880     root = 
id.substr( 0, pos );
 
 1881     rem  = 
id.
substr( pos + 1 );
 
 1887     debug() << 
"Delaying connection of Input Files until Initialize" 
 1892     debug() << 
"Now connecting of Input Files" << 
endmsg;
 
 1898       if ( 
connect( itr ).isFailure() ) {
 
 1911     debug() << 
"Delaying connection of Output Files until Initialize" 
 1918       if ( 
connect( itr ).isFailure() ) {
 
 1931     debug() << 
"copyFileLayout() to destination path: " << destination->GetPath() << 
endmsg;
 
 1935   TString 
path( (
char*)strstr( destination->GetPath(), 
":" ) );
 
 1936   path.Remove( 0, 2 );
 
 1939   TDirectory* current_source_dir = gDirectory;
 
 1942   TList* key_list = current_source_dir->GetListOfKeys();
 
 1943   int    n        = key_list->GetEntries();
 
 1944   for ( 
int j = 0; j < 
n; ++j ) {
 
 1945     TKey*             k               = (TKey*)key_list->At( j );
 
 1947     TObject*          o               = source->Get( source_pathname.
c_str() );
 
 1949     if ( o && o->IsA()->InheritsFrom( 
"TDirectory" ) ) {
 
 1953       TDirectory* destination_dir = destination->mkdir( o->GetName(), o->GetTitle() );
 
 1954       if ( destination_dir == 
nullptr ) destination_dir = destination->GetDirectory( o->GetName() );
 
 1969   if ( idr.
find( 
"/" ) == 0 ) {
 
 1977       if ( index >= itr->second->size() ) {
 
 1978         error() << 
"no index " << index << 
" found for Hist " << idr << 
endmsg;
 
 1981       hid = &( itr->second->at( index ) );
 
 1987     if ( mitr.first == mitr.second ) {
 
 1990     } 
else if ( distance( mitr.first, mitr.second ) == 1 ) {
 
 1992       if ( index >= mitr.first->second->size() ) {
 
 1993         error() << 
"no index " << index << 
" found for Hist " << idr << 
endmsg;
 
 1996       hid = &( mitr.first->second->at( 0 ) );
 
 2000       hid = &( mitr.first->second->at( 0 ) );
 
 2001       return distance( mitr.first, mitr.second );
 
 2010   ost << 
"m_hlist:  size: " << 
m_hlist.
size() << 
"\n";
 
 2012     ost << 
" - " << vh->at( 0 ) << 
" :: [" << vh << 
"] " << vh->size() << 
" {";
 
 2013     for ( 
auto& e : *vh ) {
 
 2015       ost << 
"[" << o << 
"]";
 
 2023   for ( 
auto& e : 
m_uids ) { ost << 
" - " << e.first << 
"  [" << e.second << 
"]" << 
std::endl; }
 
 2028   for ( 
auto& e : 
m_ids ) { ost << 
" - " << e.first << 
"  [" << e.second << 
"]" << 
std::endl; }
 
 2034     TObject* o = e.first;
 
 2035     THistID& i = e.second.first->at( e.second.second );
 
 2036     ost << 
" - " << o << 
" -> " << i << 
std::endl;
 
 2039   debug() << 
"dumping THistSvc contents\n" << ost.
str() << 
endmsg;
 
 2046   if ( vh->
size() == 1 ) {
 
 2047     debug() << 
"merge: id: \"" << 
name << 
"\" is size 1. nothing to do" << 
endmsg;
 
 2052     error() << 
"merge: id \"" << 
name << 
"\" is not a THn. Cannot merge" << 
endmsg;
 
 2056   TList* 
l = 
new TList();
 
 2057   for ( 
size_t i = 1; i < vh->
size(); ++i ) {
 
 2058     debug() << 
"merge: id: \"" << 
name << 
"\" (" << vh->
at( i ).obj << 
") adding index " << i << 
endmsg;
 
 2059     l->Add( vh->
at( i ).obj );
 
 2062   TH1* t0 = 
dynamic_cast<TH1*
>( vh->
at( 0 ).obj );
 
 2064     error() << 
"merge: could not dcast " << 
name << 
"(" << t0 << 
") index " << 0 << 
" to TH1" << 
endmsg;
 
 2068   Long64_t 
n = t0->Merge( 
l );
 
 2070   debug() << 
"merge: id: \"" << 
name << 
"\" merged " << 
n << 
" entries" << 
endmsg;
 
 2072   for ( 
size_t i = 1; i < vh->
size(); ++i ) {
 
 2073     TH1* th = 
dynamic_cast<TH1*
>( vh->
at( i ).obj );
 
 2075       debug() << 
"clearing index " << i << 
"(" << th << 
")" << 
endmsg;
 
 2076       th->SetDirectory( 
nullptr );
 
 2079       error() << 
"merge: could not dcast " << 
name << 
" index " << i << 
" to TH1" << 
endmsg;