The Gaudi Framework  master (ff829712)
Loading...
Searching...
No Matches
THistSvc Class Reference

#include </builds/gaudi/Gaudi/GaudiSvc/src/THistSvc/THistSvc.h>

Inheritance diagram for THistSvc:
Collaboration diagram for THistSvc:

Classes

class  GlobalDirectoryRestore
 Helper class that manages ROOts global directory and file. More...
 
struct  THistID
 Helper struct that bundles the histogram ID with a mutex, TFile and TObject*. More...
 

Public Member Functions

 THistSvc (const std::string &name, ISvcLocator *svcloc)
 
StatusCode initialize () override
 
StatusCode reinitialize () override
 
StatusCode finalize () override
 
void handle (const Incident &) override
 
StatusCode io_reinit () override
 callback method to reinitialize the internal state of the component for I/O purposes (e.g.
 
Functions to manage ROOT histograms of any kind
StatusCode regHist (const std::string &name) override
 Register a new ROOT histogram TH*X with a name.
 
StatusCode regHist (const std::string &name, std::unique_ptr< TH1 > hist) override
 Register an existing ROOT histogram TH*X with name and moved unique_ptr.
 
StatusCode regHist (const std::string &name, TH1 *) override
 
StatusCode getHist (const std::string &name, TH1 *&, size_t index=0) const override
 Return histogram with given name as TH1*, THistSvcMT still owns object.
 
StatusCode getHist (const std::string &name, TH2 *&, size_t index=0) const override
 Return histogram with given name as TH2*, THistSvcMT still owns object.
 
StatusCode getHist (const std::string &name, TH3 *&, size_t index=0) const override
 Return histogram with given name as TH3*, THistSvcMT still owns object.
 
Functions to manage TTrees
StatusCode regTree (const std::string &name) override
 Register a new TTree with a given name.
 
StatusCode regTree (const std::string &name, std::unique_ptr< TTree >) override
 Register an existing TTree with a given name and moved unique_ptr.
 
StatusCode regTree (const std::string &name, TTree *) override
 
StatusCode getTree (const std::string &name, TTree *&) const override
 Return TTree with given name.
 
Functions to manage TGraphs
StatusCode regGraph (const std::string &name) override
 Register a new TGraph with a given name.
 
StatusCode regGraph (const std::string &name, std::unique_ptr< TGraph >) override
 Register an existing TGraph with a given name and moved unique_ptr.
 
virtual StatusCode regGraph (const std::string &name, TGraph *) override
 
StatusCode getGraph (const std::string &name, TGraph *&) const override
 Return TGraph with given name.
 
StatusCode regEfficiency (const std::string &name) override
 Register a new TEfficiency with a given name.
 
StatusCode regEfficiency (const std::string &name, std::unique_ptr< TEfficiency >) override
 Register an existing TEfficiency with a given name and moved unique_ptr.
 
virtual StatusCode regEfficiency (const std::string &name, TEfficiency *) override
 
StatusCode getEfficiency (const std::string &name, TEfficiency *&) const override
 Return TEfficiency with given name.
 
Functions managing shared objects
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.
 
StatusCode regShared (const std::string &name, std::unique_ptr< TH2 >, LockedHandle< TH2 > &) override
 Register shared object of type TH2 and return LockedHandle for that object.
 
StatusCode regShared (const std::string &name, std::unique_ptr< TH3 >, LockedHandle< TH3 > &) override
 Register shared object of type TH3 and return LockedHandle for that object.
 
StatusCode regShared (const std::string &name, std::unique_ptr< TGraph >, LockedHandle< TGraph > &) override
 Register shared object of type TGraph and return LockedHandle for that object.
 
StatusCode regShared (const std::string &name, std::unique_ptr< TEfficiency >, LockedHandle< TEfficiency > &) override
 Register shared object of type TEfficiency and return LockedHandle for that object.
 
StatusCode getShared (const std::string &name, LockedHandle< TH1 > &) const override
 Retrieve shared object with given name as TH1 through LockedHandle.
 
StatusCode getShared (const std::string &name, LockedHandle< TH2 > &) const override
 Retrieve shared object with given name as TH2 through LockedHandle.
 
StatusCode getShared (const std::string &name, LockedHandle< TH3 > &) const override
 Retrieve shared object with given name as TH3 through LockedHandle.
 
StatusCode getShared (const std::string &name, LockedHandle< TGraph > &) const override
 Retrieve shared object with given name as TGraph through LockedHandle.
 
StatusCode getShared (const std::string &name, LockedHandle< TEfficiency > &) const override
 Retrieve shared object with given name as TEfficiency through LockedHandle.
 
Functions that work on any TObject in the THistSvcMT
StatusCode deReg (const std::string &name) override
 Deregister object with given name and give up ownership (without deletion!)
 
StatusCode deReg (TObject *obj) override
 Deregister obejct identified by TObject* and give up ownership (without deletion!)
 
StatusCode merge (const std::string &id) override
 Merge all clones for object with a given id.
 
StatusCode merge (TObject *) override
 Merge all clones for given TObject*.
 
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 TH1-descendants.
 
bool existsHist (const std::string &name) const override
 Check if histogram 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.
 
bool existsGraph (const std::string &name) const override
 Check if graph with given name is managed by THistSvcMT.
 
bool existsEfficiency (const std::string &name) const override
 Check if TEfficiency with given name is managed by THistSvcMT.
 
Functions returning lists of all histograms, trees and graphs
std::vector< std::string > getHists () const override
 
std::vector< std::string > getTrees () const override
 
std::vector< std::string > getGraphs () const override
 
std::vector< std::string > getEfficiencies () const override
 
StatusCode getTHists (TDirectory *td, TList &, bool recurse=false) const override
 
StatusCode getTHists (const std::string &name, TList &, bool recurse=false) const override
 
StatusCode getTHists (TDirectory *td, TList &tl, bool recurse=false, bool reg=false) override
 
StatusCode getTHists (const std::string &name, TList &tl, bool recurse=false, bool reg=false) override
 
StatusCode getTTrees (TDirectory *td, TList &, bool recurse=false) const override
 
StatusCode getTTrees (const std::string &name, TList &, bool recurse=false) const override
 
StatusCode getTTrees (TDirectory *td, TList &tl, bool recurse=false, bool reg=false) override
 
StatusCode getTTrees (const std::string &name, TList &tl, bool recurse=false, bool reg=false) override
 
StatusCode getTEfficiencies (TDirectory *td, TList &, bool recurse=false) const override
 
StatusCode getTEfficiencies (const std::string &name, TList &, bool recurse=false) const override
 
StatusCode getTEfficiencies (TDirectory *td, TList &tl, bool recurse=false, bool reg=false) override
 
StatusCode getTEfficiencies (const std::string &name, TList &tl, bool recurse=false, bool reg=false) override
 
- Public Member Functions inherited from extends< Service, ITHistSvc, IIncidentListener, IIoComponent >
void const * i_cast (const InterfaceID &tid) const override
 Implementation of IInterface::i_cast.
 
StatusCode queryInterface (const InterfaceID &ti, void **pp) override
 Implementation of IInterface::queryInterface.
 
std::vector< std::string > getInterfaceNames () const override
 Implementation of IInterface::getInterfaceNames.
 
- Public Member Functions inherited from Service
const std::string & name () const override
 Retrieve name of the service.
 
StatusCode configure () override
 
StatusCode initialize () override
 
StatusCode start () override
 
StatusCode stop () override
 
StatusCode finalize () override
 
StatusCode terminate () override
 
Gaudi::StateMachine::State FSMState () const override
 
Gaudi::StateMachine::State targetFSMState () const override
 
StatusCode reinitialize () override
 
StatusCode restart () override
 
StatusCode sysInitialize () override
 Initialize Service.
 
StatusCode sysStart () override
 Initialize Service.
 
StatusCode sysStop () override
 Initialize Service.
 
StatusCode sysFinalize () override
 Finalize Service.
 
StatusCode sysReinitialize () override
 Re-initialize the Service.
 
StatusCode sysRestart () override
 Re-initialize the Service.
 
 Service (std::string name, ISvcLocator *svcloc)
 Standard Constructor.
 
SmartIF< ISvcLocator > & serviceLocator () const override
 Retrieve pointer to service locator.
 
template<typename IFace = IService>
SmartIF< IFace > service (const std::string &name, bool createIf=true) const
 
template<class T>
Gaudi::Details::PropertyBasedeclareProperty (const std::string &name, ToolHandle< T > &hndl, const std::string &doc="none")
 
template<class T>
StatusCode declareTool (ToolHandle< T > &handle, bool createIf=true)
 
template<class T>
StatusCode declareTool (ToolHandle< T > &handle, const std::string &toolTypeAndName, bool createIf=true)
 Declare used tool.
 
template<class T>
Gaudi::Details::PropertyBasedeclareProperty (const std::string &name, ToolHandleArray< T > &hndlArr, const std::string &doc="none")
 
template<class T>
void addToolsArray (ToolHandleArray< T > &hndlArr)
 
const std::vector< IAlgTool * > & tools () const
 
SmartIF< IAuditorSvc > & auditorSvc () const
 The standard auditor service.May not be invoked before sysInitialize() has been invoked.
 
- Public Member Functions inherited from PropertyHolder< CommonMessaging< implements< IService, IProperty, IStateful > > >
StatusCode setProperty (const Gaudi::Details::PropertyBase &p)
 Set the property from a property.
 
StatusCode setProperty (const std::string &name, const char *v)
 Special case for string literals.
 
StatusCode setProperty (const std::string &name, const std::string &v)
 Special case for std::string.
 
StatusCode setProperty (const std::string &name, const TYPE &value)
 set the property form the value
 
 PropertyHolder ()=default
 
Gaudi::Details::PropertyBasedeclareProperty (Gaudi::Details::PropertyBase &prop)
 Declare a property.
 
Gaudi::Details::PropertyBasedeclareProperty (const std::string &name, TYPE &value, const std::string &doc="none")
 Helper to wrap a regular data member and use it as a regular property.
 
Gaudi::Details::PropertyBasedeclareProperty (const std::string &name, Gaudi::Property< TYPE, VERIFIER, HANDLERS > &prop, const std::string &doc="none")
 Declare a PropertyBase instance setting name and documentation.
 
Gaudi::Details::PropertyBasedeclareRemoteProperty (const std::string &name, IProperty *rsvc, const std::string &rname="")
 Declare a remote property.
 
StatusCode setProperty (const std::string &name, const Gaudi::Details::PropertyBase &p) override
 set the property from another property with a different name
 
StatusCode setProperty (const std::string &s) override
 set the property from the formatted string
 
StatusCode setProperty (const Gaudi::Details::PropertyBase &p)
 Set the property from a property.
 
StatusCode setProperty (const std::string &name, const char *v)
 Special case for string literals.
 
StatusCode setProperty (const std::string &name, const std::string &v)
 Special case for std::string.
 
StatusCode setProperty (const std::string &name, const TYPE &value)
 set the property form the value
 
StatusCode setPropertyRepr (const std::string &n, const std::string &r) override
 set the property from name and value string representation
 
StatusCode getProperty (Gaudi::Details::PropertyBase *p) const override
 get the property
 
const Gaudi::Details::PropertyBasegetProperty (std::string_view name) const override
 get the property by name
 
StatusCode getProperty (std::string_view n, std::string &v) const override
 convert the property to the string
 
const std::vector< Gaudi::Details::PropertyBase * > & getProperties () const override
 get all properties
 
bool hasProperty (std::string_view name) const override
 Return true if we have a property with the given name.
 
Gaudi::Details::PropertyBaseproperty (std::string_view name) const
 \fixme property and bindPropertiesTo should be protected
 
void bindPropertiesTo (Gaudi::Interfaces::IOptionsSvc &optsSvc)
 
 PropertyHolder (const PropertyHolder &)=delete
 
PropertyHolderoperator= (const PropertyHolder &)=delete
 
- Public Member Functions inherited from CommonMessaging< implements< IService, IProperty, IStateful > >
MSG::Level msgLevel () const
 get the cached level (originally extracted from the embedded MsgStream)
 
bool msgLevel (MSG::Level lvl) const
 get the output level from the embedded MsgStream
 
- Public Member Functions inherited from CommonMessagingBase
virtual ~CommonMessagingBase ()=default
 Virtual destructor.
 
const SmartIF< IMessageSvc > & msgSvc () const
 The standard message service.
 
MsgStreammsgStream () const
 Return an uninitialized MsgStream.
 
MsgStreammsgStream (const MSG::Level level) const
 Predefined configurable message stream for the efficient printouts.
 
MsgStreamalways () const
 shortcut for the method msgStream(MSG::ALWAYS)
 
MsgStreamfatal () const
 shortcut for the method msgStream(MSG::FATAL)
 
MsgStreamerr () const
 shortcut for the method msgStream(MSG::ERROR)
 
MsgStreamerror () const
 shortcut for the method msgStream(MSG::ERROR)
 
MsgStreamwarning () const
 shortcut for the method msgStream(MSG::WARNING)
 
MsgStreaminfo () const
 shortcut for the method msgStream(MSG::INFO)
 
MsgStreamdebug () const
 shortcut for the method msgStream(MSG::DEBUG)
 
MsgStreamverbose () const
 shortcut for the method msgStream(MSG::VERBOSE)
 
MsgStreammsg () const
 shortcut for the method msgStream(MSG::INFO)
 

Private Types

enum  Mode {
  READ , WRITE , UPDATE , APPEND ,
  SHARE , INVALID
}
 Enumerating all possible file access modes. More...
 
enum class  ObjectType {
  UNKNOWN , TH1 , TTREE , TGRAPH ,
  TEFFICIENCY
}
 Possible TObject types. More...
 
typedef std::recursive_mutex THistSvcMutex_t
 
typedef std::mutex histMut_t
 

Private Member Functions

Templated helper functions to register and retrieve Histograms and TObjects
template<typename T>
StatusCode regHist_i (std::unique_ptr< T > hist, const std::string &name, bool shared)
 
template<typename T>
StatusCode regHist_i (std::unique_ptr< T > hist, const std::string &name, bool shared, THistID *&hid)
 
template<typename T>
T * getHist_i (const std::string &name, const size_t &ind=0, bool quiet=false) const
 
template<typename T>
T * readHist_i (const std::string &name) const
 
template<typename T>
LockedHandle< T > regShared_i (const std::string &id, std::unique_ptr< T > hist)
 
template<typename T>
LockedHandle< T > getShared_i (const std::string &name) const
 
Collection of private helper methods
template<typename T>
T * readHist (const std::string &name) const
 
TTree * readTree (const std::string &name) const
 
void updateFiles ()
 Handle case where TTree grows beyond TTree::fgMaxTreeSize.
 
StatusCode writeObjectsToFile ()
 
StatusCode connect (const std::string &)
 
TDirectory * changeDir (const THistSvc::THistID &hid) const
 
std::string stripDirectoryName (std::string &dir) const
 
void removeDoubleSlash (std::string &) const
 
void MergeRootFile (TDirectory *, TDirectory *)
 
bool findStream (const std::string &name, std::string &root, std::string &rem, TFile *&file) const
 
void parseString (const std::string &id, std::string &root, std::string &rem) const
 
void setupInputFile ()
 call-back method to handle input stream property
 
void setupOutputFile ()
 call-back method to handle output stream property
 
void copyFileLayout (TDirectory *, TDirectory *)
 helper function to recursively copy the layout of a TFile into a new TFile
 
size_t findHistID (const std::string &id, const THistID *&hid, const size_t &index=0) const
 
void dump () const
 
StatusCode merge (const THistID &)
 Helper method to merge THistID objects.
 
StatusCode merge (vhid_t *)
 Helper method to merge vectors of THistID.
 
StatusCode rootOpenAction (FILEMGR_CALLBACK_ARGS)
 
StatusCode rootOpenErrAction (FILEMGR_CALLBACK_ARGS)
 

Static Private Member Functions

static Mode charToMode (const char typ)
 Convert a char to a Mode enum.
 

Private Attributes

ServiceHandle< IIncidentSvcp_incSvc
 
ServiceHandle< IFileMgrp_fileMgr
 
bool m_delayConnect = false
 
bool m_okToConnect = false
 
bool m_hasTTrees = false
 
std::string m_curstream
 
THistSvcMutex_t m_svcMut
 
Gaudi properties
Gaudi::Property< int > m_autoSave { this, "AutoSave", 0 }
 
Gaudi::Property< int > m_autoFlush { this, "AutoFlush", 0 }
 
Gaudi::Property< bool > m_print { this, "PrintAll", false }
 
Gaudi::Property< int > m_maxFileSize
 
Gaudi::Property< int > m_compressionLevel
 
Gaudi::Property< std::vector< std::string > > m_outputfile
 
Gaudi::Property< std::vector< std::string > > m_inputfile
 

Container definitions

typedef std::vector< THistIDvhid_t
 
typedef std::list< vhid_t * > hlist_t
 
typedef std::unordered_map< std::string, vhid_t * > uidMap_t
 
typedef std::unordered_multimap< std::string, vhid_t * > idMap_t
 
typedef std::unordered_map< TObject *, std::pair< vhid_t *, size_t > > objMap_t
 
typedef std::multimap< std::string, std::string > streamMap
 
std::vector< std::string > m_Rstream
 
std::vector< std::string > m_Wstream
 
std::set< std::string > m_alreadyConnectedInFiles
 list of already connected files.
 
std::set< std::string > m_alreadyConnectedOutFiles
 list of already connected files.
 
hlist_t m_hlist
 
uidMap_t m_uids
 
idMap_t m_ids
 
objMap_t m_tobjs
 
std::map< std::string, std::pair< TFile *, Mode > > m_files
 
streamMap m_fileStreams
 
std::map< std::string, std::string > m_sharedFiles
 

Additional Inherited Members

- Public Types inherited from extends< Service, ITHistSvc, IIncidentListener, IIoComponent >
using base_class
 Typedef to this class.
 
using extend_interfaces_base
 Typedef to the base of this class.
 
- Public Types inherited from Service
using Factory = Gaudi::PluginService::Factory<IService*( const std::string&, ISvcLocator* )>
 
- Public Types inherited from PropertyHolder< CommonMessaging< implements< IService, IProperty, IStateful > > >
using PropertyHolderImpl
 Typedef used to refer to this class from derived classes, as in.
 
- Public Types inherited from CommonMessaging< implements< IService, IProperty, IStateful > >
using base_class
 
- Public Types inherited from extend_interfaces< Interfaces... >
using ext_iids
 take union of the ext_iids of all Interfaces...
 
- Protected Member Functions inherited from Service
std::vector< IAlgTool * > & tools ()
 
 ~Service () override
 
int outputLevel () const
 get the Service's output level
 
- Protected Member Functions inherited from CommonMessaging< implements< IService, IProperty, IStateful > >
MSG::Level setUpMessaging () const
 Set up local caches.
 
MSG::Level resetMessaging ()
 Reinitialize internal states.
 
void updateMsgStreamOutputLevel (int level)
 Update the output level of the cached MsgStream.
 
- Protected Attributes inherited from Service
Gaudi::StateMachine::State m_state = Gaudi::StateMachine::OFFLINE
 Service state.
 
Gaudi::StateMachine::State m_targetState = Gaudi::StateMachine::OFFLINE
 Service state.
 
Gaudi::Property< int > m_outputLevel { this, "OutputLevel", MSG::NIL, "output level" }
 flag indicating whether ToolHandle tools have been added to m_tools
 
Gaudi::Property< bool > m_auditorInitialize { this, "AuditInitialize", false, "trigger auditor on initialize()" }
 
Gaudi::Property< bool > m_auditorStart { this, "AuditStart", false, "trigger auditor on start()" }
 
Gaudi::Property< bool > m_auditorStop { this, "AuditStop", false, "trigger auditor on stop()" }
 
Gaudi::Property< bool > m_auditorFinalize { this, "AuditFinalize", false, "trigger auditor on finalize()" }
 
Gaudi::Property< bool > m_auditorReinitialize { this, "AuditReinitialize", false, "trigger auditor on reinitialize()" }
 
Gaudi::Property< bool > m_auditorRestart { this, "AuditRestart", false, "trigger auditor on restart()" }
 
Gaudi::Property< bool > m_autoRetrieveTools
 
Gaudi::Property< bool > m_checkToolDeps
 
SmartIF< IAuditorSvcm_pAuditorSvc
 Auditor Service.
 

Detailed Description

Definition at line 40 of file THistSvc.h.

Member Typedef Documentation

◆ histMut_t

typedef std::mutex THistSvc::histMut_t
private

Definition at line 200 of file THistSvc.h.

◆ hlist_t

typedef std::list<vhid_t*> THistSvc::hlist_t
private

Definition at line 281 of file THistSvc.h.

◆ idMap_t

typedef std::unordered_multimap<std::string, vhid_t*> THistSvc::idMap_t
private

Definition at line 285 of file THistSvc.h.

◆ objMap_t

typedef std::unordered_map<TObject*, std::pair<vhid_t*, size_t> > THistSvc::objMap_t
private

Definition at line 286 of file THistSvc.h.

◆ streamMap

typedef std::multimap<std::string, std::string> THistSvc::streamMap
private

Definition at line 296 of file THistSvc.h.

◆ THistSvcMutex_t

typedef std::recursive_mutex THistSvc::THistSvcMutex_t
private

Definition at line 199 of file THistSvc.h.

◆ uidMap_t

typedef std::unordered_map<std::string, vhid_t*> THistSvc::uidMap_t
private

Definition at line 283 of file THistSvc.h.

◆ vhid_t

typedef std::vector<THistID> THistSvc::vhid_t
private

Definition at line 279 of file THistSvc.h.

Member Enumeration Documentation

◆ Mode

enum THistSvc::Mode
private

Enumerating all possible file access modes.

Enumerator
READ 
WRITE 
UPDATE 
APPEND 
SHARE 
INVALID 

Definition at line 216 of file THistSvc.h.

◆ ObjectType

enum class THistSvc::ObjectType
strongprivate

Possible TObject types.

Enumerator
UNKNOWN 
TH1 
TTREE 
TGRAPH 
TEFFICIENCY 

Definition at line 219 of file THistSvc.h.

219{ UNKNOWN, TH1, TTREE, TGRAPH, TEFFICIENCY };
@ UNKNOWN
Definition IFileMgr.h:147

Constructor & Destructor Documentation

◆ THistSvc()

THistSvc::THistSvc ( const std::string & name,
ISvcLocator * svcloc )

Definition at line 79 of file THistSvc.cpp.

80 : base_class( name, svcloc ), p_incSvc( "IncidentSvc", name ), p_fileMgr( "FileMgr", name ) {}
const std::string & name() const override
Retrieve name of the service.
Definition Service.cpp:333
ServiceHandle< IIncidentSvc > p_incSvc
Definition THistSvc.h:388
ServiceHandle< IFileMgr > p_fileMgr
Definition THistSvc.h:389

Member Function Documentation

◆ changeDir()

TDirectory * THistSvc::changeDir ( const THistSvc::THistID & hid) const
private

Definition at line 1728 of file THistSvc.cpp.

1728 {
1729 std::string uid = hid.id;
1730 TFile* file = hid.file;
1731 std::string stream, fdir, bdir, dir, id;
1732
1733 if ( file ) {
1734 file->cd( "/" );
1735 } else {
1736 gROOT->cd();
1737 }
1738
1739 fdir = uid;
1740 bdir = stripDirectoryName( fdir );
1741
1742 while ( ( dir = stripDirectoryName( fdir ) ) != "" ) {
1743 if ( !gDirectory->GetKey( dir.c_str() ) ) { gDirectory->mkdir( dir.c_str() ); }
1744 gDirectory->cd( dir.c_str() );
1745 }
1746
1747 return gDirectory;
1748}
std::string stripDirectoryName(std::string &dir) const
stream
Definition Write.py:32
std::string id
Definition THistSvc.h:239

◆ charToMode()

static Mode THistSvc::charToMode ( const char typ)
inlinestaticprivate

Convert a char to a Mode enum.

Definition at line 222 of file THistSvc.h.

222 {
223 switch ( typ ) {
224 case 'O':
225 return READ;
226 case 'A':
227 return APPEND;
228 case 'R':
229 return UPDATE;
230 case 'S':
231 return SHARE;
232 default:
233 return INVALID;
234 }
235 }

◆ connect()

StatusCode THistSvc::connect ( const std::string & ident)
private

Definition at line 1552 of file THistSvc.cpp.

1552 {
1553 auto loc = ident.find( " " );
1554 std::string stream = ident.substr( 0, loc );
1555 char typ( 0 );
1556 typedef std::pair<std::string, std::string> Prop;
1557 std::vector<Prop> props;
1558 std::string filename, db_typ( "ROOT" );
1559 int cl( 1 );
1560
1561 if ( loc != std::string::npos ) {
1562 using Parser = Gaudi::Utils::AttribStringParser;
1563 for ( auto attrib : Parser( ident.substr( loc + 1 ) ) ) {
1564 // Don't use to_upper_copy in order to avoid gcc 13.1 bug
1565 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109703
1566 // (Should be fixed in 13.2.)
1567 auto TAG = attrib.tag;
1568 auto VAL = attrib.value;
1569 boost::algorithm::to_upper( TAG );
1570 boost::algorithm::to_upper( VAL );
1571
1572 if ( TAG == "FILE" || TAG == "DATAFILE" ) {
1573 filename = attrib.value;
1574 removeDoubleSlash( filename );
1575 } else if ( TAG == "OPT" ) {
1576 if ( VAL == "APPEND" || VAL == "UPDATE" ) {
1577 typ = 'A';
1578 } else if ( VAL == "CREATE" || VAL == "NEW" || VAL == "WRITE" ) {
1579 typ = 'N';
1580 } else if ( VAL == "RECREATE" ) {
1581 typ = 'R';
1582 } else if ( VAL == "SHARE" ) {
1583 typ = 'S';
1584 } else if ( VAL == "OLD" || VAL == "READ" ) {
1585 typ = 'O';
1586 } else {
1587 error() << "Unknown OPT: \"" << attrib.value << "\"" << endmsg;
1588 typ = 0;
1589 }
1590 } else if ( TAG == "TYP" ) {
1591 db_typ = std::move( attrib.value );
1592 } else if ( TAG == "CL" ) {
1593 cl = std::stoi( attrib.value );
1594 } else {
1595 props.emplace_back( attrib.tag, attrib.value );
1596 }
1597 }
1598 }
1599
1600 if ( stream == "temp" ) {
1601 error() << "in JobOption \"" << ident << "\": stream name \"temp\" reserved." << endmsg;
1602 return StatusCode::FAILURE;
1603 }
1604
1605 if ( db_typ != "ROOT" ) {
1606 error() << "in JobOption \"" << ident << "\": technology type \"" << db_typ << "\" not supported." << endmsg;
1607 return StatusCode::FAILURE;
1608 }
1609
1610 if ( m_files.find( stream ) != m_files.end() ) {
1611 error() << "in JobOption \"" << ident << "\":\n stream \"" << stream << "\" already connected to file: \""
1612 << m_files[stream].first->GetName() << "\"" << endmsg;
1613 return StatusCode::FAILURE;
1614 }
1615
1616 const auto newMode = charToMode( typ );
1617 if ( newMode == THistSvc::INVALID ) {
1618 error() << "No OPT= specified or unknown access mode in: " << ident << endmsg;
1619 return StatusCode::FAILURE;
1620 }
1621
1622 // Is this file already connected to another stream?
1623 if ( m_fileStreams.find( filename ) != m_fileStreams.end() ) {
1624 auto fitr = m_fileStreams.equal_range( filename );
1625
1626 const std::string& oldstream = fitr.first->second;
1627
1628 const auto& f_info = m_files[oldstream];
1629
1630 if ( newMode != f_info.second ) {
1631 error() << "in JobOption \"" << ident << "\":\n file \"" << filename << "\" already opened by stream: \""
1632 << oldstream << "\" with different access mode." << endmsg;
1633 return StatusCode::FAILURE;
1634 } else {
1635 TFile* f2 = f_info.first;
1636 m_files[stream] = std::make_pair( f2, newMode );
1637 if ( msgLevel( MSG::DEBUG ) )
1638 debug() << "Connecting stream: \"" << stream << "\" to previously opened TFile: \"" << filename << "\""
1639 << endmsg;
1640 return StatusCode::SUCCESS;
1641 }
1642 }
1643
1644 void* vf = nullptr;
1645 TFile* f = nullptr;
1646
1647 if ( newMode == THistSvc::READ ) {
1648 // old file
1649 int r = p_fileMgr->open( Io::ROOT, name(), filename, Io::READ, vf, "HIST" );
1650
1651 if ( r != 0 ) {
1652 error() << "Unable to open ROOT file " << filename << " for reading" << endmsg;
1653 return StatusCode::FAILURE;
1654 }
1655
1656 f = (TFile*)vf;
1657
1658 // FIX ME!
1659 p_incSvc->fireIncident( FileIncident( name(), "BeginHistFile", filename ) );
1660
1661 } else if ( newMode == THistSvc::WRITE ) {
1662 // new file. error if file exists
1663 int r = p_fileMgr->open( Io::ROOT, name(), filename, ( Io::WRITE | Io::CREATE | Io::EXCL ), vf, "HIST" );
1664
1665 if ( r != 0 ) {
1666 error() << "Unable to open ROOT file " << filename << " for writing" << endmsg;
1667 return StatusCode::FAILURE;
1668 }
1669
1670 f = (TFile*)vf;
1671
1672 } else if ( newMode == THistSvc::APPEND ) {
1673 // update file
1674 int r = p_fileMgr->open( Io::ROOT, name(), filename, ( Io::WRITE | Io::APPEND ), vf, "HIST" );
1675 if ( r != 0 ) {
1676 error() << "unable to open file \"" << filename << "\" for appending" << endmsg;
1677 return StatusCode::FAILURE;
1678 }
1679
1680 f = (TFile*)vf;
1681
1682 } else if ( newMode == THistSvc::SHARE ) {
1683 // SHARE file type
1684 // For SHARE files, all data will be stored in a temp file and will be
1685 // merged into the target file in writeObjectsToFile() when finalize(),
1686 // this help to solve some confliction. e.g. with storegate
1687 static int ishared = 0;
1688 std::string realfilename = filename;
1689 filename = "tmp_THistSvc_" + std::to_string( ishared++ ) + ".root";
1690
1691 if ( msgLevel( MSG::DEBUG ) ) {
1692 debug() << "Creating temp file \"" << filename << "\" and realfilename=" << realfilename << endmsg;
1693 }
1694 m_sharedFiles[stream] = realfilename;
1695
1696 int r = p_fileMgr->open( Io::ROOT, name(), filename, ( Io::WRITE | Io::CREATE | Io::EXCL ), vf, "HIST" );
1697
1698 if ( r != 0 ) {
1699 error() << "Unable to open ROOT file " << filename << " for writing" << endmsg;
1700 return StatusCode::FAILURE;
1701 }
1702
1703 f = (TFile*)vf;
1704
1705 } else if ( newMode == THistSvc::UPDATE ) {
1706 // update file
1707 int r = p_fileMgr->open( Io::ROOT, name(), filename, ( Io::WRITE | Io::CREATE ), vf, "HIST" );
1708
1709 if ( r != 0 ) {
1710 error() << "Unable to open ROOT file " << filename << " for appending" << endmsg;
1711 return StatusCode::FAILURE;
1712 }
1713
1714 f = (TFile*)vf;
1715 }
1716
1717 m_files[stream] = std::make_pair( f, newMode );
1718 m_fileStreams.insert( std::make_pair( filename, stream ) );
1719
1720 if ( msgLevel( MSG::DEBUG ) ) {
1721 debug() << "Opening TFile \"" << filename << "\" stream: \"" << stream << "\" mode: \"" << typ << "\""
1722 << " comp level: " << cl << endmsg;
1723 }
1724
1725 return StatusCode::SUCCESS;
1726}
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition MsgStream.h:198
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
constexpr static const auto SUCCESS
Definition StatusCode.h:99
constexpr static const auto FAILURE
Definition StatusCode.h:100
std::map< std::string, std::pair< TFile *, Mode > > m_files
Definition THistSvc.h:295
static Mode charToMode(const char typ)
Convert a char to a Mode enum.
Definition THistSvc.h:222
std::map< std::string, std::string > m_sharedFiles
Definition THistSvc.h:300
void removeDoubleSlash(std::string &) const
streamMap m_fileStreams
Definition THistSvc.h:297
@ ROOT
Definition IFileMgr.h:147
@ READ
Definition IFileMgr.h:30
@ CREATE
Definition IFileMgr.h:34
@ WRITE
Definition IFileMgr.h:31
@ EXCL
Definition IFileMgr.h:35
@ APPEND
Definition IFileMgr.h:38
@ DEBUG
Definition IMessageSvc.h:22

◆ copyFileLayout()

void THistSvc::copyFileLayout ( TDirectory * destination,
TDirectory * source )
private

helper function to recursively copy the layout of a TFile into a new TFile

Definition at line 1911 of file THistSvc.cpp.

1911 {
1912 if ( msgLevel( MSG::DEBUG ) ) {
1913 debug() << "copyFileLayout() to destination path: " << destination->GetPath() << endmsg;
1914 }
1915
1916 // strip out URLs
1917 TString path( (char*)strstr( destination->GetPath(), ":" ) );
1918 path.Remove( 0, 2 );
1919
1920 source->cd( path );
1921 TDirectory* current_source_dir = gDirectory;
1922
1923 // loop over all keys in this directory
1924 TList* key_list = current_source_dir->GetListOfKeys();
1925 int n = key_list->GetEntries();
1926 for ( int j = 0; j < n; ++j ) {
1927 TKey* k = (TKey*)key_list->At( j );
1928 const std::string source_pathname = current_source_dir->GetPath() + std::string( "/" ) + k->GetName();
1929 TObject* o = source->Get( source_pathname.c_str() );
1930
1931 if ( o && o->IsA()->InheritsFrom( "TDirectory" ) ) {
1932 if ( msgLevel( MSG::VERBOSE ) ) { verbose() << " subdir [" << o->GetName() << "]..." << endmsg; }
1933 destination->cd();
1934 // Create directory if it does not exist yet
1935 TDirectory* destination_dir = destination->mkdir( o->GetName(), o->GetTitle() );
1936 if ( destination_dir == nullptr ) destination_dir = destination->GetDirectory( o->GetName() );
1937 copyFileLayout( destination_dir, source );
1938 }
1939 } // loop over keys
1940 return;
1941}
MsgStream & verbose() const
shortcut for the method msgStream(MSG::VERBOSE)
void copyFileLayout(TDirectory *, TDirectory *)
helper function to recursively copy the layout of a TFile into a new TFile
GAUDI_API std::string path(const AIDA::IBaseHistogram *aida)
get the path in THS for AIDA histogram
@ VERBOSE
Definition IMessageSvc.h:22

◆ deReg() [1/2]

StatusCode THistSvc::deReg ( const std::string & name)
override

Deregister object with given name and give up ownership (without deletion!)

Definition at line 561 of file THistSvc.cpp.

561 {
562 auto itr = m_uids.find( id );
563 if ( itr == m_uids.end() ) {
564 error() << "Problem deregistering id \"" << id << "\": not found in registry" << endmsg;
565 return StatusCode::FAILURE;
566 }
567
568 vhid_t* vh = itr->second;
569
570 if ( msgLevel( MSG::DEBUG ) ) {
571 debug() << "will deregister " << vh->size() << " elements of id \"" << id << "\"" << endmsg;
572 }
573 StatusCode sc( StatusCode::SUCCESS );
574 // vh will get deleted in deReg once empty, so we cannot query the list size in the loop
575 size_t vh_size = vh->size();
576 while ( vh_size-- ) {
577 if ( deReg( vh->back().obj ).isFailure() ) {
579 error() << "Problems deRegistering " << vh->size() << " element of id \"" << id << "\"" << endmsg;
580 break;
581 }
582 }
583
584 return sc;
585}
bool isFailure() const
Definition StatusCode.h:129
uidMap_t m_uids
Definition THistSvc.h:289
std::vector< THistID > vhid_t
Definition THistSvc.h:279
StatusCode deReg(const std::string &name) override
Deregister object with given name and give up ownership (without deletion!)
Definition THistSvc.cpp:561

◆ deReg() [2/2]

StatusCode THistSvc::deReg ( TObject * obj)
override

Deregister obejct identified by TObject* and give up ownership (without deletion!)

Definition at line 587 of file THistSvc.cpp.

587 {
588 objMap_t::iterator obj_itr = m_tobjs.find( obj );
589 if ( obj_itr != m_tobjs.end() ) {
590 vhid_t* vhid = obj_itr->second.first;
591 THistID hid = obj_itr->second.first->at( obj_itr->second.second );
592
593 auto uid_itr = m_uids.find( hid.id );
594 if ( uid_itr == m_uids.end() ) {
595 error() << "Problems deregistering TObject \"" << obj->GetName() << "\" with id \"" << hid.id
596 << "\": not in uidMap" << endmsg;
597 return StatusCode::FAILURE;
598 }
599
600 if ( vhid->size() == 1 ) {
601 // We are the last object, so we have to delete vhid properly
602 if ( msgLevel( MSG::DEBUG ) ) { debug() << "vhid for " << hid.id << " is empty. deleting" << endmsg; }
603
604 std::string root, rem;
605 parseString( hid.id, root, rem );
606
607 auto mitr = m_ids.equal_range( rem );
608 auto id_itr = std::find_if( mitr.first, mitr.second,
609 [&]( idMap_t::const_reference i ) { return i.second->at( 0 ).obj == obj; } );
610 if ( id_itr == mitr.second ) {
611 error() << "Problems deregistering TObject \"" << obj->GetName() << "\" with id \"" << hid.id
612 << "\": not in idMap" << endmsg;
613 return StatusCode::FAILURE;
614 }
615
616 auto hlist_itr = std::find( m_hlist.begin(), m_hlist.end(), vhid );
617 if ( hlist_itr == m_hlist.end() ) {
618 error() << "Problems deregistering TObject \"" << obj->GetName() << "\" with id \"" << hid.id
619 << "\": not in hlist" << endmsg;
620 return StatusCode::FAILURE;
621 }
622
623 vhid->erase( vhid->begin() + obj_itr->second.second );
624 m_tobjs.erase( obj_itr );
625
626 m_uids.erase( uid_itr );
627 m_ids.erase( id_itr );
628 m_hlist.erase( hlist_itr );
629
630 delete vhid;
631
632 } else if ( vhid->size() > 1 ) {
633 vhid->erase( vhid->begin() + obj_itr->second.second );
634 m_tobjs.erase( obj_itr );
635
636 // vector of THistID is still not empty (i.e. other instances with same name registered)
637 } else {
638 error() << "Deregistration failed unexpectedly. (bug in THistSvc?)" << endmsg;
639 }
640 return StatusCode::SUCCESS;
641 } else {
642 error() << "Cannot unregister TObject \"" << obj->GetName() << "\": not known to THistSvc" << endmsg;
643 return StatusCode::FAILURE;
644 }
645}
idMap_t m_ids
Definition THistSvc.h:290
objMap_t m_tobjs
Definition THistSvc.h:293
hlist_t m_hlist
Definition THistSvc.h:288
void parseString(const std::string &id, std::string &root, std::string &rem) const
Helper struct that bundles the histogram ID with a mutex, TFile and TObject*.
Definition THistSvc.h:238

◆ dump()

void THistSvc::dump ( ) const
private

Definition at line 1988 of file THistSvc.cpp.

1988 {
1989 std::ostringstream ost;
1990
1991 // list< vector<THistID> >
1992 ost << "m_hlist: size: " << m_hlist.size() << "\n";
1993 for ( auto& vh : m_hlist ) {
1994 ost << " - " << vh->at( 0 ) << " :: [" << vh << "] " << vh->size() << " {";
1995 for ( auto& e : *vh ) {
1996 TObject* o = e.obj;
1997 ost << "[" << o << "]";
1998 }
1999 ost << "}\n";
2000 }
2001
2002 // map uid -> vector<THistID>*
2003 ost << "\n"
2004 << "m_uids: " << m_uids.size() << "\n";
2005 for ( auto& e : m_uids ) { ost << " - " << e.first << " [" << e.second << "]" << std::endl; }
2006
2007 // multimap id -> vector<THistID>*
2008 ost << "\n"
2009 << "m_ids: " << m_ids.size() << "\n";
2010 for ( auto& e : m_ids ) { ost << " - " << e.first << " [" << e.second << "]" << std::endl; }
2011
2012 // map TObject* -> THistID*
2013 ost << "\n"
2014 << "m_tobjs: " << m_tobjs.size() << "\n";
2015 for ( auto& e : m_tobjs ) {
2016 TObject* o = e.first;
2017 THistID& i = e.second.first->at( e.second.second );
2018 ost << " - " << o << " -> " << i << std::endl;
2019 }
2020
2021 debug() << "dumping THistSvc contents\n" << ost.str() << endmsg;
2022}

◆ exists()

bool THistSvc::exists ( const std::string & name) const
override

Check if object with given name is managed by THistSvcMT exists calls existsHist and only works for TH1-descendants.

Definition at line 667 of file THistSvc.cpp.

667{ return existsHist( name ); }
bool existsHist(const std::string &name) const override
Check if histogram with given name is managed by THistSvcMT.
Definition THistSvc.cpp:669

◆ existsEfficiency()

bool THistSvc::existsEfficiency ( const std::string & name) const
override

Check if TEfficiency with given name is managed by THistSvcMT.

Definition at line 671 of file THistSvc.cpp.

671 {
672 return ( getHist_i<TEfficiency>( name, 0, true ) != nullptr );
673}
T * getHist_i(const std::string &name, const size_t &ind=0, bool quiet=false) const
Definition THistSvc.icc:183

◆ existsGraph()

bool THistSvc::existsGraph ( const std::string & name) const
override

Check if graph with given name is managed by THistSvcMT.

Definition at line 675 of file THistSvc.cpp.

675 {
676 return ( getHist_i<TGraph>( name, 0, true ) != nullptr );
677}

◆ existsHist()

bool THistSvc::existsHist ( const std::string & name) const
override

Check if histogram with given name is managed by THistSvcMT.

Definition at line 669 of file THistSvc.cpp.

669{ return ( getHist_i<TH1>( name, 0, true ) != nullptr ); }

◆ existsTree()

bool THistSvc::existsTree ( const std::string & name) const
override

Check if tree with given name is managed by THistSvcMT.

Definition at line 679 of file THistSvc.cpp.

679{ return ( getHist_i<TTree>( name, 0, true ) != nullptr ); }

◆ finalize()

StatusCode THistSvc::finalize ( )
override

Definition at line 193 of file THistSvc.cpp.

193 {
195
196 if ( msgLevel( MSG::DEBUG ) ) {
197 dump();
198 debug() << "THistSvc::finalize" << endmsg;
199 }
200
201#ifndef NDEBUG
202 if ( msgLevel( MSG::DEBUG ) ) {
203 const std::map<uidMap_t::key_type, uidMap_t::mapped_type> sorted_uids{ begin( m_uids ), end( m_uids ) };
204 for ( const auto& itr : sorted_uids ) {
205 THistID& thid = itr.second->at( 0 );
206 TObject* tobj = thid.obj;
207
208 std::string dirname( "none" );
209 if ( tobj && thid.type == ObjectType::TTREE ) {
210 TTree* tree = dynamic_cast<TTree*>( tobj );
211 if ( tree->GetDirectory() != 0 ) { dirname = tree->GetDirectory()->GetPath(); }
212 } else if ( tobj && thid.type == ObjectType::TGRAPH ) {
213 if ( !thid.temp ) {
214 dirname = thid.file->GetPath();
215 std::string id2( thid.id );
216 id2.erase( 0, id2.find( "/", 1 ) );
217 id2.erase( id2.rfind( "/" ), id2.length() );
218 if ( id2.starts_with( "/" ) ) { id2.erase( 0, 1 ); }
219 dirname += id2;
220 } else {
221 dirname = "/tmp";
222 }
223 } else if ( tobj && thid.type == ObjectType::TH1 ) {
224 TH1* th = dynamic_cast<TH1*>( tobj );
225 if ( th == nullptr ) {
226 error() << "Couldn't dcast: " << itr.first << endmsg;
227 } else {
228 if ( th->GetDirectory() != 0 ) { dirname = th->GetDirectory()->GetPath(); }
229 }
230 } else if ( !tobj ) {
231 warning() << itr.first << " has NULL TObject ptr" << endmsg;
232 }
233 debug() << "finalize: " << thid << endmsg;
234 }
235 }
236#endif
237
238 if ( writeObjectsToFile().isFailure() ) { error() << "problems writing histograms" << endmsg; }
239
240 if ( m_print ) { info() << "Listing contents of ROOT files: " << endmsg; }
241 std::vector<TFile*> deleted_files;
242 for ( auto& itr : m_files ) {
243 if ( std::find( deleted_files.begin(), deleted_files.end(), itr.second.first ) == deleted_files.end() ) {
244 deleted_files.push_back( itr.second.first );
245
246#ifndef NDEBUG
247 if ( msgLevel( MSG::DEBUG ) ) {
248 debug() << "finalizing stream/file " << itr.first << ":" << itr.second.first->GetName() << endmsg;
249 }
250#endif
251 } else {
252#ifndef NDEBUG
253 if ( msgLevel( MSG::DEBUG ) ) { debug() << "already finalized stream " << itr.first << endmsg; }
254#endif
255 continue;
256 }
257
258 if ( m_print && msgLevel( MSG::INFO ) ) {
259 info() << "==> File: " << itr.second.first->GetName() << " stream: " << itr.first << endmsg;
260
261 itr.second.first->Print( "base" );
262 }
263
264 std::string tmpfn = itr.second.first->GetName();
265
266 p_fileMgr->close( itr.second.first, name() );
267
268 if ( itr.second.second == SHARE ) {
269 // Merge File
270 void* vfile = nullptr;
271 int returncode =
272 p_fileMgr->open( Io::ROOT, name(), m_sharedFiles[itr.first], Io::WRITE | Io::APPEND, vfile, "HIST" );
273
274 if ( returncode ) {
275 error() << "unable to open Final Output File: \"" << m_sharedFiles[itr.first] << "\" for merging" << endmsg;
276 return StatusCode::FAILURE;
277 }
278
279 TFile* outputfile = (TFile*)vfile;
280 p_incSvc->fireIncident( FileIncident( name(), IncidentType::WroteToOutputFile, m_sharedFiles[itr.first] ) );
281
282 if ( msgLevel( MSG::DEBUG ) ) { debug() << "THistSvc::writeObjectsToFile()::Merging Rootfile " << endmsg; }
283
284 vfile = nullptr;
285 returncode = p_fileMgr->open( Io::ROOT, name(), tmpfn, Io::READ, vfile, "HIST" );
286
287 if ( returncode ) {
288 error() << "unable to open temporary file: \"" << tmpfn << endmsg;
289 return StatusCode::FAILURE;
290 }
291
292 TFile* inputfile = (TFile*)vfile;
293
294 outputfile->SetCompressionLevel( inputfile->GetCompressionLevel() );
295
296 MergeRootFile( outputfile, inputfile );
297
298 outputfile->Write();
299 p_fileMgr->close( outputfile, name() );
300 p_fileMgr->close( inputfile, name() );
301
302 if ( msgLevel( MSG::DEBUG ) ) { debug() << "Trying to remove temporary file \"" << tmpfn << "\"" << endmsg; }
303
304 std::remove( tmpfn.c_str() );
305 }
306 delete itr.second.first;
307 }
308
309 m_files.clear();
310 m_sharedFiles.clear();
311 m_fileStreams.clear();
312 m_hlist.clear(); // vhid* is deleted in m_tobjs
313 m_uids.clear(); // vhid* is deleted in m_tobjs
314 m_ids.clear(); // vhid* is deleted in m_tobjs
315
316 for ( auto& obj : m_tobjs ) {
317 // TObject*'s are already dealt with through root file i/o
318 // only delete vector if this object is index 0
319 if ( obj.second.second == 0 ) {
320 delete obj.second.first; // delete vhid*
321 }
322 }
323 m_tobjs.clear();
324
325 return Service::finalize();
326}
MsgStream & warning() const
shortcut for the method msgStream(MSG::WARNING)
MsgStream & info() const
shortcut for the method msgStream(MSG::INFO)
StatusCode finalize() override
Definition Service.cpp:223
Helper class that manages ROOts global directory and file.
Definition THistSvc.h:203
void MergeRootFile(TDirectory *, TDirectory *)
void dump() const
StatusCode writeObjectsToFile()
Gaudi::Property< bool > m_print
Definition THistSvc.h:371
THistSvcMutex_t m_svcMut
Definition THistSvc.h:397
AttribStringParser::Iterator begin(const AttribStringParser &parser)
@ INFO
Definition IMessageSvc.h:22
Generator[int, None, None] returncode(subprocess.CompletedProcess completed_process)
Definition fixtures.py:156
TObject * obj
Definition THistSvc.h:240

◆ findHistID()

size_t THistSvc::findHistID ( const std::string & id,
const THistID *& hid,
const size_t & index = 0 ) const
private

Definition at line 1943 of file THistSvc.cpp.

1943 {
1945
1946 std::string idr( id );
1947 removeDoubleSlash( idr );
1948
1949 hid = 0;
1950
1951 if ( idr.starts_with( "/" ) ) {
1952 // fully specified name, starts with "/"
1953 auto itr = m_uids.find( idr );
1954 if ( itr == m_uids.end() ) {
1955 // no matches found
1956 return 0;
1957 } else {
1958 // one or more matches found (clones).
1959 if ( index >= itr->second->size() ) {
1960 error() << "no index " << index << " found for Hist " << idr << endmsg;
1961 return 0;
1962 }
1963 hid = &( itr->second->at( index ) );
1964 return 1;
1965 }
1966 } else {
1967 // name not fully specified.
1968 auto mitr = m_ids.equal_range( idr );
1969 if ( mitr.first == mitr.second ) {
1970 // not found
1971 return 0;
1972 } else if ( distance( mitr.first, mitr.second ) == 1 ) {
1973 // one found
1974 if ( index >= mitr.first->second->size() ) {
1975 error() << "no index " << index << " found for Hist " << idr << endmsg;
1976 return 0;
1977 }
1978 hid = &( mitr.first->second->at( 0 ) );
1979 return 1;
1980 } else {
1981 // multiple matches
1982 hid = &( mitr.first->second->at( 0 ) );
1983 return distance( mitr.first, mitr.second );
1984 }
1985 }
1986}
size_t index(const Gaudi::ParticleProperty *property, const Gaudi::Interfaces::IParticlePropertySvc *service)
helper utility for mapping of Gaudi::ParticleProperty object into non-negative integral sequential id...

◆ findStream()

bool THistSvc::findStream ( const std::string & name,
std::string & root,
std::string & rem,
TFile *& file ) const
private

Definition at line 1817 of file THistSvc.cpp.

1817 {
1818 auto pos = id.find( "/" );
1819
1820 if ( pos == std::string::npos ) {
1821 // no "/" in id
1822 stream = "temp";
1823 rem = id;
1824 } else if ( pos != 0 ) {
1825 // id does not start with "/"
1826 stream = "temp";
1827 rem = id;
1828 } else {
1829 // id starts with "/"
1830
1831 auto pos2 = id.find( "/", pos + 1 );
1832
1833 if ( pos2 == std::string::npos ) {
1834 // need at least 2 "/" in format "/STREAM/name" or "/STREAM/dir/name"
1835 error() << "badly formed Hist/Tree id: \"" << id << "\"" << endmsg;
1836 return false;
1837 }
1838 parseString( id, stream, rem );
1839 }
1840
1841 if ( stream == "temp" ) {
1842 file = nullptr;
1843 return true;
1844 }
1845
1846 auto itr = m_files.find( stream );
1847 file = ( itr != m_files.end() ? itr->second.first : nullptr );
1848 if ( !file ) { warning() << "no stream \"" << stream << "\" associated with id: \"" << id << "\"" << endmsg; }
1849
1850 return true;
1851}

◆ getEfficiencies()

std::vector< std::string > THistSvc::getEfficiencies ( ) const
override

Definition at line 705 of file THistSvc.cpp.

705 {
706 std::vector<std::string> names;
707 names.reserve( m_uids.size() );
708 transform_if( std::begin( m_uids ), std::end( m_uids ), std::back_inserter( names ), select1st,
709 []( uidMap_t::const_reference i ) { return i.second->at( 0 ).type == ObjectType::TEFFICIENCY; } );
710 return names;
711}

◆ getEfficiency()

StatusCode THistSvc::getEfficiency ( const std::string & name,
TEfficiency *& eff ) const
override

Return TEfficiency with given name.

Definition at line 461 of file THistSvc.cpp.

461 {
462 eff = getHist_i<TEfficiency>( id );
463 if ( eff != nullptr ) {
464 return StatusCode::SUCCESS;
465 } else {
466 return StatusCode::FAILURE;
467 }
468}

◆ getGraph()

StatusCode THistSvc::getGraph ( const std::string & name,
TGraph *& graph ) const
override

Return TGraph with given name.

Definition at line 438 of file THistSvc.cpp.

438 {
439 graph = getHist_i<TGraph>( id );
440 if ( graph != nullptr ) {
441 return StatusCode::SUCCESS;
442 } else {
443 return StatusCode::FAILURE;
444 }
445}

◆ getGraphs()

std::vector< std::string > THistSvc::getGraphs ( ) const
override

Definition at line 697 of file THistSvc.cpp.

697 {
698 std::vector<std::string> names;
699 names.reserve( m_uids.size() );
700 transform_if( std::begin( m_uids ), std::end( m_uids ), std::back_inserter( names ), select1st,
701 []( uidMap_t::const_reference i ) { return i.second->at( 0 ).type == ObjectType::TGRAPH; } );
702 return names;
703}

◆ getHist() [1/3]

StatusCode THistSvc::getHist ( const std::string & name,
TH1 *& hist,
size_t index = 0 ) const
override

Return histogram with given name as TH1*, THistSvcMT still owns object.

Definition at line 344 of file THistSvc.cpp.

344 {
345 hist = getHist_i<TH1>( id, ind );
346 if ( hist != nullptr ) {
347 return StatusCode::SUCCESS;
348 } else {
349 return StatusCode::FAILURE;
350 }
351}

◆ getHist() [2/3]

StatusCode THistSvc::getHist ( const std::string & name,
TH2 *& hist,
size_t index = 0 ) const
override

Return histogram with given name as TH2*, THistSvcMT still owns object.

Definition at line 353 of file THistSvc.cpp.

353 {
354 hist = getHist_i<TH2>( id, ind );
355 if ( hist != nullptr ) {
356 return StatusCode::SUCCESS;
357 } else {
358 return StatusCode::FAILURE;
359 }
360}

◆ getHist() [3/3]

StatusCode THistSvc::getHist ( const std::string & name,
TH3 *& hist,
size_t index = 0 ) const
override

Return histogram with given name as TH3*, THistSvcMT still owns object.

Definition at line 362 of file THistSvc.cpp.

362 {
363 hist = getHist_i<TH3>( id, ind );
364 if ( hist != nullptr ) {
365 return StatusCode::SUCCESS;
366 } else {
367 return StatusCode::FAILURE;
368 }
369}

◆ getHist_i()

template<typename T>
T * THistSvc::getHist_i ( const std::string & name,
const size_t & ind = 0,
bool quiet = false ) const
private

Definition at line 183 of file THistSvc.icc.

183 {
184 // id starts with "/": unique
185
187
188 T* hist = nullptr;
189 const THistID* hid = nullptr;
190 size_t num = findHistID( id, hid, ind );
191 if ( num == 0 ) {
192 // no matches found
193 if ( !quiet ) { error() << "could not locate Hist with id \"" << id << "\"" << endmsg; }
194 return nullptr;
195 } else if ( num > 1 ) {
196 if ( !quiet ) {
197 // return failure if trying to GET a single hist
198 error() << "Multiple matches with id \"" << id << "\"."
199 << " Further specifications required." << endmsg;
200 return nullptr;
201 } else {
202 info() << "Found multiple matches with id \"" << id << "\"" << endmsg;
203 // return first match if just INQUIRING (i.e. != nullptr)
204 hist = dynamic_cast<T*>( hid->obj );
205 if ( hist == nullptr ) {
206 error() << "dcast failed, Hist id: \"" << id << "\"" << endmsg;
207 return nullptr;
208 }
209 }
210 } else {
211 hist = dynamic_cast<T*>( hid->obj );
212 if ( hist == nullptr ) {
213 error() << "dcast failed, Hist id: \"" << id << "\"" << endmsg;
214 return nullptr;
215 }
216 if ( msgLevel( MSG::VERBOSE ) ) {
217 verbose() << "found unique Hist title: \"" << hist->GetTitle() << "\" id: \"" << id << "\"" << endmsg;
218 }
219 }
220
221 return hist;
222}
size_t findHistID(const std::string &id, const THistID *&hid, const size_t &index=0) const

◆ getHists()

std::vector< std::string > THistSvc::getHists ( ) const
override

Definition at line 681 of file THistSvc.cpp.

681 {
682 std::vector<std::string> names;
683 names.reserve( m_uids.size() );
684 transform_if( std::begin( m_uids ), std::end( m_uids ), std::back_inserter( names ), select1st,
685 []( uidMap_t::const_reference i ) { return i.second->at( 0 ).type == ObjectType::TH1; } );
686 return names;
687}

◆ getShared() [1/5]

StatusCode THistSvc::getShared ( const std::string & name,
LockedHandle< TEfficiency > & lh ) const
override

Retrieve shared object with given name as TEfficiency through LockedHandle.

Definition at line 552 of file THistSvc.cpp.

552 {
554 if ( lh ) {
555 return StatusCode::SUCCESS;
556 } else {
557 return StatusCode::FAILURE;
558 }
559}
LockedHandle< T > getShared_i(const std::string &name) const
Definition THistSvc.icc:313

◆ getShared() [2/5]

StatusCode THistSvc::getShared ( const std::string & name,
LockedHandle< TGraph > & lh ) const
override

Retrieve shared object with given name as TGraph through LockedHandle.

Definition at line 543 of file THistSvc.cpp.

543 {
545 if ( lh ) {
546 return StatusCode::SUCCESS;
547 } else {
548 return StatusCode::FAILURE;
549 }
550}

◆ getShared() [3/5]

StatusCode THistSvc::getShared ( const std::string & name,
LockedHandle< TH1 > & lh ) const
override

Retrieve shared object with given name as TH1 through LockedHandle.

Definition at line 516 of file THistSvc.cpp.

516 {
517 lh = getShared_i<TH1>( name );
518 if ( lh ) {
519 return StatusCode::SUCCESS;
520 } else {
521 return StatusCode::FAILURE;
522 }
523}

◆ getShared() [4/5]

StatusCode THistSvc::getShared ( const std::string & name,
LockedHandle< TH2 > & lh ) const
override

Retrieve shared object with given name as TH2 through LockedHandle.

Definition at line 525 of file THistSvc.cpp.

525 {
526 lh = getShared_i<TH2>( name );
527 if ( lh ) {
528 return StatusCode::SUCCESS;
529 } else {
530 return StatusCode::FAILURE;
531 }
532}

◆ getShared() [5/5]

StatusCode THistSvc::getShared ( const std::string & name,
LockedHandle< TH3 > & lh ) const
override

Retrieve shared object with given name as TH3 through LockedHandle.

Definition at line 534 of file THistSvc.cpp.

534 {
535 lh = getShared_i<TH3>( name );
536 if ( lh ) {
537 return StatusCode::SUCCESS;
538 } else {
539 return StatusCode::FAILURE;
540 }
541}

◆ getShared_i()

template<typename T>
LockedHandle< T > THistSvc::getShared_i ( const std::string & name) const
private

Definition at line 313 of file THistSvc.icc.

313 {
315
316 const THistID* hid = nullptr;
317 size_t i = findHistID( name, hid );
318
319 LockedHandle<T> hist( nullptr, nullptr );
320
321 if ( i == 1 ) {
322 if ( !hid->shared ) {
323 error() << "getSharedHist: found Hist with id \"" << name << "\", but it's not marked as shared" << endmsg;
324 return hist;
325 }
326 T* h1 = dynamic_cast<T*>( hid->obj );
327 hist = LockedHandle<T>( h1, hid->mutex );
328
329 if ( msgLevel( MSG::DEBUG ) ) { debug() << "getSharedHist: found THistID: " << *hid << endmsg; }
330 } else if ( i == 0 ) {
331 error() << "no histograms matching id \"" << name << "\" found" << endmsg;
332 } else {
333 info() << "multiple matches for id \"" << name << "\" found [" << i << "], probably from different streams"
334 << endmsg;
335 }
336 return hist;
337}

◆ getTEfficiencies() [1/4]

StatusCode THistSvc::getTEfficiencies ( const std::string & name,
TList & tl,
bool recurse = false ) const
override

Definition at line 1139 of file THistSvc.cpp.

1139 {
1140
1142
1143 gErrorIgnoreLevel = kBreak;
1144
1145 StatusCode sc;
1146
1147 std::string stream, rem, r2;
1148 parseString( dir, stream, rem );
1149
1150 auto itr = m_files.find( stream );
1151 if ( itr != m_files.end() ) {
1152 r2 = itr->second.first->GetName();
1153 r2 += ":/";
1154 r2 += rem;
1155
1156 if ( msgLevel( MSG::DEBUG ) ) {
1157 debug() << "getTEfficiencies: \"" << dir << "\" looks like a stream name."
1158 << " associated TFile: \"" << itr->second.first->GetName() << "\"" << endmsg;
1159 }
1160
1161 if ( gDirectory->cd( r2.c_str() ) ) {
1163 sc = getTEfficiencies( gDirectory, tl, rcs );
1164 m_curstream = "";
1165 return sc;
1166 } else {
1167 if ( msgLevel( MSG::DEBUG ) ) { debug() << "getTEfficiencies: no such TDirectory \"" << r2 << "\"" << endmsg; }
1168 }
1169
1170 } else {
1171 if ( msgLevel( MSG::DEBUG ) ) { debug() << "getTEfficiencies: stream \"" << stream << "\" not found" << endmsg; }
1172 }
1173
1174 if ( !gDirectory->cd( dir.c_str() ) ) {
1175 error() << "getTEfficiencies: No such TDirectory/stream \"" << dir << "\"" << endmsg;
1177 } else {
1178 sc = getTHists( gDirectory, tl, rcs );
1179 }
1180
1181 return sc;
1182}
std::string m_curstream
Definition THistSvc.h:395
StatusCode getTHists(TDirectory *td, TList &, bool recurse=false) const override
Definition THistSvc.cpp:713
StatusCode getTEfficiencies(TDirectory *td, TList &, bool recurse=false) const override

◆ getTEfficiencies() [2/4]

StatusCode THistSvc::getTEfficiencies ( const std::string & name,
TList & tl,
bool recurse = false,
bool reg = false )
override

Definition at line 1247 of file THistSvc.cpp.

1247 {
1249
1250 gErrorIgnoreLevel = kBreak;
1251
1252 StatusCode sc;
1253
1254 std::string stream, rem, r2;
1255 parseString( dir, stream, rem );
1256
1257 auto itr = m_files.find( stream );
1258 if ( itr != m_files.end() ) {
1259 r2 = itr->second.first->GetName();
1260 r2 += ":/";
1261 r2 += rem;
1262
1263 if ( msgLevel( MSG::DEBUG ) ) {
1264 debug() << "getTEfficiencies: \"" << dir << "\" looks like a stream name."
1265 << " associated TFile: \"" << itr->second.first->GetName() << "\"" << endmsg;
1266 }
1267
1268 if ( gDirectory->cd( r2.c_str() ) ) {
1270 sc = getTEfficiencies( gDirectory, tl, rcs, reg );
1271 m_curstream.clear();
1272 return sc;
1273 }
1274 if ( msgLevel( MSG::DEBUG ) ) { debug() << "getTEfficiencies: no such TDirectory \"" << r2 << "\"" << endmsg; }
1275 } else {
1276 if ( msgLevel( MSG::DEBUG ) ) { debug() << "getTEfficiencies: stream \"" << stream << "\" not found" << endmsg; }
1277 }
1278
1279 if ( !gDirectory->cd( dir.c_str() ) ) {
1280 error() << "getTEfficiencies: No such TDirectory/stream \"" << dir << "\"" << endmsg;
1282 } else {
1283 if ( reg ) {
1284 warning() << "Unable to register histograms automatically "
1285 << "without a valid stream name" << endmsg;
1286 reg = false;
1287 }
1288 sc = getTEfficiencies( gDirectory, tl, rcs, reg );
1289 }
1290
1291 return sc;
1292}

◆ getTEfficiencies() [3/4]

StatusCode THistSvc::getTEfficiencies ( TDirectory * td,
TList & tl,
bool recurse = false ) const
override

Definition at line 1093 of file THistSvc.cpp.

1093 {
1095
1096 gErrorIgnoreLevel = kBreak;
1097
1098 if ( !td->cd() ) {
1099 error() << "getTEfficiencies: No such TDirectory \"" << td->GetPath() << "\"" << endmsg;
1100 return StatusCode::FAILURE;
1101 }
1102
1103 if ( msgLevel( MSG::DEBUG ) ) {
1104 debug() << "getTEfficiencies: \"" << td->GetPath() << "\": found " << td->GetListOfKeys()->GetSize() << " keys"
1105 << endmsg;
1106 }
1107
1108 TIter nextkey( td->GetListOfKeys() );
1109 while ( TKey* key = (TKey*)nextkey() ) {
1110 auto& log = debug();
1111 if ( msgLevel( MSG::DEBUG ) ) log << " key: " << key->GetName();
1112 TObject* obj = key->ReadObj();
1113 if ( obj != 0 && obj->IsA()->InheritsFrom( "TDirectory" ) ) {
1114 if ( msgLevel( MSG::DEBUG ) ) log << " (" << obj->IsA()->GetName() << ")";
1115 } else if ( obj != 0 && obj->IsA()->InheritsFrom( "TEfficiency" ) ) {
1116 if ( msgLevel( MSG::DEBUG ) ) log << " (" << obj->IsA()->GetName() << ")";
1117 tl.Add( obj );
1118 } else if ( obj != 0 ) {
1119 if ( msgLevel( MSG::DEBUG ) ) log << " [" << obj->IsA()->GetName() << "]";
1120 }
1121 if ( msgLevel( MSG::DEBUG ) ) log << endmsg;
1122 }
1123
1124 // operate recursively
1125 if ( rcs ) {
1126 nextkey = td->GetListOfKeys();
1127 while ( TKey* key = (TKey*)nextkey() ) {
1128 TObject* obj = key->ReadObj();
1129 if ( obj && obj->IsA()->InheritsFrom( "TDirectory" ) ) {
1130 TDirectory* tt = dynamic_cast<TDirectory*>( obj );
1131 getTHists( tt, tl, rcs ).ignore( /* AUTOMATICALLY ADDED FOR gaudi/Gaudi!763 */ );
1132 }
1133 }
1134 }
1135
1136 return StatusCode::SUCCESS;
1137}
const StatusCode & ignore() const
Allow discarding a StatusCode without warning.
Definition StatusCode.h:139

◆ getTEfficiencies() [4/4]

StatusCode THistSvc::getTEfficiencies ( TDirectory * td,
TList & tl,
bool recurse = false,
bool reg = false )
override

Definition at line 1184 of file THistSvc.cpp.

1184 {
1186
1187 gErrorIgnoreLevel = kBreak;
1188
1189 if ( !td->cd() ) {
1190 error() << "getTEfficiencies: No such TDirectory \"" << td->GetPath() << "\"" << endmsg;
1191 return StatusCode::FAILURE;
1192 }
1193
1194 if ( msgLevel( MSG::DEBUG ) ) {
1195 debug() << "getTEfficiencies: \"" << td->GetPath() << "\": found " << td->GetListOfKeys()->GetSize() << " keys"
1196 << endmsg;
1197 }
1198
1199 TIter nextkey( td->GetListOfKeys() );
1200 while ( TKey* key = (TKey*)nextkey() ) {
1201 auto& log = debug();
1202 if ( msgLevel( MSG::DEBUG ) ) log << " key: " << key->GetName();
1203 TObject* obj = key->ReadObj();
1204 if ( obj && obj->IsA()->InheritsFrom( "TDirectory" ) ) {
1205 if ( msgLevel( MSG::DEBUG ) ) log << " (" << obj->IsA()->GetName() << ")";
1206 } else if ( obj && obj->IsA()->InheritsFrom( "TEfficiency" ) ) {
1207 if ( msgLevel( MSG::DEBUG ) ) log << " (" << obj->IsA()->GetName() << ")";
1208 tl.Add( obj );
1209 if ( reg && m_curstream != "" ) {
1210 std::string dir = td->GetPath();
1211 std::string fil = td->GetFile()->GetName();
1212 dir.erase( 0, fil.length() + 1 );
1213 std::string id = "/" + m_curstream;
1214 if ( dir == "/" ) {
1215 id = id + "/" + key->GetName();
1216 } else {
1217 id = id + dir + "/" + key->GetName();
1218 }
1219 if ( !exists( id ) ) {
1220 if ( msgLevel( MSG::DEBUG ) ) log << " reg as \"" << id << "\"";
1221 regHist( id ).ignore();
1222 } else {
1223 if ( msgLevel( MSG::DEBUG ) ) log << " already registered";
1224 }
1225 }
1226 } else if ( obj ) {
1227 if ( msgLevel( MSG::DEBUG ) ) log << " [" << obj->IsA()->GetName() << "]";
1228 }
1229 if ( msgLevel( MSG::DEBUG ) ) log << endmsg;
1230 }
1231
1232 // operate recursively
1233 if ( rcs ) {
1234 nextkey = td->GetListOfKeys();
1235 while ( TKey* key = (TKey*)nextkey() ) {
1236 TObject* obj = key->ReadObj();
1237 if ( obj && obj->IsA()->InheritsFrom( "TDirectory" ) ) {
1238 TDirectory* tt = dynamic_cast<TDirectory*>( obj );
1239 getTEfficiencies( tt, tl, rcs, reg ).ignore( /* AUTOMATICALLY ADDED FOR gaudi/Gaudi!763 */ );
1240 }
1241 }
1242 }
1243
1244 return StatusCode::SUCCESS;
1245}
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...
Definition THistSvc.cpp:667
StatusCode regHist(const std::string &name) override
Register a new ROOT histogram TH*X with a name.
Definition THistSvc.cpp:330

◆ getTHists() [1/4]

StatusCode THistSvc::getTHists ( const std::string & name,
TList & tl,
bool recurse = false ) const
override

Definition at line 758 of file THistSvc.cpp.

758 {
759
761
762 gErrorIgnoreLevel = kBreak;
763
764 StatusCode sc;
765
766 std::string stream, rem, r2;
767 parseString( dir, stream, rem );
768
769 auto itr = m_files.find( stream );
770 if ( itr != m_files.end() ) {
771 r2 = itr->second.first->GetName();
772 r2 += ":/";
773 r2 += rem;
774
775 if ( msgLevel( MSG::DEBUG ) ) {
776 debug() << "getTHists: \"" << dir << "\" looks like a stream name."
777 << " associated TFile: \"" << itr->second.first->GetName() << "\"" << endmsg;
778 }
779
780 if ( gDirectory->cd( r2.c_str() ) ) {
782 sc = getTHists( gDirectory, tl, rcs );
783 m_curstream = "";
784 return sc;
785 } else {
786 if ( msgLevel( MSG::DEBUG ) ) { debug() << "getTHists: no such TDirectory \"" << r2 << "\"" << endmsg; }
787 }
788
789 } else {
790 if ( msgLevel( MSG::DEBUG ) ) { debug() << "getTHists: stream \"" << stream << "\" not found" << endmsg; }
791 }
792
793 if ( !gDirectory->cd( dir.c_str() ) ) {
794 error() << "getTHists: No such TDirectory/stream \"" << dir << "\"" << endmsg;
796 } else {
797 sc = getTHists( gDirectory, tl, rcs );
798 }
799
800 return sc;
801}

◆ getTHists() [2/4]

StatusCode THistSvc::getTHists ( const std::string & name,
TList & tl,
bool recurse = false,
bool reg = false )
override

Definition at line 865 of file THistSvc.cpp.

865 {
867
868 gErrorIgnoreLevel = kBreak;
869
870 StatusCode sc;
871
872 std::string stream, rem, r2;
873 parseString( dir, stream, rem );
874
875 auto itr = m_files.find( stream );
876 if ( itr != m_files.end() ) {
877 r2 = itr->second.first->GetName();
878 r2 += ":/";
879 r2 += rem;
880
881 if ( msgLevel( MSG::DEBUG ) ) {
882 debug() << "getTHists: \"" << dir << "\" looks like a stream name."
883 << " associated TFile: \"" << itr->second.first->GetName() << "\"" << endmsg;
884 }
885
886 if ( gDirectory->cd( r2.c_str() ) ) {
888 sc = getTHists( gDirectory, tl, rcs, reg );
889 m_curstream.clear();
890 return sc;
891 }
892 if ( msgLevel( MSG::DEBUG ) ) { debug() << "getTHists: no such TDirectory \"" << r2 << "\"" << endmsg; }
893 } else {
894 if ( msgLevel( MSG::DEBUG ) ) { debug() << "getTHists: stream \"" << stream << "\" not found" << endmsg; }
895 }
896
897 if ( !gDirectory->cd( dir.c_str() ) ) {
898 error() << "getTHists: No such TDirectory/stream \"" << dir << "\"" << endmsg;
900 } else {
901 if ( reg ) {
902 warning() << "Unable to register histograms automatically "
903 << "without a valid stream name" << endmsg;
904 reg = false;
905 }
906 sc = getTHists( gDirectory, tl, rcs, reg );
907 }
908
909 return sc;
910}

◆ getTHists() [3/4]

StatusCode THistSvc::getTHists ( TDirectory * td,
TList & tl,
bool recurse = false ) const
override

Definition at line 713 of file THistSvc.cpp.

713 {
715
716 gErrorIgnoreLevel = kBreak;
717
718 if ( !td->cd() ) {
719 error() << "getTHists: No such TDirectory \"" << td->GetPath() << "\"" << endmsg;
720 return StatusCode::FAILURE;
721 }
722
723 if ( msgLevel( MSG::DEBUG ) ) {
724 debug() << "getTHists: \"" << td->GetPath() << "\": found " << td->GetListOfKeys()->GetSize() << " keys" << endmsg;
725 }
726
727 TIter nextkey( td->GetListOfKeys() );
728 while ( TKey* key = (TKey*)nextkey() ) {
729 auto& log = debug();
730 if ( msgLevel( MSG::DEBUG ) ) log << " key: " << key->GetName();
731 TObject* obj = key->ReadObj();
732 if ( obj != 0 && obj->IsA()->InheritsFrom( "TDirectory" ) ) {
733 if ( msgLevel( MSG::DEBUG ) ) log << " (" << obj->IsA()->GetName() << ")";
734 } else if ( obj != 0 && obj->IsA()->InheritsFrom( "TH1" ) ) {
735 if ( msgLevel( MSG::DEBUG ) ) log << " (" << obj->IsA()->GetName() << ")";
736 tl.Add( obj );
737 } else if ( obj != 0 ) {
738 if ( msgLevel( MSG::DEBUG ) ) log << " [" << obj->IsA()->GetName() << "]";
739 }
740 if ( msgLevel( MSG::DEBUG ) ) log << endmsg;
741 }
742
743 // operate recursively
744 if ( rcs ) {
745 nextkey = td->GetListOfKeys();
746 while ( TKey* key = (TKey*)nextkey() ) {
747 TObject* obj = key->ReadObj();
748 if ( obj && obj->IsA()->InheritsFrom( "TDirectory" ) ) {
749 TDirectory* tt = dynamic_cast<TDirectory*>( obj );
750 getTHists( tt, tl, rcs ).ignore( /* AUTOMATICALLY ADDED FOR gaudi/Gaudi!763 */ );
751 }
752 }
753 }
754
755 return StatusCode::SUCCESS;
756}

◆ getTHists() [4/4]

StatusCode THistSvc::getTHists ( TDirectory * td,
TList & tl,
bool recurse = false,
bool reg = false )
override

Definition at line 803 of file THistSvc.cpp.

803 {
805
806 gErrorIgnoreLevel = kBreak;
807
808 if ( !td->cd() ) {
809 error() << "getTHists: No such TDirectory \"" << td->GetPath() << "\"" << endmsg;
810 return StatusCode::FAILURE;
811 }
812
813 if ( msgLevel( MSG::DEBUG ) ) {
814 debug() << "getTHists: \"" << td->GetPath() << "\": found " << td->GetListOfKeys()->GetSize() << " keys" << endmsg;
815 }
816
817 TIter nextkey( td->GetListOfKeys() );
818 while ( TKey* key = (TKey*)nextkey() ) {
819 auto& log = debug();
820 if ( msgLevel( MSG::DEBUG ) ) log << " key: " << key->GetName();
821 TObject* obj = key->ReadObj();
822 if ( obj && obj->IsA()->InheritsFrom( "TDirectory" ) ) {
823 if ( msgLevel( MSG::DEBUG ) ) log << " (" << obj->IsA()->GetName() << ")";
824 } else if ( obj && obj->IsA()->InheritsFrom( "TH1" ) ) {
825 if ( msgLevel( MSG::DEBUG ) ) log << " (" << obj->IsA()->GetName() << ")";
826 tl.Add( obj );
827 if ( reg && m_curstream != "" ) {
828 std::string dir = td->GetPath();
829 std::string fil = td->GetFile()->GetName();
830 dir.erase( 0, fil.length() + 1 );
831 std::string id = "/" + m_curstream;
832 if ( dir == "/" ) {
833 id = id + "/" + key->GetName();
834 } else {
835 id = id + dir + "/" + key->GetName();
836 }
837 if ( !exists( id ) ) {
838 if ( msgLevel( MSG::DEBUG ) ) log << " reg as \"" << id << "\"";
839 regHist( id ).ignore();
840 } else {
841 if ( msgLevel( MSG::DEBUG ) ) log << " already registered";
842 }
843 }
844 } else if ( obj ) {
845 if ( msgLevel( MSG::DEBUG ) ) log << " [" << obj->IsA()->GetName() << "]";
846 }
847 if ( msgLevel( MSG::DEBUG ) ) log << endmsg;
848 }
849
850 // operate recursively
851 if ( rcs ) {
852 nextkey = td->GetListOfKeys();
853 while ( TKey* key = (TKey*)nextkey() ) {
854 TObject* obj = key->ReadObj();
855 if ( obj && obj->IsA()->InheritsFrom( "TDirectory" ) ) {
856 TDirectory* tt = dynamic_cast<TDirectory*>( obj );
857 getTHists( tt, tl, rcs, reg ).ignore( /* AUTOMATICALLY ADDED FOR gaudi/Gaudi!763 */ );
858 }
859 }
860 }
861
862 return StatusCode::SUCCESS;
863}

◆ getTree()

StatusCode THistSvc::getTree ( const std::string & name,
TTree *& tree ) const
override

Return TTree with given name.

Definition at line 397 of file THistSvc.cpp.

397 {
398 tree = getHist_i<TTree>( id );
399 if ( tree != nullptr ) {
400 return StatusCode::SUCCESS;
401 } else {
402 return StatusCode::FAILURE;
403 }
404}

◆ getTrees()

std::vector< std::string > THistSvc::getTrees ( ) const
override

Definition at line 689 of file THistSvc.cpp.

689 {
690 std::vector<std::string> names;
691 names.reserve( m_uids.size() );
692 transform_if( std::begin( m_uids ), std::end( m_uids ), std::back_inserter( names ), select1st,
693 []( uidMap_t::const_reference i ) { return i.second->at( 0 ).type == ObjectType::TTREE; } );
694 return names;
695}

◆ getTTrees() [1/4]

StatusCode THistSvc::getTTrees ( const std::string & name,
TList & tl,
bool recurse = false ) const
override

Definition at line 957 of file THistSvc.cpp.

957 {
959
960 gErrorIgnoreLevel = kBreak;
961
962 StatusCode sc;
963
964 std::string stream, rem, r2;
965 parseString( dir, stream, rem );
966
967 auto itr = m_files.find( stream );
968 if ( itr != m_files.end() ) {
969 r2 = itr->second.first->GetName();
970 r2 += ":/";
971 r2 += rem;
972
973 if ( msgLevel( MSG::DEBUG ) ) {
974 debug() << "getTTrees: \"" << dir << "\" looks like a stream name."
975 << " associated TFile: \"" << itr->second.first->GetName() << "\"" << endmsg;
976 }
977
978 if ( gDirectory->cd( r2.c_str() ) ) { return getTTrees( gDirectory, tl, rcs ); }
979 if ( msgLevel( MSG::DEBUG ) ) { debug() << "getTTrees: no such TDirectory \"" << r2 << "\"" << endmsg; }
980 } else {
981 if ( msgLevel( MSG::DEBUG ) ) { debug() << "getTTrees: stream \"" << stream << "\" not found" << endmsg; }
982 }
983
984 if ( !gDirectory->cd( dir.c_str() ) ) {
985 error() << "getTTrees: No such TDirectory/stream \"" << dir << "\"" << endmsg;
987 } else {
988 sc = getTTrees( gDirectory, tl, rcs );
989 }
990 return sc;
991}
StatusCode getTTrees(TDirectory *td, TList &, bool recurse=false) const override
Definition THistSvc.cpp:912

◆ getTTrees() [2/4]

StatusCode THistSvc::getTTrees ( const std::string & name,
TList & tl,
bool recurse = false,
bool reg = false )
override

Definition at line 1055 of file THistSvc.cpp.

1055 {
1057
1058 gErrorIgnoreLevel = kBreak;
1059
1060 StatusCode sc;
1061
1062 std::string stream, rem, r2;
1063 parseString( dir, stream, rem );
1064
1065 auto itr = m_files.find( stream );
1066 if ( itr != m_files.end() ) {
1067 r2 = itr->second.first->GetName();
1068 r2 += ":/";
1069 r2 += rem;
1070
1071 if ( msgLevel( MSG::DEBUG ) ) {
1072 debug() << "getTTrees: \"" << dir << "\" looks like a stream name."
1073 << " associated TFile: \"" << itr->second.first->GetName() << "\"" << endmsg;
1074 }
1075
1076 if ( gDirectory->cd( r2.c_str() ) ) {
1077 return getTTrees( gDirectory, tl, rcs, reg );
1078 } else {
1079 if ( msgLevel( MSG::DEBUG ) ) { debug() << "getTTrees: no such TDirectory \"" << r2 << "\"" << endmsg; }
1080 }
1081 } else {
1082 if ( msgLevel( MSG::DEBUG ) ) { debug() << "getTTrees: stream \"" << stream << "\" not found" << endmsg; }
1083 }
1084
1085 if ( !gDirectory->cd( dir.c_str() ) ) {
1086 error() << "getTTrees: No such TDirectory/stream \"" << dir << "\"" << endmsg;
1087 return StatusCode::FAILURE;
1088 }
1089
1090 return getTTrees( gDirectory, tl, rcs, reg );
1091}

◆ getTTrees() [3/4]

StatusCode THistSvc::getTTrees ( TDirectory * td,
TList & tl,
bool recurse = false ) const
override

Definition at line 912 of file THistSvc.cpp.

912 {
914
915 gErrorIgnoreLevel = kBreak;
916
917 if ( !td->cd() ) {
918 error() << "getTTrees: No such TDirectory \"" << td->GetPath() << "\"" << endmsg;
919 return StatusCode::FAILURE;
920 }
921
922 if ( msgLevel( MSG::DEBUG ) ) {
923 debug() << "getTHists: \"" << td->GetPath() << "\": found " << td->GetListOfKeys()->GetSize() << " keys" << endmsg;
924 }
925
926 TIter nextkey( td->GetListOfKeys() );
927 while ( TKey* key = (TKey*)nextkey() ) {
928 auto& log = debug();
929 if ( msgLevel( MSG::DEBUG ) ) log << " key: " << key->GetName();
930 TObject* obj = key->ReadObj();
931 if ( obj != 0 && obj->IsA()->InheritsFrom( "TDirectory" ) ) {
932 if ( msgLevel( MSG::DEBUG ) ) log << " (" << obj->IsA()->GetName() << ")";
933 } else if ( obj != 0 && obj->IsA()->InheritsFrom( "TTree" ) ) {
934 if ( msgLevel( MSG::DEBUG ) ) log << " (" << obj->IsA()->GetName() << ")";
935 tl.Add( obj );
936 } else if ( obj != 0 ) {
937 if ( msgLevel( MSG::DEBUG ) ) log << " [" << obj->IsA()->GetName() << "]";
938 }
939 log << endmsg;
940 }
941
942 // operate recursively
943 if ( rcs ) {
944 nextkey = td->GetListOfKeys();
945 while ( TKey* key = (TKey*)nextkey() ) {
946 TObject* obj = key->ReadObj();
947 if ( obj && obj->IsA()->InheritsFrom( "TDirectory" ) ) {
948 TDirectory* tt = dynamic_cast<TDirectory*>( obj );
949 getTTrees( tt, tl, rcs ).ignore( /* AUTOMATICALLY ADDED FOR gaudi/Gaudi!763 */ );
950 }
951 }
952 }
953
954 return StatusCode::SUCCESS;
955}

◆ getTTrees() [4/4]

StatusCode THistSvc::getTTrees ( TDirectory * td,
TList & tl,
bool recurse = false,
bool reg = false )
override

Definition at line 993 of file THistSvc.cpp.

993 {
995
996 gErrorIgnoreLevel = kBreak;
997
998 if ( !td->cd() ) {
999 error() << "getTTrees: No such TDirectory \"" << td->GetPath() << "\"" << endmsg;
1000 return StatusCode::FAILURE;
1001 }
1002
1003 if ( msgLevel( MSG::DEBUG ) ) {
1004 debug() << "getTHists: \"" << td->GetPath() << "\": found " << td->GetListOfKeys()->GetSize() << " keys" << endmsg;
1005 }
1006
1007 TIter nextkey( td->GetListOfKeys() );
1008 while ( TKey* key = (TKey*)nextkey() ) {
1009 auto& log = debug();
1010 if ( msgLevel( MSG::DEBUG ) ) log << " key: " << key->GetName();
1011 TObject* obj = key->ReadObj();
1012 if ( obj && obj->IsA()->InheritsFrom( "TDirectory" ) ) {
1013 if ( msgLevel( MSG::DEBUG ) ) log << " (" << obj->IsA()->GetName() << ")";
1014 } else if ( obj && obj->IsA()->InheritsFrom( "TTree" ) ) {
1015 if ( msgLevel( MSG::DEBUG ) ) log << " (" << obj->IsA()->GetName() << ")";
1016 tl.Add( obj );
1017 if ( reg && m_curstream != "" ) {
1018 std::string dir = td->GetPath();
1019 std::string fil = td->GetFile()->GetName();
1020 dir.erase( 0, fil.length() + 1 );
1021 std::string id = "/" + m_curstream;
1022 if ( dir == "/" ) {
1023 id = id + "/" + key->GetName();
1024 } else {
1025 id = id + dir + "/" + key->GetName();
1026 }
1027 if ( !exists( id ) ) {
1028 if ( msgLevel( MSG::DEBUG ) ) log << " reg as \"" << id << "\"";
1029 regHist( id ).ignore();
1030 } else {
1031 if ( msgLevel( MSG::DEBUG ) ) log << " already registered";
1032 }
1033 }
1034 } else if ( obj != 0 ) {
1035 if ( msgLevel( MSG::DEBUG ) ) log << " [" << obj->IsA()->GetName() << "]";
1036 }
1037 if ( msgLevel( MSG::DEBUG ) ) log << endmsg;
1038 }
1039
1040 // operate recursively
1041 if ( rcs ) {
1042 nextkey = td->GetListOfKeys();
1043 while ( TKey* key = (TKey*)nextkey() ) {
1044 TObject* obj = key->ReadObj();
1045 if ( obj && obj->IsA()->InheritsFrom( "TDirectory" ) ) {
1046 TDirectory* tt = dynamic_cast<TDirectory*>( obj );
1047 getTTrees( tt, tl, rcs, reg ).ignore( /* AUTOMATICALLY ADDED FOR gaudi/Gaudi!763 */ );
1048 }
1049 }
1050 }
1051
1052 return StatusCode::SUCCESS;
1053}

◆ handle()

void THistSvc::handle ( const Incident & )
override

Definition at line 1296 of file THistSvc.cpp.

1296 {
1297
1298 if ( m_maxFileSize.value() == -1 ) return;
1299
1300 // convert to bytes.
1301 Long64_t mfs = (Long64_t)m_maxFileSize.value() * (Long64_t)1048576;
1302 Long64_t mfs_warn = mfs * 95 / 100;
1303
1304 updateFiles();
1305
1306 for ( const auto& f : m_files ) {
1307 TFile* tf = f.second.first;
1308
1309#ifndef NDEBUG
1310 if ( msgLevel( MSG::DEBUG ) ) {
1311 debug() << "stream: " << f.first << " name: " << tf->GetName() << " size: " << tf->GetSize() << endmsg;
1312 }
1313#endif
1314
1315 // Terminate job if output file is too large
1316 if ( tf->GetSize() > mfs ) {
1317
1318 if ( writeObjectsToFile().isFailure() ) { error() << "problems writing histograms" << endmsg; }
1319 throw GaudiException( fmt::format( "file \"{}\" associated with stream \"{}\" has exceeded the max "
1320 "file size of {} MB. Terminating Job.",
1321 tf->GetName(), f.first, m_maxFileSize.value() ),
1323
1324 } else if ( tf->GetSize() > mfs_warn ) {
1325 warning() << "file \"" << tf->GetName() << "\" associated with stream \"" << f.first
1326 << "\" is at 95% of its maximum allowable file size of " << m_maxFileSize.value() << "MB" << endmsg;
1327 }
1328 }
1329}
Gaudi::Property< int > m_maxFileSize
Definition THistSvc.h:372
void updateFiles()
Handle case where TTree grows beyond TTree::fgMaxTreeSize.

◆ initialize()

StatusCode THistSvc::initialize ( )
override

Definition at line 82 of file THistSvc.cpp.

82 {
84
85 StatusCode status = Service::initialize();
86
87 if ( status.isFailure() ) {
88 error() << "initializing service" << endmsg;
89 return status;
90 }
91
92 StatusCode st( StatusCode::SUCCESS );
93
94 try {
96 } catch ( GaudiException& err ) {
97 error() << "Caught: " << err << endmsg;
99 }
100
101 try {
103 } catch ( GaudiException& err ) {
104 error() << "Caught: " << err << endmsg;
106 }
107
108 // Protect against multiple instances of TROOT
109 if ( !gROOT ) {
110 static TROOT root( "root", "ROOT I/O" );
111 // gDebug = 99;
112 } else {
113 if ( msgLevel( MSG::VERBOSE ) ) { verbose() << "ROOT already initialized, debug = " << gDebug << endmsg; }
114 }
115
116 if ( p_incSvc.retrieve().isFailure() ) {
117 error() << "unable to get the IncidentSvc" << endmsg;
119 } else {
120 p_incSvc->addListener( this, "EndEvent", 100, true );
121 }
122
123 if ( p_fileMgr.retrieve().isFailure() ) {
124 error() << "unable to get the FileMgr" << endmsg;
126 } else {
127 if ( msgLevel( MSG::DEBUG ) ) { debug() << "got the FileMgr" << endmsg; }
128 }
129
130 // Register open/close callback actions
131 using namespace std::placeholders;
132 auto boa = [this]( const Io::FileAttr* fa, const std::string& caller ) { return this->rootOpenAction( fa, caller ); };
133 if ( p_fileMgr->regAction( boa, Io::OPEN, Io::ROOT ).isFailure() ) {
134 error() << "unable to register ROOT file open action with FileMgr" << endmsg;
135 }
136 auto bea = [this]( const Io::FileAttr* fa, const std::string& caller ) {
137 return this->rootOpenErrAction( fa, caller );
138 };
139 if ( p_fileMgr->regAction( bea, Io::OPEN_ERR, Io::ROOT ).isFailure() ) {
140 error() << "unable to register ROOT file open Error action with FileMgr" << endmsg;
141 }
142
143 m_okToConnect = true;
144 if ( m_delayConnect ) {
145 if ( !m_inputfile.value().empty() ) setupInputFile();
146 if ( !m_outputfile.value().empty() ) setupOutputFile();
147 m_delayConnect = false;
148 }
151
152 auto iomgr = service<IIoComponentMgr>( "IoComponentMgr" );
153 if ( !iomgr ) {
154 error() << "unable to get the IoComponentMgr" << endmsg;
156 } else {
157 if ( !iomgr->io_register( this ).isSuccess() ) {
158 error() << "could not register with the I/O component manager !" << endmsg;
160 } else {
161 bool all_good = true;
162 // register input/output files...
163 for ( const auto& reg : m_files ) {
164 const std::string& fname = reg.second.first->GetName();
165 const IIoComponentMgr::IoMode::Type iomode =
167 if ( !iomgr->io_register( this, iomode, fname ).isSuccess() ) {
168 warning() << "could not register file [" << fname << "] with the I/O component manager..." << endmsg;
169 all_good = false;
170 } else {
171 info() << "registered file [" << fname << "]... [ok]" << endmsg;
172 }
173 }
174 if ( !all_good ) {
175 error() << "problem while registering input/output files with "
176 << "the I/O component manager !" << endmsg;
178 }
179 }
180 }
181
182 if ( st.isFailure() ) { fatal() << "Unable to initialize THistSvc" << endmsg; }
183
184 return st;
185}
MsgStream & fatal() const
shortcut for the method msgStream(MSG::FATAL)
MsgStream & err() const
shortcut for the method msgStream(MSG::ERROR)
SmartIF< IFace > service(const std::string &name, bool createIf=true) const
Definition Service.h:79
StatusCode initialize() override
Definition Service.cpp:118
void setupOutputFile()
call-back method to handle output stream property
void setupInputFile()
call-back method to handle input stream property
Gaudi::Property< std::vector< std::string > > m_inputfile
Definition THistSvc.h:383
bool m_delayConnect
Definition THistSvc.h:391
bool m_okToConnect
Definition THistSvc.h:392
Gaudi::Property< std::vector< std::string > > m_outputfile
Definition THistSvc.h:381
StatusCode rootOpenAction(FILEMGR_CALLBACK_ARGS)
std::set< std::string > m_alreadyConnectedOutFiles
list of already connected files.
Definition THistSvc.h:275
std::set< std::string > m_alreadyConnectedInFiles
list of already connected files.
Definition THistSvc.h:271
StatusCode rootOpenErrAction(FILEMGR_CALLBACK_ARGS)
@ OPEN
Definition IFileMgr.h:263
@ OPEN_ERR
Definition IFileMgr.h:263

◆ io_reinit()

StatusCode THistSvc::io_reinit ( )
override

callback method to reinitialize the internal state of the component for I/O purposes (e.g.

upon fork(2))

Definition at line 1334 of file THistSvc.cpp.

1334 {
1335 bool all_good = true;
1336 if ( msgLevel( MSG::DEBUG ) ) { debug() << "reinitializing I/O..." << endmsg; }
1337
1338 // retrieve the I/O component manager...
1339
1340 auto iomgr = service<IIoComponentMgr>( "IoComponentMgr", true );
1341 if ( !iomgr ) {
1342 error() << "could not retrieve I/O component manager !" << endmsg;
1343 return StatusCode::FAILURE;
1344 }
1345
1347 // to hide the expected errors upon closing the files whose
1348 // file descriptors have been swept under the rug...
1349 gErrorIgnoreLevel = kFatal;
1350
1351 for ( auto& ifile : m_files ) {
1352 TFile* f = ifile.second.first;
1353 std::string fname = f->GetName();
1354 if ( msgLevel( MSG::DEBUG ) ) {
1355 debug() << "file [" << fname << "] mode: [" << f->GetOption() << "] r:" << f->GetFileBytesRead()
1356 << " w:" << f->GetFileBytesWritten() << " cnt:" << f->GetFileCounter() << endmsg;
1357 }
1358
1359 if ( ifile.second.second == READ ) {
1360 if ( msgLevel( MSG::DEBUG ) ) { debug() << " TFile opened in READ mode: not reassigning names" << endmsg; }
1361 continue;
1362 }
1363
1364 if ( !iomgr->io_retrieve( this, fname ).isSuccess() ) {
1365 error() << "could not retrieve new name for [" << fname << "] !!" << endmsg;
1366 all_good = false;
1367 continue;
1368 } else if ( fname.empty() ) {
1369 if ( msgLevel( MSG::DEBUG ) ) { debug() << "empty new name for [" << fname << "], skipping..." << endmsg; }
1370 continue;
1371 } else {
1372 if ( msgLevel( MSG::DEBUG ) ) { debug() << "got a new name [" << fname << "]..." << endmsg; }
1373 }
1374
1375 void* vf = nullptr;
1376 Option_t* opts = f->GetOption();
1377 int r = p_fileMgr->open( Io::ROOT, name(), fname, Io::WRITE, vf, "HIST" );
1378 if ( r != 0 ) {
1379 error() << "unable to open file \"" << fname << "\" for writing" << endmsg;
1380 return StatusCode::FAILURE;
1381 }
1382 TFile* newfile = (TFile*)vf;
1383 newfile->SetOption( opts );
1384
1385 if ( ifile.second.second != THistSvc::READ ) {
1386 copyFileLayout( newfile, f );
1387 ifile.second.first = newfile;
1388 }
1389
1390 // loop over all uids and migrate them to the new file
1391 for ( auto& uid : m_uids ) {
1392 for ( auto& hid : *uid.second ) {
1393 if ( hid.file != f ) continue;
1394 TDirectory* olddir = this->changeDir( hid );
1395 hid.file = newfile;
1396 // side-effect: create needed directories...
1397 TDirectory* newdir = this->changeDir( hid );
1398 TClass* cl = hid.obj->IsA();
1399
1400 // migrate the objects to the new file.
1401 // thanks to the object model of ROOT, it is super easy.
1402 if ( hid.type == ObjectType::TTREE ) {
1403 TTree& tree = dynamic_cast<TTree&>( *hid.obj );
1404 tree.SetDirectory( newdir );
1405 tree.Reset();
1406 } else if ( hid.type == ObjectType::TH1 ) {
1407 TH1& hist = dynamic_cast<TH1&>( *hid.obj );
1408 hist.SetDirectory( newdir );
1409 hist.Reset();
1410 } else if ( hid.type == ObjectType::TEFFICIENCY ) {
1411 dynamic_cast<TEfficiency&>( *hid.obj ).SetDirectory( newdir );
1412 } else if ( hid.type == ObjectType::TGRAPH ) {
1413 olddir->Remove( hid.obj );
1414 newdir->Append( hid.obj );
1415 } else {
1416 error() << "id: \"" << hid.id << "\" is not a inheriting from a class "
1417 << "we know how to handle (received [" << cl->GetName() << "], "
1418 << "expected [TTree, TH1, TGraph or TEfficiency]) !" << endmsg << "attaching to current dir ["
1419 << newdir->GetPath() << "] "
1420 << "nonetheless..." << endmsg;
1421 olddir->Remove( hid.obj );
1422 newdir->Append( hid.obj );
1423 }
1424 }
1425 }
1426 f->ReOpen( "READ" );
1427 p_fileMgr->close( f, name() );
1428 f = newfile;
1429 }
1430
1431 return all_good ? StatusCode::SUCCESS : StatusCode::FAILURE;
1432}
TDirectory * changeDir(const THistSvc::THistID &hid) const

◆ merge() [1/4]

StatusCode THistSvc::merge ( const std::string & id)
override

Merge all clones for object with a given id.

Definition at line 647 of file THistSvc.cpp.

647 {
648 uidMap_t::iterator itr = m_uids.find( name );
649 if ( itr == m_uids.end() ) {
650 error() << "merge: id \"" << name << "\" not found" << endmsg;
651 return StatusCode::FAILURE;
652 }
653
654 return merge( itr->second );
655}
StatusCode merge(const std::string &id) override
Merge all clones for object with a given id.
Definition THistSvc.cpp:647

◆ merge() [2/4]

StatusCode THistSvc::merge ( const THistID & hid)
private

Helper method to merge THistID objects.

Definition at line 2024 of file THistSvc.cpp.

2024{ return merge( hid.id ); }

◆ merge() [3/4]

StatusCode THistSvc::merge ( TObject * obj)
override

Merge all clones for given TObject*.

Definition at line 657 of file THistSvc.cpp.

657 {
658 objMap_t::iterator itr = m_tobjs.find( obj );
659 if ( itr != m_tobjs.end() ) {
660 return merge( itr->second.first );
661 } else {
662 error() << "merge: unknown object " << obj << endmsg;
663 return StatusCode::FAILURE;
664 }
665}

◆ merge() [4/4]

StatusCode THistSvc::merge ( vhid_t * vh)
private

Helper method to merge vectors of THistID.

Definition at line 2026 of file THistSvc.cpp.

2026 {
2027 const std::string& name = vh->at( 0 ).id;
2028 if ( vh->size() == 1 ) {
2029 debug() << "merge: id: \"" << name << "\" is size 1. nothing to do" << endmsg;
2030 return StatusCode::SUCCESS;
2031 }
2032
2033 if ( vh->at( 0 ).type != ObjectType::TH1 ) {
2034 error() << "merge: id \"" << name << "\" is not a THn. Cannot merge" << endmsg;
2035 return StatusCode::FAILURE;
2036 }
2037
2038 TList* l = new TList();
2039 for ( size_t i = 1; i < vh->size(); ++i ) {
2040 debug() << "merge: id: \"" << name << "\" (" << vh->at( i ).obj << ") adding index " << i << endmsg;
2041 l->Add( vh->at( i ).obj );
2042 }
2043
2044 TH1* t0 = dynamic_cast<TH1*>( vh->at( 0 ).obj );
2045 if ( t0 == 0 ) {
2046 error() << "merge: could not dcast " << name << "(" << t0 << ") index " << 0 << " to TH1" << endmsg;
2047 return StatusCode::FAILURE;
2048 }
2049
2050 Long64_t n = t0->Merge( l );
2051
2052 debug() << "merge: id: \"" << name << "\" merged " << n << " entries" << endmsg;
2053
2054 for ( size_t i = 1; i < vh->size(); ++i ) {
2055 TH1* th = dynamic_cast<TH1*>( vh->at( i ).obj );
2056 if ( th != 0 ) {
2057 debug() << "clearing index " << i << "(" << th << ")" << endmsg;
2058 th->SetDirectory( nullptr );
2059 th->Reset();
2060 } else {
2061 error() << "merge: could not dcast " << name << " index " << i << " to TH1" << endmsg;
2062 return StatusCode::FAILURE;
2063 }
2064 }
2065 return StatusCode::SUCCESS;
2066}
dict l
Definition gaudirun.py:583

◆ MergeRootFile()

void THistSvc::MergeRootFile ( TDirectory * target,
TDirectory * source )
private

Definition at line 1770 of file THistSvc.cpp.

1770 {
1771 if ( msgLevel( MSG::DEBUG ) ) { debug() << "Target path: " << target->GetPath() << endmsg; }
1772 TString path( (char*)strstr( target->GetPath(), ":" ) );
1773 path.Remove( 0, 2 );
1774
1775 source->cd( path );
1776 TDirectory* current_sourcedir = gDirectory;
1777
1778 // loop over all keys in this directory
1779 TList* lkeys = current_sourcedir->GetListOfKeys();
1780 int nkeys = lkeys->GetEntries();
1781 TKey* key = nullptr;
1782 for ( int jj = 0; jj < nkeys; jj++ ) {
1783 key = (TKey*)lkeys->At( jj );
1784 std::string pathnameinsource = current_sourcedir->GetPath() + std::string( "/" ) + key->GetName();
1785 if ( msgLevel( MSG::DEBUG ) ) { debug() << "Reading Key:" << pathnameinsource << endmsg; }
1786 TObject* obj = source->Get( pathnameinsource.c_str() );
1787
1788 if ( obj ) {
1789 if ( obj->IsA()->InheritsFrom( "TDirectory" ) ) {
1790 // it's a subdirectory
1791 if ( msgLevel( MSG::DEBUG ) ) { debug() << "Found subdirectory " << obj->GetName() << endmsg; }
1792
1793 // create a new subdir of same name and title in the target file
1794 target->cd();
1795 TDirectory* newtargetdir = target->mkdir( obj->GetName(), obj->GetTitle() );
1796
1797 MergeRootFile( newtargetdir, source );
1798
1799 } else if ( obj->IsA()->InheritsFrom( "TTree" ) ) {
1800 if ( msgLevel( MSG::DEBUG ) ) { debug() << "Found TTree " << obj->GetName() << endmsg; }
1801 TTree* mytree = dynamic_cast<TTree*>( obj );
1802 int nentries = (int)mytree->GetEntries();
1803 mytree->SetBranchStatus( "*", 1 );
1804
1805 if ( msgLevel( MSG::DEBUG ) ) { debug() << "Dumping TTree " << nentries << " entries" << endmsg; }
1806 target->cd();
1807 mytree->CloneTree();
1808
1809 } else {
1810 target->cd();
1811 obj->Write( key->GetName() );
1812 }
1813 }
1814 }
1815}

◆ parseString()

void THistSvc::parseString ( const std::string & id,
std::string & root,
std::string & rem ) const
private

Definition at line 1853 of file THistSvc.cpp.

1853 {
1854 auto pos = id.find( "/" );
1855
1856 if ( pos == std::string::npos ) {
1857 root.clear();
1858 rem = id;
1859 } else if ( pos == 0 ) {
1860 parseString( id.substr( 1 ), root, rem );
1861 } else {
1862 root = id.substr( 0, pos );
1863 rem = id.substr( pos + 1 );
1864 }
1865}

◆ readHist()

template<typename T>
T * THistSvc::readHist ( const std::string & name) const
private

Definition at line 1451 of file THistSvc.cpp.

1451 {
1452 return dynamic_cast<T*>( readHist_i<T>( id ) );
1453}
T * readHist_i(const std::string &name) const
Definition THistSvc.icc:225

◆ readHist_i()

template<typename T>
T * THistSvc::readHist_i ( const std::string & name) const
private

Definition at line 225 of file THistSvc.icc.

225 {
227
228 std::string idr( id );
229 removeDoubleSlash( idr );
230
231 std::string stream, rem, dir, fdir, bdir, fdir2;
232 TFile* file = nullptr;
233
234 if ( !findStream( idr, stream, rem, file ) ) { return nullptr; }
235
236 if ( !file ) {
237 error() << "no associated file found" << endmsg;
238 return nullptr;
239 }
240
241 file->cd( "/" );
242
243 fdir = idr;
244 bdir = stripDirectoryName( fdir );
245 fdir2 = fdir;
246 while ( ( dir = stripDirectoryName( fdir ) ) != "" ) {
247 if ( !gDirectory->GetKey( dir.c_str() ) ) {
248 error() << "Directory \"" << fdir2 << "\" doesnt exist in " << file->GetName() << endmsg;
249 return nullptr;
250 }
251 gDirectory->cd( dir.c_str() );
252 }
253
254 TObject* to = nullptr;
255 gDirectory->GetObject( fdir.c_str(), to );
256
257 if ( !to ) {
258 error() << "Could not get obj \"" << fdir << "\" in " << gDirectory->GetPath() << endmsg;
259 return nullptr;
260 }
261
262 T* hist = dynamic_cast<T*>( to );
263 if ( hist == nullptr ) {
264 error() << "Could not convert \"" << idr << "\" to a " << System::typeinfoName( typeid( *hist ) ) << " as is a "
265 << to->IsA()->GetName() << endmsg;
266 return nullptr;
267 }
268
269 if ( msgLevel( MSG::DEBUG ) ) {
270 debug() << "Read in " << hist->IsA()->GetName() << " \"" << hist->GetName() << "\" from file " << file->GetName()
271 << endmsg;
272 hist->Print();
273 }
274
275 return hist;
276}
bool findStream(const std::string &name, std::string &root, std::string &rem, TFile *&file) const
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition System.cpp:260

◆ readTree()

TTree * THistSvc::readTree ( const std::string & name) const
private

Definition at line 1455 of file THistSvc.cpp.

1455{ return dynamic_cast<TTree*>( readHist_i<TTree>( id ) ); }

◆ regEfficiency() [1/3]

StatusCode THistSvc::regEfficiency ( const std::string & name)
override

Register a new TEfficiency with a given name.

Definition at line 447 of file THistSvc.cpp.

447 {
448 std::unique_ptr<TEfficiency> eff = nullptr;
449 return regHist_i( std::move( eff ), id, false );
450}
StatusCode regHist_i(std::unique_ptr< T > hist, const std::string &name, bool shared)
Definition THistSvc.icc:21

◆ regEfficiency() [2/3]

StatusCode THistSvc::regEfficiency ( const std::string & name,
std::unique_ptr< TEfficiency > eff )
override

Register an existing TEfficiency with a given name and moved unique_ptr.

Definition at line 452 of file THistSvc.cpp.

452 {
453 return regHist_i( std::move( eff ), id, false );
454}

◆ regEfficiency() [3/3]

StatusCode THistSvc::regEfficiency ( const std::string & name,
TEfficiency * eff_ptr )
overridevirtual
Deprecated
{Just kept for compatibiltiy to current ATLAS code. Pleas use std::unique_ptrs instead!} Register a new TEfficiency with a given name and a raw pointer

Definition at line 456 of file THistSvc.cpp.

456 {
457 std::unique_ptr<TEfficiency> eff( eff_ptr );
458 return regHist_i( std::move( eff ), id, false );
459}

◆ regGraph() [1/3]

StatusCode THistSvc::regGraph ( const std::string & name)
override

Register a new TGraph with a given name.

Definition at line 406 of file THistSvc.cpp.

406 {
407 std::unique_ptr<TGraph> graph = std::make_unique<TGraph>();
408 return regHist_i( std::move( graph ), id, false );
409}

◆ regGraph() [2/3]

StatusCode THistSvc::regGraph ( const std::string & name,
std::unique_ptr< TGraph > graph )
override

Register an existing TGraph with a given name and moved unique_ptr.

Definition at line 411 of file THistSvc.cpp.

411 {
412 if ( strcmp( graph->GetName(), "Graph" ) == 0 ) {
413 std::string id2( id );
414 std::string::size_type i = id2.rfind( "/" );
415 if ( i != std::string::npos ) { id2.erase( 0, i + 1 ); }
416
417 info() << "setting name of TGraph id: \"" << id << "\" to \"" << id2 << "\" since it is unset" << endmsg;
418 graph->SetName( id2.c_str() );
419 }
420
421 return regHist_i( std::move( graph ), id, false );
422}

◆ regGraph() [3/3]

StatusCode THistSvc::regGraph ( const std::string & name,
TGraph * graph_ptr )
overridevirtual
Deprecated
{Just kept for compatibiltiy to current ATLAS code. Pleas use std::unique_ptrs instead!} Register a new TGraph with a given name and a raw pointer

Definition at line 424 of file THistSvc.cpp.

424 {
425 std::unique_ptr<TGraph> graph( graph_ptr );
426 if ( strcmp( graph->GetName(), "Graph" ) == 0 ) {
427 std::string id2( id );
428 std::string::size_type i = id2.rfind( "/" );
429 if ( i != std::string::npos ) { id2.erase( 0, i + 1 ); }
430
431 info() << "setting name of TGraph id: \"" << id << "\" to \"" << id2 << "\" since it is unset" << endmsg;
432 graph->SetName( id2.c_str() );
433 }
434
435 return regHist_i( std::move( graph ), id, false );
436}

◆ regHist() [1/3]

StatusCode THistSvc::regHist ( const std::string & name)
override

Register a new ROOT histogram TH*X with a name.

Definition at line 330 of file THistSvc.cpp.

330 {
331 std::unique_ptr<TH1> hist = nullptr;
332 return regHist_i( std::move( hist ), id, false );
333}

◆ regHist() [2/3]

StatusCode THistSvc::regHist ( const std::string & name,
std::unique_ptr< TH1 > hist )
override

Register an existing ROOT histogram TH*X with name and moved unique_ptr.

Parameters
[in]namedefines the histogram id/name under which it is recorded
[in]histtransfers ownership of the histogram to the THistSvc

Definition at line 335 of file THistSvc.cpp.

335 {
336 return regHist_i( std::move( hist ), id, false );
337}

◆ regHist() [3/3]

StatusCode THistSvc::regHist ( const std::string & name,
TH1 * hist_ptr )
override
Deprecated
{Just for compatibility purposes. Ownership should be clearly managed.} Register an existing ROOT histogram TH*X with name and pointer

Definition at line 339 of file THistSvc.cpp.

339 {
340 std::unique_ptr<TH1> hist( hist_ptr );
341 return regHist_i( std::move( hist ), id, false );
342}

◆ regHist_i() [1/2]

template<typename T>
StatusCode THistSvc::regHist_i ( std::unique_ptr< T > hist,
const std::string & name,
bool shared )
private

Definition at line 21 of file THistSvc.icc.

21 {
22 THistID* hid = nullptr;
23 return regHist_i( std::move( hist ), id, shared, hid );
24}

◆ regHist_i() [2/2]

template<typename T>
StatusCode THistSvc::regHist_i ( std::unique_ptr< T > hist,
const std::string & name,
bool shared,
THistID *& hid )
private

Definition at line 27 of file THistSvc.icc.

27 {
29 phid = nullptr;
30
31 // It is sad that we lose propper memory management here
32 T* hist = nullptr;
33 if ( hist_unique.get() != nullptr ) { hist = hist_unique.release(); }
34 if ( msgLevel( MSG::DEBUG ) ) {
35 debug() << "regHist_i obj: " << hist << " id: " << id << " s: " << shared << endmsg;
36 }
37
38 std::string idr( id );
39 removeDoubleSlash( idr );
40
41 if ( idr.find( "/" ) == idr.length() ) {
42 error() << "Badly formed identifier \"" << idr << "\": "
43 << "Must not end with a /" << endmsg;
44 delete hist;
46 }
47
48 TFile* f = nullptr;
49 std::string stream, name;
50 if ( !findStream( idr, stream, name, f ) ) {
51 error() << "Could not register id: \"" << idr << "\"" << endmsg;
52 delete hist;
54 }
55
56 std::string uid = "/" + stream + "/" + name;
57
58 uidMap_t::iterator uitr = m_uids.find( uid );
59 bool exists( false );
60 if ( uitr != m_uids.end() ) {
61 exists = true;
62 TObject* t1 = uitr->second->at( 0 ).obj;
63 if ( hist->Compare( t1 ) != 0 ) {
64 error() << "previously registered object with identifier \"" << uid << "\" does not compare to this one"
65 << endmsg;
66 delete hist;
68 } else {
69 if ( msgLevel( MSG::DEBUG ) ) {
70 debug() << "previously registered id \"" << uid << "\": num " << uitr->second->size() << endmsg;
71 }
72 }
73 }
74
75 bool temp = false;
76 if ( !f ) {
77 temp = true;
78 if ( msgLevel( MSG::DEBUG ) ) { debug() << "Historgram with id \"" << idr << "\" is temporary" << endmsg; }
79 }
80
81 TObject* to = nullptr;
82 THistID hid;
83 // check to see if this hist is to be read in;
84 if ( !temp && m_files.find( stream )->second.second == READ ) {
85 if ( hist != 0 ) { warning() << "Registering id: \"" << idr << "\" with non zero pointer!" << endmsg; }
86
87 hist = readHist_i<T>( idr );
88 if ( hist == nullptr ) {
89 error() << "Unable to read in hist" << endmsg;
90 delete hist;
92 }
93 to = dynamic_cast<TObject*>( hist );
94 hid = THistID( uid, temp, to, f, m_files.find( stream )->second.second );
95 } else if ( !hist ) {
96 error() << "Unable to read in hist with id: \"" << idr << "\"" << endmsg;
97 delete hist;
99 } else {
100 to = dynamic_cast<TObject*>( hist );
101 if ( to == nullptr ) {
102 error() << "Could not dcast to TObject. id: \"" << idr << "\"" << endmsg;
103 delete hist;
104 return StatusCode::FAILURE;
105 }
106
107 auto oitr = m_tobjs.find( to );
108 if ( oitr != m_tobjs.end() ) {
109 error() << "already registered id: \"" << idr << "\" with identifier \""
110 << oitr->second.first->at( oitr->second.second ).id << "\"" << endmsg;
111 delete hist;
112 return StatusCode::FAILURE;
113 }
114 }
115
116 const auto findF = m_files.find( stream );
117 hid = ( findF != m_files.end() ? THistID( uid, temp, to, f, findF->second.second ) : THistID( uid, temp, to, f ) );
118
119 hid.shared = shared;
120 TDirectory* dir = changeDir( hid );
121
122 if ( TTree* tree = dynamic_cast<TTree*>( hist ) ) {
123 tree->SetDirectory( dir );
124 hid.type = ObjectType::TTREE;
125 m_hasTTrees = true; // at least one TTree is registered
126 } else if ( TH1* th1 = dynamic_cast<TH1*>( hist ) ) {
127 th1->SetDirectory( dir );
128 hid.type = ObjectType::TH1;
129 } else if ( TEfficiency* teff = dynamic_cast<TEfficiency*>( hist ) ) {
130 teff->SetDirectory( dir );
131 hid.type = ObjectType::TEFFICIENCY;
132 } else if ( dynamic_cast<TGraph*>( hist ) ) {
133 dir->Append( hist );
134 hid.type = ObjectType::TGRAPH;
135 } else {
136 error() << "id: \"" << idr << "\" is not a TH, TTree, TGraph, or TEfficiency. Attaching it to current dir."
137 << endmsg;
138 dir->Append( hist );
139 hid.type = ObjectType::UNKNOWN;
140 }
141
142 std::string fname;
143 if ( !f ) {
144 fname = "none";
145 } else {
146 fname = f->GetName();
147 }
148
149 if ( msgLevel( MSG::DEBUG ) ) {
150 debug() << "Registering" << ( shared ? " shared " : " " ) << System::typeinfoName( typeid( *hist ) ) << " title: \""
151 << hist->GetTitle() << "\" id: \"" << uid
152 << "\" dir: "
153 // << hist->GetDirectory()->GetPath() << " "
154 << changeDir( hid )->GetPath() << " file: " << fname << endmsg;
155 }
156
157 // create a mutex for all shared histograms
158 if ( shared ) { hid.mutex = new histMut_t; }
159
160 if ( exists ) {
161 vhid_t* vi = uitr->second;
162 vi->push_back( hid );
163 phid = &( vi->back() );
164
165 m_tobjs.emplace( to, std::pair<vhid_t*, size_t>( vi, vi->size() - 1 ) );
166 } else {
167 vhid_t* vi = new vhid_t{ hid };
168 m_hlist.emplace( m_hlist.end(), vi );
169
170 phid = &( vi->back() );
171 m_uids.emplace( uid, vi );
172 m_ids.emplace( name, vi );
173
174 m_tobjs.emplace( to, std::pair<vhid_t*, size_t>( vi, 0 ) );
175 }
176
177 if ( msgLevel( MSG::DEBUG ) ) { debug() << "regHist_i THistID: " << hid << endmsg; }
178
179 return StatusCode::SUCCESS;
180}
TemplatedAlg< int, std::vector< std::string > > t1
bool m_hasTTrees
Definition THistSvc.h:393
std::mutex histMut_t
Definition THistSvc.h:200

◆ regShared() [1/5]

StatusCode THistSvc::regShared ( const std::string & name,
std::unique_ptr< TEfficiency > eff,
LockedHandle< TEfficiency > & lh )
override

Register shared object of type TEfficiency and return LockedHandle for that object.

Definition at line 506 of file THistSvc.cpp.

507 {
508 lh = regShared_i<TEfficiency>( id, std::move( eff ) );
509 if ( lh ) {
510 return StatusCode::SUCCESS;
511 } else {
512 return StatusCode::FAILURE;
513 }
514}
LockedHandle< T > regShared_i(const std::string &id, std::unique_ptr< T > hist)
Definition THistSvc.icc:279

◆ regShared() [2/5]

StatusCode THistSvc::regShared ( const std::string & name,
std::unique_ptr< TGraph > graph,
LockedHandle< TGraph > & lh )
override

Register shared object of type TGraph and return LockedHandle for that object.

Definition at line 497 of file THistSvc.cpp.

497 {
498 lh = regShared_i<TGraph>( id, std::move( graph ) );
499 if ( lh ) {
500 return StatusCode::SUCCESS;
501 } else {
502 return StatusCode::FAILURE;
503 }
504}

◆ regShared() [3/5]

StatusCode THistSvc::regShared ( const std::string & name,
std::unique_ptr< TH1 > hist,
LockedHandle< TH1 > & lh )
override

Register shared object of type TH1 and return LockedHandle for that object.

Definition at line 470 of file THistSvc.cpp.

470 {
471 lh = regShared_i<TH1>( id, std::move( hist ) );
472 if ( lh ) {
473 return StatusCode::SUCCESS;
474 } else {
475 return StatusCode::FAILURE;
476 }
477}

◆ regShared() [4/5]

StatusCode THistSvc::regShared ( const std::string & name,
std::unique_ptr< TH2 > hist,
LockedHandle< TH2 > & lh )
override

Register shared object of type TH2 and return LockedHandle for that object.

Definition at line 479 of file THistSvc.cpp.

479 {
480 lh = regShared_i<TH2>( id, std::move( hist ) );
481 if ( lh ) {
482 return StatusCode::SUCCESS;
483 } else {
484 return StatusCode::FAILURE;
485 }
486}

◆ regShared() [5/5]

StatusCode THistSvc::regShared ( const std::string & name,
std::unique_ptr< TH3 > hist,
LockedHandle< TH3 > & lh )
override

Register shared object of type TH3 and return LockedHandle for that object.

Definition at line 488 of file THistSvc.cpp.

488 {
489 lh = regShared_i<TH3>( id, std::move( hist ) );
490 if ( lh ) {
491 return StatusCode::SUCCESS;
492 } else {
493 return StatusCode::FAILURE;
494 }
495}

◆ regShared_i()

template<typename T>
LockedHandle< T > THistSvc::regShared_i ( const std::string & id,
std::unique_ptr< T > hist )
private

Definition at line 279 of file THistSvc.icc.

279 {
280 LockedHandle<T> lh( nullptr, nullptr );
281 const THistID* hid = nullptr;
282 if ( findHistID( id, hid ) == 0 ) {
283 T* phist = hist.get();
284 THistID* phid = nullptr;
285 if ( regHist_i( std::move( hist ), id, true, phid ).isSuccess() ) {
286 lh.set( phist, phid->mutex );
287
288 } else {
289 error() << "regSharedHist: unable to register shared hist with id \"" << id << "\"" << endmsg;
290 }
291 } else {
292 if ( !hid->shared ) {
293 error() << "regSharedHist: previously register Hist with id \"" << id << "\" was not marked shared" << endmsg;
294 }
295
296 if ( hist->Compare( hid->obj ) != 0 ) {
297 error() << "regSharedHist: Histogram " << id << " does not compare with " << hid << endmsg;
298 } else {
299 T* phist = dynamic_cast<T*>( hid->obj );
300 if ( phist == 0 ) {
301 error() << "regSharedHist: unable to dcast retrieved shared hist \"" << id << "\" of type "
302 << hid->obj->IsA()->GetName() << " to requested type " << System::typeinfoName( typeid( T ) ) << endmsg;
303 } else {
304 lh.set( phist, hid->mutex );
305 delete hist.release();
306 }
307 }
308 }
309 return lh;
310}

◆ regTree() [1/3]

StatusCode THistSvc::regTree ( const std::string & name)
override

Register a new TTree with a given name.

Definition at line 371 of file THistSvc.cpp.

371 {
372 std::unique_ptr<TTree> tree = nullptr;
373 return regHist_i( std::move( tree ), id, false );
374}

◆ regTree() [2/3]

StatusCode THistSvc::regTree ( const std::string & name,
std::unique_ptr< TTree > tree )
override

Register an existing TTree with a given name and moved unique_ptr.

Definition at line 376 of file THistSvc.cpp.

376 {
377 StatusCode sc = regHist_i( std::move( tree ), id, false );
378 TTree* tr = nullptr;
379 if ( getTree( id, tr ).isSuccess() && sc.isSuccess() ) {
380 if ( m_autoSave != 0 ) { tr->SetAutoSave( m_autoSave ); }
381 tr->SetAutoFlush( m_autoFlush );
382 }
383 return sc;
384}
bool isSuccess() const
Definition StatusCode.h:314
Gaudi::Property< int > m_autoSave
Definition THistSvc.h:369
Gaudi::Property< int > m_autoFlush
Definition THistSvc.h:370
StatusCode getTree(const std::string &name, TTree *&) const override
Return TTree with given name.
Definition THistSvc.cpp:397

◆ regTree() [3/3]

StatusCode THistSvc::regTree ( const std::string & name,
TTree * tree_ptr )
override
Deprecated
{Just kept for compatibiltiy to current ATLAS code. Pleas use std::unique_ptrs instead!} Register a new TTree with a given name and a raw pointer

Definition at line 386 of file THistSvc.cpp.

386 {
387 std::unique_ptr<TTree> tree( tree_ptr );
388 StatusCode sc = regHist_i( std::move( tree ), id, false );
389 TTree* tr = nullptr;
390 if ( getTree( id, tr ).isSuccess() && sc.isSuccess() ) {
391 if ( m_autoSave != 0 ) { tr->SetAutoSave( m_autoSave ); }
392 tr->SetAutoFlush( m_autoFlush );
393 }
394 return sc;
395}

◆ reinitialize()

StatusCode THistSvc::reinitialize ( )
override

Definition at line 187 of file THistSvc.cpp.

187 {
189 warning() << "reinitialize not implemented" << endmsg;
190 return StatusCode::SUCCESS;
191}

◆ removeDoubleSlash()

void THistSvc::removeDoubleSlash ( std::string & id) const
private

Definition at line 1766 of file THistSvc.cpp.

1766 {
1767 while ( id.find( "//" ) != std::string::npos ) { id.replace( id.find( "//" ), 2, "/" ); }
1768}

◆ rootOpenAction()

StatusCode THistSvc::rootOpenAction ( FILEMGR_CALLBACK_ARGS )
private

Definition at line 2068 of file THistSvc.cpp.

2068 {
2069 if ( fa->tech() != Io::ROOT ) {
2070 // This should never happen
2071 return StatusCode::SUCCESS;
2072 }
2073
2074 if ( fa->desc() != "HIST" ) { return StatusCode::SUCCESS; }
2075
2076 p_incSvc->fireIncident( FileIncident( caller, "OpenHistFile", fa->name() ) );
2077
2078 if ( fa->flags().isRead() ) {
2079 p_incSvc->fireIncident( FileIncident( caller, "BeginHistFile", fa->name() ) );
2080 } else if ( fa->flags().isWrite() ) {
2081 p_incSvc->fireIncident( FileIncident( caller, IncidentType::BeginOutputFile, fa->name() ) );
2082 } else {
2083 // for Io::RW
2084 p_incSvc->fireIncident( FileIncident( caller, IncidentType::BeginOutputFile, fa->name() ) );
2085 }
2086
2087 return StatusCode::SUCCESS;
2088}

◆ rootOpenErrAction()

StatusCode THistSvc::rootOpenErrAction ( FILEMGR_CALLBACK_ARGS )
private

Definition at line 2090 of file THistSvc.cpp.

2090 {
2091 if ( fa->tech() != Io::ROOT ) {
2092 // This should never happen
2093 return StatusCode::SUCCESS;
2094 }
2095
2096 if ( fa->desc() != "HIST" ) { return StatusCode::SUCCESS; }
2097
2098 if ( fa->flags().isRead() ) {
2099 p_incSvc->fireIncident( FileIncident( caller, IncidentType::FailInputFile, fa->name() ) );
2100 } else if ( fa->flags().isWrite() ) {
2101 p_incSvc->fireIncident( FileIncident( caller, IncidentType::FailOutputFile, fa->name() ) );
2102 } else {
2103 // for Io::RW
2104 p_incSvc->fireIncident( FileIncident( caller, "FailRWFile", fa->name() ) );
2105 }
2106
2107 return StatusCode::SUCCESS;
2108}

◆ setupInputFile()

void THistSvc::setupInputFile ( )
private

call-back method to handle input stream property

Definition at line 1867 of file THistSvc.cpp.

1867 {
1869 debug() << "Delaying connection of Input Files until Initialize"
1870 << ". now in " << FSMState() << endmsg;
1871
1872 m_delayConnect = true;
1873 } else {
1874 debug() << "Now connecting of Input Files" << endmsg;
1875
1876 StatusCode sc = StatusCode::SUCCESS;
1877
1878 for ( const auto& itr : m_inputfile.value() ) {
1879 if ( m_alreadyConnectedInFiles.end() != m_alreadyConnectedInFiles.find( itr ) ) { continue; }
1880 if ( connect( itr ).isFailure() ) {
1882 } else {
1883 m_alreadyConnectedInFiles.insert( itr );
1884 }
1885 }
1886
1887 if ( !sc.isSuccess() ) { throw GaudiException( "Problem connecting inputfile !!", name(), StatusCode::FAILURE ); }
1888 }
1889}
Gaudi::StateMachine::State FSMState() const override
Definition Service.h:55
StatusCode connect(const std::string &)

◆ setupOutputFile()

void THistSvc::setupOutputFile ( )
private

call-back method to handle output stream property

Definition at line 1891 of file THistSvc.cpp.

1891 {
1893 debug() << "Delaying connection of Output Files until Initialize"
1894 << ". now in " << FSMState() << endmsg;
1895 m_delayConnect = true;
1896 } else {
1897 StatusCode sc = StatusCode::SUCCESS;
1898 for ( const auto& itr : m_outputfile.value() ) {
1899 if ( m_alreadyConnectedOutFiles.end() != m_alreadyConnectedOutFiles.find( itr ) ) { continue; }
1900 if ( connect( itr ).isFailure() ) {
1902 } else {
1903 m_alreadyConnectedOutFiles.insert( itr );
1904 }
1905 }
1906
1907 if ( !sc.isSuccess() ) { throw GaudiException( "Problem connecting outputfile !!", name(), StatusCode::FAILURE ); }
1908 }
1909}

◆ stripDirectoryName()

std::string THistSvc::stripDirectoryName ( std::string & dir) const
private

Definition at line 1750 of file THistSvc.cpp.

1750 {
1751 std::string::size_type i = dir.find( "/" );
1752
1753 if ( i == std::string::npos ) return {};
1754
1755 if ( i == 0 ) {
1756 dir.erase( 0, 1 );
1757 return stripDirectoryName( dir );
1758 }
1759
1760 std::string root = dir.substr( 0, i );
1761 dir.erase( 0, i );
1762
1763 return root;
1764}

◆ updateFiles()

void THistSvc::updateFiles ( )
private

Handle case where TTree grows beyond TTree::fgMaxTreeSize.

Definition at line 1457 of file THistSvc.cpp.

1457 {
1458
1459 if ( !m_hasTTrees ) return;
1460
1461 // If TTrees grow beyond TTree::fgMaxTreeSize, a new file is
1462 // automatically created by root, and the old one closed. We
1463 // need to migrate all the UIDs over to show the correct file
1464 // pointer. This is ugly.
1465
1466 for ( auto uitr = m_uids.begin(); uitr != m_uids.end(); ++uitr ) {
1467 for ( auto& hid : *( uitr->second ) ) {
1468
1469 // Only relevant for TTrees and if not in read mode
1470 if ( hid.type != ObjectType::TTREE || hid.temp || hid.mode == READ || hid.obj == nullptr ) continue;
1471
1472 if ( msgLevel( MSG::VERBOSE ) )
1473 verbose() << " update: " << uitr->first << " " << hid.id << " " << hid.mode << endmsg;
1474
1475 TTree* tr = dynamic_cast<TTree*>( hid.obj );
1476 TFile* oldFile = hid.file;
1477 TFile* newFile = tr->GetCurrentFile();
1478
1479 if ( oldFile != newFile ) {
1480 std::string newFileName = newFile->GetName();
1481 std::string oldFileName, streamName, rem;
1482 TFile* dummy = nullptr;
1483 findStream( hid.id, streamName, rem, dummy );
1484
1485 for ( auto& itr : m_files ) {
1486 if ( itr.second.first == oldFile ) { itr.second.first = newFile; }
1487 }
1488
1489 for ( auto uitr2 = uitr; uitr2 != m_uids.end(); ++uitr2 ) {
1490 for ( auto& hid2 : *( uitr2->second ) ) {
1491 if ( hid2.file == oldFile ) { hid2.file = newFile; }
1492 }
1493 }
1494
1495 auto sitr = std::find_if( std::begin( m_fileStreams ), std::end( m_fileStreams ),
1496 [&]( streamMap::const_reference s ) { return s.second == streamName; } );
1497 if ( sitr != std::end( m_fileStreams ) ) oldFileName = sitr->first;
1498
1499#ifndef NDEBUG
1500 if ( msgLevel( MSG::DEBUG ) ) {
1501 debug() << "migrating uid: " << hid.id << " stream: " << streamName << " oldFile: " << oldFileName
1502 << " newFile: " << newFileName << endmsg;
1503 }
1504#endif
1505
1506 if ( !oldFileName.empty() ) {
1507 auto i = m_fileStreams.lower_bound( oldFileName );
1508 while ( i != std::end( m_fileStreams ) && i->first == oldFileName ) {
1509#ifndef NDEBUG
1510 if ( msgLevel( MSG::DEBUG ) ) {
1511 debug() << "changing filename \"" << i->first << "\" to \"" << newFileName << "\" for stream \""
1512 << i->second << "\"" << endmsg;
1513 }
1514#endif
1515 std::string nm = std::move( i->second );
1516 i = m_fileStreams.erase( i );
1517 m_fileStreams.emplace( newFileName, std::move( nm ) );
1518 }
1519 } else {
1520 error() << "Problems updating fileStreams with new file name" << endmsg;
1521 }
1522 }
1523 }
1524 }
1525}
constexpr double nm

◆ writeObjectsToFile()

StatusCode THistSvc::writeObjectsToFile ( )
private

Definition at line 1527 of file THistSvc.cpp.

1527 {
1528 updateFiles();
1529
1530 std::for_each( m_files.begin(), m_files.end(), []( std::pair<const std::string, std::pair<TFile*, Mode>>& i ) {
1531 auto mode = i.second.second;
1532 auto file = i.second.first;
1533 if ( mode == WRITE || mode == UPDATE || mode == SHARE ) {
1534 file->Write( "", TObject::kOverwrite );
1535 } else if ( mode == APPEND ) {
1536 file->Write( "" );
1537 }
1538 } );
1539
1540 if ( msgLevel( MSG::DEBUG ) ) {
1541 debug() << "THistSvc::writeObjectsToFile()::List of Files connected in ROOT " << endmsg;
1542 TSeqCollection* filelist = gROOT->GetListOfFiles();
1543 for ( int ii = 0; ii < filelist->GetEntries(); ii++ ) {
1544 debug() << "THistSvc::writeObjectsToFile()::List of Files connected in ROOT: \"" << filelist->At( ii )->GetName()
1545 << "\"" << endmsg;
1546 }
1547 }
1548
1549 return StatusCode::SUCCESS;
1550}

Member Data Documentation

◆ m_alreadyConnectedInFiles

std::set<std::string> THistSvc::m_alreadyConnectedInFiles
private

list of already connected files.

This is to keep track of files registered by the setupInputFile callback method

Definition at line 271 of file THistSvc.h.

◆ m_alreadyConnectedOutFiles

std::set<std::string> THistSvc::m_alreadyConnectedOutFiles
private

list of already connected files.

This is to keep track of files registered by the setupOutputFile callback method

Definition at line 275 of file THistSvc.h.

◆ m_autoFlush

Gaudi::Property<int> THistSvc::m_autoFlush { this, "AutoFlush", 0 }
private

Definition at line 370 of file THistSvc.h.

370{ this, "AutoFlush", 0 };

◆ m_autoSave

Gaudi::Property<int> THistSvc::m_autoSave { this, "AutoSave", 0 }
private

Definition at line 369 of file THistSvc.h.

369{ this, "AutoSave", 0 };

◆ m_compressionLevel

Gaudi::Property<int> THistSvc::m_compressionLevel
private
Initial value:
{ this, "CompressionLevel", 1, [this]( auto& ) {
this->warning()
<< "\"CompressionLevel\" Property has been deprecated. "
<< "Set it via the \"CL=\" parameter in the \"Output\" Property"
<< endmsg;
} }

Definition at line 375 of file THistSvc.h.

375 { this, "CompressionLevel", 1, [this]( auto& ) {
376 this->warning()
377 << "\"CompressionLevel\" Property has been deprecated. "
378 << "Set it via the \"CL=\" parameter in the \"Output\" Property"
379 << endmsg;
380 } };

◆ m_curstream

std::string THistSvc::m_curstream
mutableprivate

Definition at line 395 of file THistSvc.h.

◆ m_delayConnect

bool THistSvc::m_delayConnect = false
private

Definition at line 391 of file THistSvc.h.

◆ m_files

std::map<std::string, std::pair<TFile*, Mode> > THistSvc::m_files
private

Definition at line 295 of file THistSvc.h.

◆ m_fileStreams

streamMap THistSvc::m_fileStreams
private

Definition at line 297 of file THistSvc.h.

◆ m_hasTTrees

bool THistSvc::m_hasTTrees = false
private

Definition at line 393 of file THistSvc.h.

◆ m_hlist

hlist_t THistSvc::m_hlist
private

Definition at line 288 of file THistSvc.h.

◆ m_ids

idMap_t THistSvc::m_ids
private

Definition at line 290 of file THistSvc.h.

◆ m_inputfile

Gaudi::Property<std::vector<std::string> > THistSvc::m_inputfile
private
Initial value:
{
this, "Input", {}, &THistSvc::setupInputFile, "", "OrderedSet<std::string>" }

Definition at line 383 of file THistSvc.h.

383 {
384 this, "Input", {}, &THistSvc::setupInputFile, "", "OrderedSet<std::string>" };

◆ m_maxFileSize

Gaudi::Property<int> THistSvc::m_maxFileSize
private
Initial value:
{ this, "MaxFileSize", 10240,
"maximum file size in MB. if exceeded,"
" will cause an abort. -1 to never check." }

Definition at line 372 of file THistSvc.h.

372 { this, "MaxFileSize", 10240,
373 "maximum file size in MB. if exceeded,"
374 " will cause an abort. -1 to never check." };

◆ m_okToConnect

bool THistSvc::m_okToConnect = false
private

Definition at line 392 of file THistSvc.h.

◆ m_outputfile

Gaudi::Property<std::vector<std::string> > THistSvc::m_outputfile
private
Initial value:
{
this, "Output", {}, &THistSvc::setupOutputFile, "", "OrderedSet<std::string>" }

Definition at line 381 of file THistSvc.h.

381 {
382 this, "Output", {}, &THistSvc::setupOutputFile, "", "OrderedSet<std::string>" };

◆ m_print

Gaudi::Property<bool> THistSvc::m_print { this, "PrintAll", false }
private

Definition at line 371 of file THistSvc.h.

371{ this, "PrintAll", false };

◆ m_Rstream

std::vector<std::string> THistSvc::m_Rstream
private

Definition at line 267 of file THistSvc.h.

◆ m_sharedFiles

std::map<std::string, std::string> THistSvc::m_sharedFiles
private

Definition at line 300 of file THistSvc.h.

◆ m_svcMut

THistSvcMutex_t THistSvc::m_svcMut
mutableprivate

Definition at line 397 of file THistSvc.h.

◆ m_tobjs

objMap_t THistSvc::m_tobjs
private

Definition at line 293 of file THistSvc.h.

◆ m_uids

uidMap_t THistSvc::m_uids
private

Definition at line 289 of file THistSvc.h.

◆ m_Wstream

std::vector<std::string> THistSvc::m_Wstream
private

Definition at line 267 of file THistSvc.h.

◆ p_fileMgr

ServiceHandle<IFileMgr> THistSvc::p_fileMgr
private

Definition at line 389 of file THistSvc.h.

◆ p_incSvc

ServiceHandle<IIncidentSvc> THistSvc::p_incSvc
private

Definition at line 388 of file THistSvc.h.


The documentation for this class was generated from the following files: