17 #include "boost/algorithm/string/case_conv.hpp" 20 #include "TDirectory.h" 58 template <
typename InputIterator,
typename OutputIterator,
typename UnaryOperation,
typename UnaryPredicate>
59 OutputIterator transform_if( InputIterator first, InputIterator last, OutputIterator result, UnaryOperation op,
60 UnaryPredicate pred ) {
61 while ( first != last ) {
62 if ( pred( *first ) ) *result++ = op( *first );
68 constexpr
struct select1st_t {
69 template <
typename T,
typename S>
106 static TROOT
root(
"root",
"ROOT I/O" );
113 error() <<
"unable to get the IncidentSvc" <<
endmsg;
130 error() <<
"unable to register ROOT file open action with FileMgr" <<
endmsg;
136 error() <<
"unable to register ROOT file open Error action with FileMgr" <<
endmsg;
149 if (
service(
"IoComponentMgr", iomgr,
true ).isFailure() ) {
150 error() <<
"unable to get the IoComponentMgr" <<
endmsg;
154 error() <<
"could not register with the I/O component manager !" <<
endmsg;
157 bool all_good =
true;
159 for (
const auto& reg :
m_files ) {
160 const std::string& fname = reg.second.first->GetName();
164 warning() <<
"could not register file [" << fname <<
"] with the I/O component manager..." <<
endmsg;
167 info() <<
"registered file [" << fname <<
"]... [ok]" <<
endmsg;
171 error() <<
"problem while registering input/output files with " 172 <<
"the I/O component manager !" <<
endmsg;
200 for (
const auto& itr : sorted_uids ) {
201 THistID& thid = itr.second->at( 0 );
202 TObject* tobj = thid.
obj;
205 if ( tobj && tobj->IsA()->InheritsFrom(
"TTree" ) ) {
206 TTree* tree = dynamic_cast<TTree*>( tobj );
207 if ( tree->GetDirectory() != 0 ) {
dirname = tree->GetDirectory()->GetPath(); }
208 }
else if ( tobj && tobj->IsA()->InheritsFrom(
"TGraph" ) ) {
214 if ( id2.
find(
"/" ) == 0 ) { id2.
erase( 0, 1 ); }
219 }
else if ( tobj && tobj->IsA()->InheritsFrom(
"TH1" ) ) {
220 TH1* th = dynamic_cast<TH1*>( tobj );
221 if ( th ==
nullptr ) {
222 error() <<
"Couldn't dcast: " << itr.first <<
endmsg;
224 if ( th->GetDirectory() != 0 ) {
dirname = th->GetDirectory()->GetPath(); }
226 }
else if ( !tobj ) {
239 if (
std::find( deleted_files.
begin(), deleted_files.
end(), itr.second.first ) == deleted_files.
end() ) {
240 deleted_files.
push_back( itr.second.first );
244 debug() <<
"finalizing stream/file " << itr.first <<
":" << itr.second.first->GetName() <<
endmsg;
255 info() <<
"==> File: " << itr.second.first->GetName() <<
" stream: " << itr.first <<
endmsg;
257 itr.second.first->Print(
"base" );
265 if (
service(
"IncidentSvc", pIncidentSvc ).isFailure() ) {
266 error() <<
"Unable to get the IncidentSvc" <<
endmsg;
270 if ( itr.second.second ==
SHARE ) {
272 void* vfile =
nullptr;
281 TFile* outputfile = (TFile*)vfile;
290 error() <<
"unable to open temporary file: \"" << tmpfn <<
endmsg;
294 TFile* inputfile = (TFile*)vfile;
296 outputfile->SetCompressionLevel( inputfile->GetCompressionLevel() );
308 delete itr.second.first;
320 delete obj.second.first;
340 if ( hist_ptr !=
nullptr ) { hist_ptr = hist.
get(); }
350 hist = getHist_i<TH1>(
id, ind );
351 if ( hist !=
nullptr ) {
359 hist = getHist_i<TH2>(
id, ind );
360 if ( hist !=
nullptr ) {
368 hist = getHist_i<TH3>(
id, ind );
369 if ( hist !=
nullptr ) {
403 tree = getHist_i<TTree>(
id );
404 if ( tree !=
nullptr ) {
417 if ( strcmp(
graph->GetName(),
"Graph" ) == 0 ) {
419 std::string::size_type i = id2.
rfind(
"/" );
420 if ( i != std::string::npos ) { id2.
erase( 0, i + 1 ); }
422 info() <<
"setting name of TGraph id: \"" <<
id <<
"\" to \"" << id2 <<
"\" since it is unset" <<
endmsg;
431 if ( strcmp(
graph->GetName(),
"Graph" ) == 0 ) {
433 std::string::size_type i = id2.
rfind(
"/" );
434 if ( i != std::string::npos ) { id2.
erase( 0, i + 1 ); }
436 info() <<
"setting name of TGraph id: \"" <<
id <<
"\" to \"" << id2 <<
"\" since it is unset" <<
endmsg;
444 graph = getHist_i<TGraph>(
id );
445 if (
graph !=
nullptr ) {
467 eff = getHist_i<TEfficiency>(
id );
468 if ( eff !=
nullptr ) {
476 lh = regShared_i<TH1>(
id,
std::move( hist ) );
485 lh = regShared_i<TH2>(
id,
std::move( hist ) );
494 lh = regShared_i<TH3>(
id,
std::move( hist ) );
513 lh = regShared_i<TEfficiency>(
id,
std::move( eff ) );
522 lh = getShared_i<TH1>(
name );
531 lh = getShared_i<TH2>(
name );
540 lh = getShared_i<TH3>(
name );
549 lh = getShared_i<TGraph>(
name );
558 lh = getShared_i<TEfficiency>(
name );
569 error() <<
"Problem deregistering id \"" <<
id <<
"\": not found in registry" <<
endmsg;
574 debug() <<
"will deregister " << vh->
size() <<
" elements of id \"" <<
id <<
"\"" <<
endmsg;
577 size_t vh_size = vh->
size();
578 while ( vh_size-- ) {
579 if (
deReg( vh->
back().obj ).isFailure() ) {
581 error() <<
"Problems deRegistering " << vh->
size() <<
" element of id \"" <<
id <<
"\"" <<
endmsg;
592 vhid_t* vhid = obj_itr->second.first;
593 THistID hid = obj_itr->second.first->at( obj_itr->second.second );
597 error() <<
"Problems deregistering TObject \"" << obj->GetName() <<
"\" with id \"" << hid.
id 598 <<
"\": not in uidMap" <<
endmsg;
602 if ( vhid->
size() == 1 ) {
604 debug() <<
"vhid for " << hid.
id <<
" is empty. deleting" <<
endmsg;
611 [&]( idMap_t::const_reference i ) { return i.second->at( 0 ).obj == obj; } );
612 if ( id_itr == mitr.second ) {
613 error() <<
"Problems deregistering TObject \"" << obj->GetName() <<
"\" with id \"" << hid.
id 614 <<
"\": not in idMap" <<
endmsg;
620 error() <<
"Problems deregistering TObject \"" << obj->GetName() <<
"\" with id \"" << hid.
id 621 <<
"\": not in hlist" <<
endmsg;
625 vhid->
erase( vhid->
begin() + obj_itr->second.second );
634 }
else if ( vhid->
size() > 1 ) {
636 vhid->
erase( vhid->
begin() + obj_itr->second.second );
640 error() <<
"Deregistration failed unexpectedly. (bug in THistSvc?)" <<
endmsg;
644 error() <<
"Cannot unregister TObject \"" << obj->GetName() <<
"\": not known to THistSvc" <<
endmsg;
656 return merge( itr->second );
662 return merge( itr->second.first );
664 error() <<
"merge: unknown object " << obj <<
endmsg;
674 return ( getHist_i<TEfficiency>(
name, 0,
true ) !=
nullptr );
678 return ( getHist_i<TGraph>(
name, 0,
true ) !=
nullptr );
687 []( uidMap_t::const_reference i ) {
return i.second->at( 0 ).obj->IsA()->InheritsFrom(
"TH1" ); } );
695 []( uidMap_t::const_reference i ) {
return i.second->at( 0 ).obj->IsA()->InheritsFrom(
"TTree" ); } );
703 []( uidMap_t::const_reference i ) {
return i.second->at( 0 ).obj->IsA()->InheritsFrom(
"TGraph" ); } );
712 []( uidMap_t::const_reference i ) {
return i.second->at( 0 ).obj->IsA()->InheritsFrom(
"TEfficiency" ); } );
719 gErrorIgnoreLevel = kBreak;
722 error() <<
"getTHists: No such TDirectory \"" << td->GetPath() <<
"\"" <<
endmsg;
727 debug() <<
"getTHists: \"" << td->GetPath() <<
"\": found " << td->GetListOfKeys()->GetSize() <<
" keys" <<
endmsg;
730 TIter nextkey( td->GetListOfKeys() );
731 while ( TKey* key = (TKey*)nextkey() ) {
734 TObject* obj = key->ReadObj();
735 if ( obj != 0 && obj->IsA()->InheritsFrom(
"TDirectory" ) ) {
737 }
else if ( obj != 0 && obj->IsA()->InheritsFrom(
"TH1" ) ) {
740 }
else if ( obj != 0 ) {
748 nextkey = td->GetListOfKeys();
749 while ( TKey* key = (TKey*)nextkey() ) {
750 TObject* obj = key->ReadObj();
751 if ( obj && obj->IsA()->InheritsFrom(
"TDirectory" ) ) {
752 TDirectory* tt = dynamic_cast<TDirectory*>( obj );
765 gErrorIgnoreLevel = kBreak;
774 r2 = itr->second.first->GetName();
779 debug() <<
"getTHists: \"" << dir <<
"\" looks like a stream name." 780 <<
" associated TFile: \"" << itr->second.first->GetName() <<
"\"" <<
endmsg;
783 if ( gDirectory->cd( r2.
c_str() ) ) {
796 if ( !gDirectory->cd( dir.
c_str() ) ) {
797 error() <<
"getTHists: No such TDirectory/stream \"" << dir <<
"\"" <<
endmsg;
809 gErrorIgnoreLevel = kBreak;
812 error() <<
"getTHists: No such TDirectory \"" << td->GetPath() <<
"\"" <<
endmsg;
817 debug() <<
"getTHists: \"" << td->GetPath() <<
"\": found " << td->GetListOfKeys()->GetSize() <<
" keys" <<
endmsg;
820 TIter nextkey( td->GetListOfKeys() );
821 while ( TKey* key = (TKey*)nextkey() ) {
824 TObject* obj = key->ReadObj();
825 if ( obj && obj->IsA()->InheritsFrom(
"TDirectory" ) ) {
827 }
else if ( obj && obj->IsA()->InheritsFrom(
"TH1" ) ) {
836 id =
id +
"/" + key->GetName();
838 id =
id + dir +
"/" + key->GetName();
855 nextkey = td->GetListOfKeys();
856 while ( TKey* key = (TKey*)nextkey() ) {
857 TObject* obj = key->ReadObj();
858 if ( obj && obj->IsA()->InheritsFrom(
"TDirectory" ) ) {
859 TDirectory* tt = dynamic_cast<TDirectory*>( obj );
871 gErrorIgnoreLevel = kBreak;
880 r2 = itr->second.first->GetName();
885 debug() <<
"getTHists: \"" << dir <<
"\" looks like a stream name." 886 <<
" associated TFile: \"" << itr->second.first->GetName() <<
"\"" <<
endmsg;
889 if ( gDirectory->cd( r2.
c_str() ) ) {
891 sc =
getTHists( gDirectory, tl, rcs, reg );
900 if ( !gDirectory->cd( dir.
c_str() ) ) {
901 error() <<
"getTHists: No such TDirectory/stream \"" << dir <<
"\"" <<
endmsg;
905 warning() <<
"Unable to register histograms automatically " 906 <<
"without a valid stream name" <<
endmsg;
909 sc =
getTHists( gDirectory, tl, rcs, reg );
918 gErrorIgnoreLevel = kBreak;
921 error() <<
"getTTrees: No such TDirectory \"" << td->GetPath() <<
"\"" <<
endmsg;
926 debug() <<
"getTHists: \"" << td->GetPath() <<
"\": found " << td->GetListOfKeys()->GetSize() <<
" keys" <<
endmsg;
929 TIter nextkey( td->GetListOfKeys() );
930 while ( TKey* key = (TKey*)nextkey() ) {
933 TObject* obj = key->ReadObj();
934 if ( obj != 0 && obj->IsA()->InheritsFrom(
"TDirectory" ) ) {
936 }
else if ( obj != 0 && obj->IsA()->InheritsFrom(
"TTree" ) ) {
939 }
else if ( obj != 0 ) {
947 nextkey = td->GetListOfKeys();
948 while ( TKey* key = (TKey*)nextkey() ) {
949 TObject* obj = key->ReadObj();
950 if ( obj && obj->IsA()->InheritsFrom(
"TDirectory" ) ) {
951 TDirectory* tt = dynamic_cast<TDirectory*>( obj );
963 gErrorIgnoreLevel = kBreak;
972 r2 = itr->second.first->GetName();
977 debug() <<
"getTTrees: \"" << dir <<
"\" looks like a stream name." 978 <<
" associated TFile: \"" << itr->second.first->GetName() <<
"\"" <<
endmsg;
981 if ( gDirectory->cd( r2.
c_str() ) ) {
return getTTrees( gDirectory, tl, rcs ); }
987 if ( !gDirectory->cd( dir.
c_str() ) ) {
988 error() <<
"getTTrees: No such TDirectory/stream \"" << dir <<
"\"" <<
endmsg;
999 gErrorIgnoreLevel = kBreak;
1002 error() <<
"getTTrees: No such TDirectory \"" << td->GetPath() <<
"\"" <<
endmsg;
1007 debug() <<
"getTHists: \"" << td->GetPath() <<
"\": found " << td->GetListOfKeys()->GetSize() <<
" keys" <<
endmsg;
1010 TIter nextkey( td->GetListOfKeys() );
1011 while ( TKey* key = (TKey*)nextkey() ) {
1014 TObject* obj = key->ReadObj();
1015 if ( obj && obj->IsA()->InheritsFrom(
"TDirectory" ) ) {
1017 }
else if ( obj && obj->IsA()->InheritsFrom(
"TTree" ) ) {
1026 id =
id +
"/" + key->GetName();
1028 id =
id + dir +
"/" + key->GetName();
1037 }
else if ( obj != 0 ) {
1045 nextkey = td->GetListOfKeys();
1046 while ( TKey* key = (TKey*)nextkey() ) {
1047 TObject* obj = key->ReadObj();
1048 if ( obj && obj->IsA()->InheritsFrom(
"TDirectory" ) ) {
1049 TDirectory* tt = dynamic_cast<TDirectory*>( obj );
1061 gErrorIgnoreLevel = kBreak;
1070 r2 = itr->second.first->GetName();
1075 debug() <<
"getTTrees: \"" << dir <<
"\" looks like a stream name." 1076 <<
" associated TFile: \"" << itr->second.first->GetName() <<
"\"" <<
endmsg;
1079 if ( gDirectory->cd( r2.
c_str() ) ) {
1080 return getTTrees( gDirectory, tl, rcs, reg );
1088 if ( !gDirectory->cd( dir.
c_str() ) ) {
1089 error() <<
"getTTrees: No such TDirectory/stream \"" << dir <<
"\"" <<
endmsg;
1093 return getTTrees( gDirectory, tl, rcs, reg );
1099 gErrorIgnoreLevel = kBreak;
1102 error() <<
"getTEfficiencies: No such TDirectory \"" << td->GetPath() <<
"\"" <<
endmsg;
1107 debug() <<
"getTEfficiencies: \"" << td->GetPath() <<
"\": found " << td->GetListOfKeys()->GetSize() <<
" keys" 1111 TIter nextkey( td->GetListOfKeys() );
1112 while ( TKey* key = (TKey*)nextkey() ) {
1115 TObject* obj = key->ReadObj();
1116 if ( obj != 0 && obj->IsA()->InheritsFrom(
"TDirectory" ) ) {
1118 }
else if ( obj != 0 && obj->IsA()->InheritsFrom(
"TEfficiency" ) ) {
1121 }
else if ( obj != 0 ) {
1129 nextkey = td->GetListOfKeys();
1130 while ( TKey* key = (TKey*)nextkey() ) {
1131 TObject* obj = key->ReadObj();
1132 if ( obj && obj->IsA()->InheritsFrom(
"TDirectory" ) ) {
1133 TDirectory* tt = dynamic_cast<TDirectory*>( obj );
1146 gErrorIgnoreLevel = kBreak;
1155 r2 = itr->second.first->GetName();
1160 debug() <<
"getTEfficiencies: \"" << dir <<
"\" looks like a stream name." 1161 <<
" associated TFile: \"" << itr->second.first->GetName() <<
"\"" <<
endmsg;
1164 if ( gDirectory->cd( r2.
c_str() ) ) {
1177 if ( !gDirectory->cd( dir.
c_str() ) ) {
1178 error() <<
"getTEfficiencies: No such TDirectory/stream \"" << dir <<
"\"" <<
endmsg;
1190 gErrorIgnoreLevel = kBreak;
1193 error() <<
"getTEfficiencies: No such TDirectory \"" << td->GetPath() <<
"\"" <<
endmsg;
1198 debug() <<
"getTEfficiencies: \"" << td->GetPath() <<
"\": found " << td->GetListOfKeys()->GetSize() <<
" keys" 1202 TIter nextkey( td->GetListOfKeys() );
1203 while ( TKey* key = (TKey*)nextkey() ) {
1206 TObject* obj = key->ReadObj();
1207 if ( obj && obj->IsA()->InheritsFrom(
"TDirectory" ) ) {
1209 }
else if ( obj && obj->IsA()->InheritsFrom(
"TEfficiency" ) ) {
1218 id =
id +
"/" + key->GetName();
1220 id =
id + dir +
"/" + key->GetName();
1237 nextkey = td->GetListOfKeys();
1238 while ( TKey* key = (TKey*)nextkey() ) {
1239 TObject* obj = key->ReadObj();
1240 if ( obj && obj->IsA()->InheritsFrom(
"TDirectory" ) ) {
1241 TDirectory* tt = dynamic_cast<TDirectory*>( obj );
1253 gErrorIgnoreLevel = kBreak;
1262 r2 = itr->second.first->GetName();
1267 debug() <<
"getTEfficiencies: \"" << dir <<
"\" looks like a stream name." 1268 <<
" associated TFile: \"" << itr->second.first->GetName() <<
"\"" <<
endmsg;
1271 if ( gDirectory->cd( r2.
c_str() ) ) {
1282 if ( !gDirectory->cd( dir.
c_str() ) ) {
1283 error() <<
"getTEfficiencies: No such TDirectory/stream \"" << dir <<
"\"" <<
endmsg;
1287 warning() <<
"Unable to register histograms automatically " 1288 <<
"without a valid stream name" <<
endmsg;
1305 Long64_t mfs = (Long64_t)
m_maxFileSize.value() * (Long64_t)1048576;
1306 Long64_t mfs_warn = mfs * 95 / 100;
1310 for (
const auto& f :
m_files ) {
1311 TFile* tf = f.second.first;
1315 debug() <<
"stream: " << f.first <<
" name: " << tf->GetName() <<
" size: " << tf->GetSize() <<
endmsg;
1320 if ( tf->GetSize() > mfs ) {
1324 fatal() <<
"file \"" << tf->GetName() <<
"\" associated with stream \"" << f.first
1325 <<
"\" has exceeded the max file size of " <<
m_maxFileSize.value() <<
"MB. Terminating Job." <<
endmsg;
1328 if (
service(
"ApplicationMgr",
evt,
true ).isSuccess() ) {
1329 evt->stopRun().ignore( );
1334 }
else if ( tf->GetSize() > mfs_warn ) {
1335 warning() <<
"file \"" << tf->GetName() <<
"\" associated with stream \"" << f.first
1336 <<
"\" is at 95% of its maximum allowable file size of " <<
m_maxFileSize.value() <<
"MB" <<
endmsg;
1345 bool all_good =
true;
1352 if (
service(
"IoComponentMgr", iomgr,
true ).isFailure() ) {
1353 error() <<
"could not retrieve I/O component manager !" <<
endmsg;
1360 gErrorIgnoreLevel = kFatal;
1362 for (
auto& ifile :
m_files ) {
1363 TFile* f = ifile.second.first;
1366 debug() <<
"file [" << fname <<
"] mode: [" << f->GetOption() <<
"] r:" << f->GetFileBytesRead()
1367 <<
" w:" << f->GetFileBytesWritten() <<
" cnt:" << f->GetFileCounter() <<
endmsg;
1370 if ( ifile.second.second ==
READ ) {
1375 if ( !iomgr->
io_retrieve(
this, fname ).isSuccess() ) {
1376 error() <<
"could not retrieve new name for [" << fname <<
"] !!" <<
endmsg;
1379 }
else if ( fname.
empty() ) {
1387 Option_t*
opts = f->GetOption();
1390 error() <<
"unable to open file \"" << fname <<
"\" for writing" <<
endmsg;
1393 TFile* newfile = (TFile*)vf;
1394 newfile->SetOption(
opts );
1398 ifile.second.first = newfile;
1402 for (
auto& uid :
m_uids ) {
1403 for (
auto& hid : *uid.second ) {
1404 if ( hid.file != f )
continue;
1405 TDirectory* olddir = this->
changeDir( hid );
1408 TDirectory* newdir = this->
changeDir( hid );
1409 TClass* cl = hid.obj->IsA();
1413 if ( cl->InheritsFrom(
"TTree" ) ) {
1414 dynamic_cast<TTree*>( hid.obj )->SetDirectory( newdir );
1415 dynamic_cast<TTree*>( hid.obj )->Reset();
1416 }
else if ( cl->InheritsFrom(
"TH1" ) ) {
1417 dynamic_cast<TH1*>( hid.obj )->SetDirectory( newdir );
1418 dynamic_cast<TH1*>( hid.obj )->Reset();
1419 }
else if ( cl->InheritsFrom(
"TEfficiency" ) ) {
1420 dynamic_cast<TEfficiency*>( hid.obj )->SetDirectory( newdir );
1421 }
else if ( cl->InheritsFrom(
"TGraph" ) ) {
1422 olddir->Remove( hid.obj );
1423 newdir->Append( hid.obj );
1425 error() <<
"id: \"" << hid.id <<
"\" is not a inheriting from a class " 1426 <<
"we know how to handle (received [" << cl->GetName() <<
"], " 1427 <<
"expected [TTree, TH1, TGraph or TEfficiency]) !" <<
endmsg <<
"attaching to current dir [" 1428 << newdir->GetPath() <<
"] " 1429 <<
"nonetheless..." <<
endmsg;
1430 olddir->Remove( hid.obj );
1431 newdir->Append( hid.obj );
1435 f->ReOpen(
"READ" );
1452 gDirectory = m_gDirectory;
1454 gErrorIgnoreLevel = m_gErrorIgnoreLevel;
1459 template <
typename T>
1461 return dynamic_cast<T*>( readHist_i<T>(
id ) );
1475 for (
auto& hid : *( uitr->second ) ) {
1478 verbose() <<
" update: " << uitr->first <<
" " << hid.id <<
" " << hid.mode <<
endmsg;
1480 TObject* to = hid.obj;
1481 TFile* oldFile = hid.file;
1484 }
else if ( hid.temp || hid.mode ==
READ ) {
1490 }
else if ( to->IsA()->InheritsFrom(
"TTree" ) ) {
1491 TTree* tr = dynamic_cast<TTree*>( to );
1492 TFile* newFile = tr->GetCurrentFile();
1494 if ( oldFile != newFile ) {
1497 TFile* dummy =
nullptr;
1498 findStream( hid.id, streamName, rem, dummy );
1501 if ( itr.second.first == oldFile ) { itr.second.first = newFile; }
1504 for (
auto uitr2 = uitr; uitr2 !=
m_uids.
end(); ++uitr2 ) {
1505 for (
auto& hid2 : *( uitr2->second ) ) {
1506 if ( hid2.file == oldFile ) { hid2.file = newFile; }
1511 [&]( streamMap::const_reference
s ) {
return s.second == streamName; } );
1516 debug() <<
"migrating uid: " << hid.id <<
" stream: " << streamName <<
" oldFile: " << oldFileName
1517 <<
" newFile: " << newFileName <<
endmsg;
1521 if ( !oldFileName.
empty() ) {
1526 debug() <<
"changing filename \"" << i->first <<
"\" to \"" << newFileName <<
"\" for stream \"" 1527 << i->second <<
"\"" <<
endmsg;
1535 error() <<
"Problems updating fileStreams with new file name" <<
endmsg;
1547 auto mode = i.second.second;
1548 auto file = i.second.first;
1550 file->Write(
"", TObject::kOverwrite );
1551 }
else if ( mode ==
APPEND ) {
1557 debug() <<
"THistSvc::writeObjectsToFile()::List of Files connected in ROOT " <<
endmsg;
1558 TSeqCollection* filelist = gROOT->GetListOfFiles();
1559 for (
int ii = 0; ii < filelist->GetEntries(); ii++ ) {
1560 debug() <<
"THistSvc::writeObjectsToFile()::List of Files connected in ROOT: \"" << filelist->At( ii )->GetName()
1569 auto loc = ident.
find(
" " );
1577 if ( loc != std::string::npos ) {
1579 for (
auto attrib : Parser( ident.
substr( loc + 1 ) ) ) {
1580 auto TAG = boost::algorithm::to_upper_copy( attrib.tag );
1581 auto VAL = boost::algorithm::to_upper_copy( attrib.value );
1583 if ( TAG ==
"FILE" || TAG ==
"DATAFILE" ) {
1586 }
else if ( TAG ==
"OPT" ) {
1587 if ( VAL ==
"APPEND" || VAL ==
"UPDATE" ) {
1589 }
else if ( VAL ==
"CREATE" || VAL ==
"NEW" || VAL ==
"WRITE" ) {
1591 }
else if ( VAL ==
"RECREATE" ) {
1593 }
else if ( VAL ==
"SHARE" ) {
1595 }
else if ( VAL ==
"OLD" || VAL ==
"READ" ) {
1598 error() <<
"Unknown OPT: \"" << attrib.value <<
"\"" <<
endmsg;
1601 }
else if ( TAG ==
"TYP" ) {
1603 }
else if ( TAG ==
"CL" ) {
1611 if ( stream ==
"temp" ) {
1612 error() <<
"in JobOption \"" << ident <<
"\": stream name \"temp\" reserved." <<
endmsg;
1616 if ( db_typ !=
"ROOT" ) {
1617 error() <<
"in JobOption \"" << ident <<
"\": technology type \"" << db_typ <<
"\" not supported." <<
endmsg;
1622 error() <<
"in JobOption \"" << ident <<
"\":\n stream \"" << stream <<
"\" already connected to file: \"" 1629 error() <<
"No OPT= specified or unknown access mode in: " << ident <<
endmsg;
1637 const std::string& oldstream = fitr.first->second;
1639 const auto& f_info =
m_files[oldstream];
1641 if ( newMode != f_info.second ) {
1642 error() <<
"in JobOption \"" << ident <<
"\":\n file \"" <<
filename <<
"\" already opened by stream: \"" 1643 << oldstream <<
"\" with different access mode." <<
endmsg;
1646 TFile* f2 = f_info.first;
1649 debug() <<
"Connecting stream: \"" << stream <<
"\" to previously opened TFile: \"" <<
filename <<
"\"" 1656 if (
service(
"IncidentSvc",
pi ).isFailure() ) {
1657 error() <<
"Unable to get the IncidentSvc" <<
endmsg;
1704 static int ishared = 0;
1709 debug() <<
"Creating temp file \"" <<
filename <<
"\" and realfilename=" << realfilename <<
endmsg;
1738 debug() <<
"Opening TFile \"" <<
filename <<
"\" stream: \"" << stream <<
"\" mode: \"" << typ <<
"\"" 1739 <<
" comp level: " << cl <<
endmsg;
1747 TFile* file = hid.
file;
1760 if ( !gDirectory->GetKey( dir.
c_str() ) ) { gDirectory->mkdir( dir.
c_str() ); }
1761 gDirectory->cd( dir.
c_str() );
1768 std::string::size_type i = dir.
find(
"/" );
1770 if ( i == std::string::npos )
return {};
1784 while (
id.find(
"//" ) != std::string::npos ) {
id.replace(
id.find(
"//" ), 2,
"/" ); }
1789 TString
path( (
char*)strstr( target->GetPath(),
":" ) );
1790 path.Remove( 0, 2 );
1793 TDirectory* current_sourcedir = gDirectory;
1796 TList* lkeys = current_sourcedir->GetListOfKeys();
1797 int nkeys = lkeys->GetEntries();
1798 TKey* key =
nullptr;
1799 for (
int jj = 0; jj < nkeys; jj++ ) {
1800 key = (TKey*)lkeys->At( jj );
1803 TObject* obj = source->Get( pathnameinsource.
c_str() );
1806 if ( obj->IsA()->InheritsFrom(
"TDirectory" ) ) {
1812 TDirectory* newtargetdir = target->mkdir( obj->GetName(), obj->GetTitle() );
1816 }
else if ( obj->IsA()->InheritsFrom(
"TTree" ) ) {
1818 TTree* mytree = dynamic_cast<TTree*>( obj );
1819 int nentries = (int)mytree->GetEntries();
1820 mytree->SetBranchStatus(
"*", 1 );
1824 mytree->CloneTree();
1828 obj->Write( key->GetName() );
1835 auto pos =
id.find(
"/" );
1837 if ( pos == std::string::npos ) {
1841 }
else if ( pos != 0 ) {
1848 auto pos2 =
id.
find(
"/", pos + 1 );
1850 if ( pos2 == std::string::npos ) {
1852 error() <<
"badly formed Hist/Tree id: \"" <<
id <<
"\"" <<
endmsg;
1858 if ( stream ==
"temp" ) {
1865 if ( !file ) {
warning() <<
"no stream \"" << stream <<
"\" associated with id: \"" <<
id <<
"\"" <<
endmsg; }
1871 auto pos =
id.find(
"/" );
1873 if ( pos == std::string::npos ) {
1876 }
else if ( pos == 0 ) {
1879 root =
id.substr( 0, pos );
1880 rem =
id.
substr( pos + 1 );
1886 debug() <<
"Delaying connection of Input Files until Initialize" 1891 debug() <<
"Now connecting of Input Files" <<
endmsg;
1910 debug() <<
"Delaying connection of Input Files until Initialize" 1930 debug() <<
"copyFileLayout() to destination path: " << destination->GetPath() <<
endmsg;
1934 TString
path( (
char*)strstr( destination->GetPath(),
":" ) );
1935 path.Remove( 0, 2 );
1938 TDirectory* current_source_dir = gDirectory;
1941 TList* key_list = current_source_dir->GetListOfKeys();
1942 int n = key_list->GetEntries();
1943 for (
int j = 0; j <
n; ++j ) {
1944 TKey* k = (TKey*)key_list->At( j );
1946 TObject* o = source->Get( source_pathname.
c_str() );
1948 if ( o && o->IsA()->InheritsFrom(
"TDirectory" ) ) {
1952 TDirectory* destination_dir = destination->mkdir( o->GetName(), o->GetTitle() );
1953 if ( destination_dir ==
nullptr ) destination_dir = destination->GetDirectory( o->GetName() );
1968 if ( idr.
find(
"/" ) == 0 ) {
1976 if ( index >= itr->second->size() ) {
1977 error() <<
"no index " << index <<
" found for Hist " << idr <<
endmsg;
1980 hid = &( itr->second->at( index ) );
1986 if ( mitr.first == mitr.second ) {
1989 }
else if ( distance( mitr.first, mitr.second ) == 1 ) {
1991 if ( index >= mitr.first->second->size() ) {
1992 error() <<
"no index " << index <<
" found for Hist " << idr <<
endmsg;
1995 hid = &( mitr.first->second->at( 0 ) );
1999 hid = &( mitr.first->second->at( 0 ) );
2000 return distance( mitr.first, mitr.second );
2009 ost <<
"m_hlist: size: " <<
m_hlist.
size() <<
"\n";
2011 ost <<
" - " << vh->at( 0 ) <<
" :: [" << vh <<
"] " << vh->size() <<
" {";
2012 for (
auto& e : *vh ) {
2014 ost <<
"[" << o <<
"]";
2022 for (
auto& e :
m_uids ) { ost <<
" - " << e.first <<
" [" << e.second <<
"]" <<
std::endl; }
2027 for (
auto& e :
m_ids ) { ost <<
" - " << e.first <<
" [" << e.second <<
"]" <<
std::endl; }
2033 TObject* o = e.first;
2034 THistID& i = e.second.first->at( e.second.second );
2035 ost <<
" - " << o <<
" -> " << i <<
std::endl;
2045 if ( vh->
size() == 1 ) {
2046 debug() <<
"merge: id: \"" <<
name <<
"\" is size 1. nothing to do" <<
endmsg;
2050 if ( !vh->
at( 0 ).obj->IsA()->InheritsFrom(
"TH1" ) ) {
2051 error() <<
"merge: id \"" <<
name <<
"\" is not a THn. Cannot merge" <<
endmsg;
2055 TList*
l =
new TList();
2056 for (
size_t i = 1; i < vh->
size(); ++i ) {
2057 debug() <<
"merge: id: \"" <<
name <<
"\" (" << vh->
at( i ).obj <<
") adding index " << i <<
endmsg;
2058 l->Add( vh->
at( i ).obj );
2061 TH1* t0 = dynamic_cast<TH1*>( vh->
at( 0 ).obj );
2063 error() <<
"merge: could not dcast " <<
name <<
"(" << t0 <<
") index " << 0 <<
" to TH1" <<
endmsg;
2067 Long64_t
n = t0->Merge(
l );
2069 debug() <<
"merge: id: \"" <<
name <<
"\" merged " <<
n <<
" entries" <<
endmsg;
2071 for (
size_t i = 1; i < vh->
size(); ++i ) {
2072 TH1* th = dynamic_cast<TH1*>( vh->
at( i ).obj );
2074 debug() <<
"clearing index " << i <<
"(" << th <<
")" <<
endmsg;
2075 th->SetDirectory(
nullptr );
2078 error() <<
"merge: could not dcast " <<
name <<
" index " << i <<
" to TH1" <<
endmsg;
Parse attribute strings allowing iteration over the various attributes.
bool existsEfficiency(const std::string &name) const override
Check if TEfficiency with given name is managed by THistSvcMT.
GlobalDirectoryRestore(THistSvcMutex_t &mut)
Helper struct that bundles the histogram ID with a mutex, TFile and TObject*.
StatusCode initialize() override
void MergeRootFile(TDirectory *, TDirectory *)
std::vector< std::string > getTrees() const override
This class is the FileIncident.
StatusCode initialize() override
StatusCode deReg(const std::string &name) override
Deregister object with given name and give up ownership (without deletion!)
Define general base for Gaudi exception.
virtual Io::open_t open(const Io::IoTech &, const std::string &caller, const std::string &fname, const Io::IoFlags &, Io::Fd &, void *&, const std::string &desc, const bool shared=false)=0
StatusCode finalize() override
Gaudi::StateMachine::State FSMState() const override
MsgStream & warning() const
shortcut for the method msgStream(MSG::WARNING)
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.
std::vector< std::string > getEfficiencies() const override
This file contains the class definition for the FileIncident class.
StatusCode getShared(const std::string &name, LockedHandle< TH1 > &) const override
Retrieve shared object with given name as TH1 through LockedHandle.
T * readHist(const std::string &name) const
StatusCode getTEfficiencies(TDirectory *td, TList &, bool recurse=false) const override
StatusCode getTTrees(TDirectory *td, TList &, bool recurse=false) const override
const std::string & name() const
StatusCode writeObjectsToFile()
constexpr static const auto SUCCESS
StatusCode merge(const std::string &id) override
Merge all clones for object with a given id.
StatusCode getGraph(const std::string &name, TGraph *&) const override
Return TGraph with given name.
bool existsGraph(const std::string &name) const override
Check if graph with given name is managed by THistSvcMT.
StatusCode rootOpenAction(FILEMGR_CALLBACK_ARGS)
void copyFileLayout(TDirectory *, TDirectory *)
helper function to recursively copy the layout of a TFile into a new TFile
MsgStream & info() const
shortcut for the method msgStream(MSG::INFO)
std::string stripDirectoryName(std::string &dir) const
bool findStream(const std::string &name, std::string &root, std::string &rem, TFile *&file) const
Gaudi::Property< std::vector< std::string > > m_outputfile
StatusCode getTHists(TDirectory *td, TList &, bool recurse=false) const override
MSG::Level msgLevel() const
get the cached level (originally extracted from the embedded MsgStream)
virtual StatusCode regAction(Io::bfcn_action_t, const Io::Action &, const std::string &d="")=0
#define DECLARE_COMPONENT(type)
void setupOutputFile()
call-back method to handle output stream property
void parseString(const std::string &id, std::string &root, std::string &rem) const
void setupInputFile()
call-back method to handle input stream property
const std::string & name() const override
Retrieve name of the service.
Gaudi::Property< int > m_autoSave
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
virtual void fireIncident(const Incident &incident)=0
Fire an Incident.
Gaudi::Property< std::vector< std::string > > m_inputfile
StatusCode getTree(const std::string &name, TTree *&) const override
Return TTree with given name.
This class is used for returning status codes from appropriate routines.
Provides automatic lock/unlock access to a class upon deref of ptr.
Gaudi::Property< bool > m_print
void handle(const Incident &) override
Gaudi::Property< int > m_maxFileSize
std::vector< std::string > getHists() const override
MsgStream & verbose() const
shortcut for the method msgStream(MSG::VERBOSE)
static Mode charToMode(const char typ)
Convert a char to a Mode enum.
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
~GlobalDirectoryRestore()
TDirectory * changeDir(const THistSvc::THistID &hid) const
StatusCode rootOpenErrAction(FILEMGR_CALLBACK_ARGS)
bool existsHist(const std::string &name) const override
Check if histogram with given name is managed by THistSvcMT.
StatusCode finalize() override
bool existsTree(const std::string &name) const override
Check if tree with given name is managed by THistSvcMT.
StatusCode regHist_i(std::unique_ptr< T > hist, const std::string &name, bool shared)
const std::string & desc() const
StatusCode regHist(const std::string &name) override
Register a new ROOT histogram TH*X with a name.
StatusCode getHist(const std::string &name, TH1 *&, size_t index=0) const override
Return histogram with given name as TH1*, THistSvcMT still owns object.
virtual std::vector< std::string > io_retrieve(IIoComponent *iocomponent)=0
: retrieve all registered filenames for a given IIoComponent
const StatusCode & ignore() const
Ignore/check StatusCode.
StatusCode regEfficiency(const std::string &name) override
Register a new TEfficiency with a given name.
StatusCode reinitialize() override
T back_inserter(T... args)
void removeDoubleSlash(std::string &) const
Base class for all Incidents (computing events).
virtual void addListener(IIncidentListener *lis, const std::string &type="", long priority=0, bool rethrow=false, bool singleShot=false)=0
Add listener.
std::map< std::string, std::pair< TFile *, Mode > > m_files
StatusCode connect(const std::string &)
constexpr static const auto FAILURE
The IEventProcessor is the interface to process events.
virtual StatusCode io_register(IIoComponent *iocomponent)=0
: allow a IIoComponent to register itself with this manager so appropriate actions can be taken when ...
std::set< std::string > m_alreadyConnectedOutFiles
list of already connected files.
StatusCode regTree(const std::string &name) override
Register a new TTree with a given name.
std::map< std::string, std::string > m_sharedFiles
StatusCode service(const std::string &name, const T *&psvc, bool createIf=true) const
Access a service by name, creating it if it doesn't already exist.
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...
MsgStream & err() const
shortcut for the method msgStream(MSG::ERROR)
AttribStringParser::Iterator begin(const AttribStringParser &parser)
std::set< std::string > m_alreadyConnectedInFiles
list of already connected files.
StatusCode getEfficiency(const std::string &name, TEfficiency *&) const override
Return TEfficiency with given name.
StatusCode regGraph(const std::string &name) override
Register a new TGraph with a given name.
Gaudi::Property< int > m_autoFlush
StatusCode io_reinit() override
callback method to reinitialize the internal state of the component for I/O purposes (e....
size_t findHistID(const std::string &id, const THistID *&hid, const size_t &index=0) const
MsgStream & fatal() const
shortcut for the method msgStream(MSG::FATAL)
TTree * readTree(const std::string &name) const
Helper class that manages ROOts global directory and file.
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
TDirectory * m_gDirectory
The interface implemented by the IncidentSvc service.
void updateFiles()
Handle case where TTree grows beyond TTree::fgMaxTreeSize.
std::vector< std::string > getGraphs() const override
T emplace_back(T... args)
virtual Io::close_t close(const Io::Fd, const std::string &caller)=0