21#include <TEfficiency.h>
33class THistSvc :
public extends<Service, ITHistSvc, IIncidentListener, IIoComponent> {
146 bool exists(
const std::string&
name )
const override;
161 std::vector<std::string>
getHists()
const override;
162 std::vector<std::string>
getTrees()
const override;
163 std::vector<std::string>
getGraphs()
const override;
168 StatusCode getTHists( TDirectory* td, TList& tl,
bool recurse =
false,
bool reg =
false )
override;
173 StatusCode getTTrees( TDirectory* td, TList& tl,
bool recurse =
false,
bool reg =
false )
override;
251 ost <<
"id: " << hid.
id <<
" t: " << hid.
temp <<
" s: " << hid.
shared <<
" M: " << hid.
mode <<
" m: " << hid.
mutex
252 <<
" o: " << hid.
obj <<
" T: " <<
static_cast<int>( hid.
type ) <<
" " << hid.
obj->IsA()->GetName();
276 typedef std::unordered_map<std::string, vhid_t*>
uidMap_t;
278 typedef std::unordered_multimap<std::string, vhid_t*>
idMap_t;
279 typedef std::unordered_map<TObject*, std::pair<vhid_t*, size_t>>
objMap_t;
288 std::map<std::string, std::pair<TFile*, Mode>>
m_files;
289 typedef std::multimap<std::string, std::string>
streamMap;
300 template <
typename T>
302 template <
typename T>
304 template <
typename T>
305 T*
getHist_i(
const std::string&
name,
const size_t& ind = 0,
bool quiet =
false )
const;
306 template <
typename T>
309 template <
typename T>
311 template <
typename T>
319 template <
typename T>
333 bool findStream(
const std::string&
name, std::string& root, std::string& rem, TFile*& file )
const;
334 void parseString(
const std::string&
id, std::string& root, std::string& rem )
const;
345 size_t findHistID(
const std::string&
id,
const THistID*& hid,
const size_t& index = 0 )
const;
366 "maximum file size in MB. if exceeded,"
367 " will cause an abort. -1 to never check." };
370 <<
"\"CompressionLevel\" Property has been deprecated. "
371 <<
"Set it via the \"CL=\" parameter in the \"Output\" Property"
396 return regHist_i( std::move( hist ),
id, shared, hid );
406 if ( hist_unique.get() !=
nullptr ) { hist = hist_unique.release(); }
408 debug() <<
"regHist_i obj: " << hist <<
" id: " <<
id <<
" s: " << shared <<
endmsg;
411 std::string idr(
id );
414 if ( idr.find(
"/" ) == idr.length() ) {
415 error() <<
"Badly formed identifier \"" << idr <<
"\": "
416 <<
"Must not end with a /" <<
endmsg;
422 std::string stream,
name;
424 error() <<
"Could not register id: \"" << idr <<
"\"" <<
endmsg;
429 std::string uid =
"/" + stream +
"/" +
name;
431 uidMap_t::iterator uitr =
m_uids.find( uid );
433 if ( uitr !=
m_uids.end() ) {
435 TObject*
t1 = uitr->second->at( 0 ).obj;
436 if ( hist->Compare(
t1 ) != 0 ) {
437 error() <<
"previously registered object with identifier \"" << uid <<
"\" does not compare to this one"
443 debug() <<
"previously registered id \"" << uid <<
"\": num " << uitr->second->size() <<
endmsg;
454 TObject* to =
nullptr;
457 if ( !temp &&
m_files.find( stream )->second.second ==
READ ) {
458 if ( hist != 0 ) {
warning() <<
"Registering id: \"" << idr <<
"\" with non zero pointer!" <<
endmsg; }
461 if ( hist ==
nullptr ) {
466 to =
dynamic_cast<TObject*
>( hist );
467 hid =
THistID( uid, temp, to, f,
m_files.find( stream )->second.second );
468 }
else if ( !hist ) {
469 error() <<
"Unable to read in hist with id: \"" << idr <<
"\"" <<
endmsg;
473 to =
dynamic_cast<TObject*
>( hist );
474 if ( to ==
nullptr ) {
475 error() <<
"Could not dcast to TObject. id: \"" << idr <<
"\"" <<
endmsg;
480 auto oitr =
m_tobjs.find( to );
482 error() <<
"already registered id: \"" << idr <<
"\" with identifier \""
483 << oitr->second.first->at( oitr->second.second ).id <<
"\"" <<
endmsg;
489 const auto findF =
m_files.find( stream );
490 hid = ( findF !=
m_files.end() ?
THistID( uid, temp, to, f, findF->second.second ) :
THistID( uid, temp, to, f ) );
495 if ( TTree* tree =
dynamic_cast<TTree*
>( hist ) ) {
496 tree->SetDirectory( dir );
499 }
else if (
TH1* th1 =
dynamic_cast<TH1*
>( hist ) ) {
500 th1->SetDirectory( dir );
502 }
else if ( TEfficiency* teff =
dynamic_cast<TEfficiency*
>( hist ) ) {
503 teff->SetDirectory( dir );
505 }
else if (
dynamic_cast<TGraph*
>( hist ) ) {
509 error() <<
"id: \"" << idr <<
"\" is not a TH, TTree, TGraph, or TEfficiency. Attaching it to current dir."
519 fname = f->GetName();
524 << hist->GetTitle() <<
"\" id: \"" << uid
534 vhid_t* vi = uitr->second;
535 vi->push_back( hid );
536 phid = &( vi->back() );
538 m_tobjs.emplace( to, std::pair<vhid_t*, size_t>( vi, vi->size() - 1 ) );
543 phid = &( vi->back() );
544 m_uids.emplace( uid, vi );
547 m_tobjs.emplace( to, std::pair<vhid_t*, size_t>( vi, 0 ) );
566 if ( !quiet ) {
error() <<
"could not locate Hist with id \"" <<
id <<
"\"" <<
endmsg; }
568 }
else if ( num > 1 ) {
571 error() <<
"Multiple matches with id \"" <<
id <<
"\"."
572 <<
" Further specifications required." <<
endmsg;
575 info() <<
"Found multiple matches with id \"" <<
id <<
"\"" <<
endmsg;
577 hist =
dynamic_cast<T*
>( hid->
obj );
578 if ( hist ==
nullptr ) {
579 error() <<
"dcast failed, Hist id: \"" <<
id <<
"\"" <<
endmsg;
584 hist =
dynamic_cast<T*
>( hid->
obj );
585 if ( hist ==
nullptr ) {
586 error() <<
"dcast failed, Hist id: \"" <<
id <<
"\"" <<
endmsg;
590 verbose() <<
"found unique Hist title: \"" << hist->GetTitle() <<
"\" id: \"" <<
id <<
"\"" <<
endmsg;
601 std::string idr(
id );
604 std::string stream, rem, dir, fdir, bdir, fdir2;
605 TFile* file =
nullptr;
607 if ( !
findStream( idr, stream, rem, file ) ) {
return nullptr; }
620 if ( !gDirectory->GetKey( dir.c_str() ) ) {
621 error() <<
"Directory \"" << fdir2 <<
"\" doesnt exist in " << file->GetName() <<
endmsg;
624 gDirectory->cd( dir.c_str() );
627 TObject* to =
nullptr;
628 gDirectory->GetObject( fdir.c_str(), to );
631 error() <<
"Could not get obj \"" << fdir <<
"\" in " << gDirectory->GetPath() <<
endmsg;
635 T* hist =
dynamic_cast<T*
>( to );
636 if ( hist ==
nullptr ) {
638 << to->IsA()->GetName() <<
endmsg;
643 debug() <<
"Read in " << hist->IsA()->GetName() <<
" \"" << hist->GetName() <<
"\" from file " << file->GetName()
656 T* phist = hist.get();
658 if (
regHist_i( std::move( hist ),
id,
true, phid ).isSuccess() ) {
662 error() <<
"regSharedHist: unable to register shared hist with id \"" <<
id <<
"\"" <<
endmsg;
666 error() <<
"regSharedHist: previously register Hist with id \"" <<
id <<
"\" was not marked shared" <<
endmsg;
669 if ( hist->Compare( hid->
obj ) != 0 ) {
670 error() <<
"regSharedHist: Histogram " <<
id <<
" does not compare with " << hid <<
endmsg;
672 T* phist =
dynamic_cast<T*
>( hid->
obj );
674 error() <<
"regSharedHist: unable to dcast retrieved shared hist \"" <<
id <<
"\" of type "
678 delete hist.release();
696 error() <<
"getSharedHist: found Hist with id \"" <<
name <<
"\", but it's not marked as shared" <<
endmsg;
699 T* h1 =
dynamic_cast<T*
>( hid->
obj );
703 }
else if ( i == 0 ) {
704 error() <<
"no histograms matching id \"" <<
name <<
"\" found" <<
endmsg;
706 info() <<
"multiple matches for id \"" <<
name <<
"\" found [" << i <<
"], probably from different streams"
#define FILEMGR_CALLBACK_ARGS
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
TemplatedAlg< int, std::vector< std::string > > t1
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 & debug() const
shortcut for the method msgStream(MSG::DEBUG)
MsgStream & info() const
shortcut for the method msgStream(MSG::INFO)
MSG::Level msgLevel() const
Implementation of property with value of concrete type.
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Base class for all Incidents (computing events).
Provides automatic lock/unlock access to a class upon deref of ptr.
void set(T *ptr, MutexType *mut)
Handle to be used in lieu of naked pointers to services.
const std::string & name() const override
Retrieve name of the service.
This class is used for returning status codes from appropriate routines.
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
Mode
Enumerating all possible file access modes.
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
std::vector< std::string > m_Wstream
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
Gaudi::Property< int > m_compressionLevel
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 &)
std::unordered_multimap< std::string, vhid_t * > idMap_t
StatusCode regHist_i(std::unique_ptr< T > hist, const std::string &name, bool shared)
Gaudi::Property< std::vector< std::string > > m_inputfile
std::unordered_map< std::string, vhid_t * > uidMap_t
ObjectType
Possible TObject types.
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::list< vhid_t * > hlist_t
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
std::multimap< std::string, std::string > streamMap
void parseString(const std::string &id, std::string &root, std::string &rem) const
std::vector< std::string > m_Rstream
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
std::unordered_map< TObject *, std::pair< vhid_t *, size_t > > objMap_t
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)
Base class used to extend a class implementing other interfaces.
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Helper struct that bundles the histogram ID with a mutex, TFile and TObject*.
bool operator<(THistID const &rhs) const
THistID(const THistID &rhs)=default
THistID(std::string &i, bool &t, TObject *o, TFile *f)
THistID & operator=(const THistID &rhs)=default
friend std::ostream & operator<<(std::ostream &ost, const THistID &hid)
THistID(std::string &i, bool &t, TObject *o, TFile *f, Mode m)