21#include <TEfficiency.h>
34class THistSvc :
public extends<Service, ITHistSvc, IIncidentListener, IIoComponent> {
147 bool exists(
const std::string&
name )
const override;
162 std::vector<std::string>
getHists()
const override;
163 std::vector<std::string>
getTrees()
const override;
164 std::vector<std::string>
getGraphs()
const override;
169 StatusCode getTHists( TDirectory* td, TList& tl,
bool recurse =
false,
bool reg =
false )
override;
174 StatusCode getTTrees( TDirectory* td, TList& tl,
bool recurse =
false,
bool reg =
false )
override;
255 ost <<
"id: " << hid.
id <<
" t: " << hid.
temp <<
" s: " << hid.
shared <<
" M: " << hid.
mode
256 <<
" m: " << hid.
mutex.get() <<
" o: " << hid.
obj <<
" T: " <<
static_cast<int>( hid.
type ) <<
" "
257 << hid.
obj->IsA()->GetName();
281 typedef std::unordered_map<std::string, vhid_t*>
uidMap_t;
283 typedef std::unordered_multimap<std::string, vhid_t*>
idMap_t;
284 typedef std::unordered_map<TObject*, std::pair<vhid_t*, size_t>>
objMap_t;
293 std::map<std::string, std::pair<TFile*, Mode>>
m_files;
294 typedef std::multimap<std::string, std::string>
streamMap;
305 template <
typename T>
307 template <
typename T>
309 template <
typename T>
310 T*
getHist_i(
const std::string&
name,
const size_t& ind = 0,
bool quiet =
false )
const;
311 template <
typename T>
314 template <
typename T>
316 template <
typename T>
324 template <
typename T>
338 bool findStream(
const std::string&
name, std::string& root, std::string& rem, TFile*& file )
const;
339 void parseString(
const std::string&
id, std::string& root, std::string& rem )
const;
350 size_t findHistID(
const std::string&
id,
const THistID*& hid,
const size_t& index = 0 )
const;
371 "maximum file size in MB. if exceeded,"
372 " will cause an abort. -1 to never check." };
375 <<
"\"CompressionLevel\" Property has been deprecated. "
376 <<
"Set it via the \"CL=\" parameter in the \"Output\" Property"
401 return regHist_i( std::move( hist ),
id, shared, hid );
411 if ( hist_unique.get() !=
nullptr ) { hist = hist_unique.release(); }
413 debug() <<
"regHist_i obj: " << hist <<
" id: " <<
id <<
" s: " << shared <<
endmsg;
416 std::string idr(
id );
419 if ( idr.find(
"/" ) == idr.length() ) {
420 error() <<
"Badly formed identifier \"" << idr <<
"\": "
421 <<
"Must not end with a /" <<
endmsg;
427 std::string stream,
name;
429 error() <<
"Could not register id: \"" << idr <<
"\"" <<
endmsg;
434 std::string uid =
"/" + stream +
"/" +
name;
436 uidMap_t::iterator uitr =
m_uids.find( uid );
438 if ( uitr !=
m_uids.end() ) {
440 TObject*
t1 = uitr->second->at( 0 ).obj;
441 if ( hist->Compare(
t1 ) != 0 ) {
442 error() <<
"previously registered object with identifier \"" << uid <<
"\" does not compare to this one"
448 debug() <<
"previously registered id \"" << uid <<
"\": num " << uitr->second->size() <<
endmsg;
459 TObject* to =
nullptr;
462 if ( !temp &&
m_files.find( stream )->second.second ==
READ ) {
463 if ( hist != 0 ) {
warning() <<
"Registering id: \"" << idr <<
"\" with non zero pointer!" <<
endmsg; }
466 if ( hist ==
nullptr ) {
471 to =
dynamic_cast<TObject*
>( hist );
472 hid =
THistID( uid, temp, to, f,
m_files.find( stream )->second.second );
473 }
else if ( !hist ) {
474 error() <<
"Unable to read in hist with id: \"" << idr <<
"\"" <<
endmsg;
478 to =
dynamic_cast<TObject*
>( hist );
479 if ( to ==
nullptr ) {
480 error() <<
"Could not dcast to TObject. id: \"" << idr <<
"\"" <<
endmsg;
485 auto oitr =
m_tobjs.find( to );
487 error() <<
"already registered id: \"" << idr <<
"\" with identifier \""
488 << oitr->second.first->at( oitr->second.second ).id <<
"\"" <<
endmsg;
494 const auto findF =
m_files.find( stream );
495 hid = ( findF !=
m_files.end() ?
THistID( uid, temp, to, f, findF->second.second ) :
THistID( uid, temp, to, f ) );
500 if ( TTree* tree =
dynamic_cast<TTree*
>( hist ) ) {
501 tree->SetDirectory( dir );
504 }
else if (
TH1* th1 =
dynamic_cast<TH1*
>( hist ) ) {
505 th1->SetDirectory( dir );
507 }
else if ( TEfficiency* teff =
dynamic_cast<TEfficiency*
>( hist ) ) {
508 teff->SetDirectory( dir );
510 }
else if (
dynamic_cast<TGraph*
>( hist ) ) {
514 error() <<
"id: \"" << idr <<
"\" is not a TH, TTree, TGraph, or TEfficiency. Attaching it to current dir."
524 fname = f->GetName();
529 << hist->GetTitle() <<
"\" id: \"" << uid
536 if ( shared ) { hid.
mutex = std::make_unique<histMut_t>(); }
539 vhid_t* vi = uitr->second;
540 vi->push_back( std::move( hid ) );
541 phid = &( vi->back() );
543 m_tobjs.emplace( to, std::pair<vhid_t*, size_t>( vi, vi->size() - 1 ) );
546 vi->push_back( std::move( hid ) );
549 phid = &( vi->back() );
550 m_uids.emplace( uid, vi );
553 m_tobjs.emplace( to, std::pair<vhid_t*, size_t>( vi, 0 ) );
572 if ( !quiet ) {
error() <<
"could not locate Hist with id \"" <<
id <<
"\"" <<
endmsg; }
574 }
else if ( num > 1 ) {
577 error() <<
"Multiple matches with id \"" <<
id <<
"\"."
578 <<
" Further specifications required." <<
endmsg;
581 info() <<
"Found multiple matches with id \"" <<
id <<
"\"" <<
endmsg;
583 hist =
dynamic_cast<T*
>( hid->
obj );
584 if ( hist ==
nullptr ) {
585 error() <<
"dcast failed, Hist id: \"" <<
id <<
"\"" <<
endmsg;
590 hist =
dynamic_cast<T*
>( hid->
obj );
591 if ( hist ==
nullptr ) {
592 error() <<
"dcast failed, Hist id: \"" <<
id <<
"\"" <<
endmsg;
596 verbose() <<
"found unique Hist title: \"" << hist->GetTitle() <<
"\" id: \"" <<
id <<
"\"" <<
endmsg;
607 std::string idr(
id );
610 std::string stream, rem, dir, fdir, bdir, fdir2;
611 TFile* file =
nullptr;
613 if ( !
findStream( idr, stream, rem, file ) ) {
return nullptr; }
626 if ( !gDirectory->GetKey( dir.c_str() ) ) {
627 error() <<
"Directory \"" << fdir2 <<
"\" doesnt exist in " << file->GetName() <<
endmsg;
630 gDirectory->cd( dir.c_str() );
633 TObject* to =
nullptr;
634 gDirectory->GetObject( fdir.c_str(), to );
637 error() <<
"Could not get obj \"" << fdir <<
"\" in " << gDirectory->GetPath() <<
endmsg;
641 T* hist =
dynamic_cast<T*
>( to );
642 if ( hist ==
nullptr ) {
644 << to->IsA()->GetName() <<
endmsg;
649 debug() <<
"Read in " << hist->IsA()->GetName() <<
" \"" << hist->GetName() <<
"\" from file " << file->GetName()
662 T* phist = hist.get();
664 if (
regHist_i( std::move( hist ),
id,
true, phid ).isSuccess() ) {
668 error() <<
"regSharedHist: unable to register shared hist with id \"" <<
id <<
"\"" <<
endmsg;
672 error() <<
"regSharedHist: previously register Hist with id \"" <<
id <<
"\" was not marked shared" <<
endmsg;
675 if ( hist->Compare( hid->
obj ) != 0 ) {
676 error() <<
"regSharedHist: Histogram " <<
id <<
" does not compare with " << hid <<
endmsg;
678 T* phist =
dynamic_cast<T*
>( hid->
obj );
680 error() <<
"regSharedHist: unable to dcast retrieved shared hist \"" <<
id <<
"\" of type "
684 delete hist.release();
702 error() <<
"getSharedHist: found Hist with id \"" <<
name <<
"\", but it's not marked as shared" <<
endmsg;
705 T* h1 =
dynamic_cast<T*
>( hid->
obj );
709 }
else if ( i == 0 ) {
710 error() <<
"no histograms matching id \"" <<
name <<
"\" found" <<
endmsg;
712 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*.
THistID(const THistID &rhs)=delete
THistID & operator=(const THistID &rhs)=delete
std::unique_ptr< histMut_t > mutex
bool operator<(THistID const &rhs) const
THistID(THistID &&rhs)=default
THistID(std::string &i, bool &t, TObject *o, TFile *f)
THistID & operator=(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)