The Gaudi Framework  master (ba5b4fb7)
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 34 of file THistSvc.h.

Member Typedef Documentation

◆ histMut_t

typedef std::mutex THistSvc::histMut_t
private

Definition at line 194 of file THistSvc.h.

◆ hlist_t

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

Definition at line 279 of file THistSvc.h.

◆ idMap_t

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

Definition at line 283 of file THistSvc.h.

◆ objMap_t

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

Definition at line 284 of file THistSvc.h.

◆ streamMap

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

Definition at line 294 of file THistSvc.h.

◆ THistSvcMutex_t

typedef std::recursive_mutex THistSvc::THistSvcMutex_t
private

Definition at line 193 of file THistSvc.h.

◆ uidMap_t

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

Definition at line 281 of file THistSvc.h.

◆ vhid_t

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

Definition at line 277 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 210 of file THistSvc.h.

◆ ObjectType

enum class THistSvc::ObjectType
strongprivate

Possible TObject types.

Enumerator
UNKNOWN 
TH1 
TTREE 
TGRAPH 
TEFFICIENCY 

Definition at line 213 of file THistSvc.h.

213{ 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 66 of file THistSvc.cpp.

67 : 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:386
ServiceHandle< IFileMgr > p_fileMgr
Definition THistSvc.h:387

Member Function Documentation

◆ changeDir()

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

Definition at line 1719 of file THistSvc.cpp.

1719 {
1720 std::string uid = hid.id;
1721 TFile* file = hid.file;
1722 std::string stream, fdir, bdir, dir, id;
1723
1724 if ( file ) {
1725 file->cd( "/" );
1726 } else {
1727 gROOT->cd();
1728 }
1729
1730 fdir = uid;
1731 bdir = stripDirectoryName( fdir );
1732
1733 while ( ( dir = stripDirectoryName( fdir ) ) != "" ) {
1734 if ( !gDirectory->GetKey( dir.c_str() ) ) { gDirectory->mkdir( dir.c_str() ); }
1735 gDirectory->cd( dir.c_str() );
1736 }
1737
1738 return gDirectory;
1739}
std::string stripDirectoryName(std::string &dir) const
stream
Definition Write.py:32
std::string id
Definition THistSvc.h:233

◆ charToMode()

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

Convert a char to a Mode enum.

Definition at line 216 of file THistSvc.h.

216 {
217 switch ( typ ) {
218 case 'O':
219 return READ;
220 case 'A':
221 return APPEND;
222 case 'R':
223 return UPDATE;
224 case 'S':
225 return SHARE;
226 default:
227 return INVALID;
228 }
229 }

◆ connect()

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

Definition at line 1543 of file THistSvc.cpp.

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

1902 {
1903 if ( msgLevel( MSG::DEBUG ) ) {
1904 debug() << "copyFileLayout() to destination path: " << destination->GetPath() << endmsg;
1905 }
1906
1907 // strip out URLs
1908 TString path( (char*)strstr( destination->GetPath(), ":" ) );
1909 path.Remove( 0, 2 );
1910
1911 source->cd( path );
1912 TDirectory* current_source_dir = gDirectory;
1913
1914 // loop over all keys in this directory
1915 TList* key_list = current_source_dir->GetListOfKeys();
1916 int n = key_list->GetEntries();
1917 for ( int j = 0; j < n; ++j ) {
1918 TKey* k = (TKey*)key_list->At( j );
1919 const std::string source_pathname = current_source_dir->GetPath() + std::string( "/" ) + k->GetName();
1920 TObject* o = source->Get( source_pathname.c_str() );
1921
1922 if ( o && o->IsA()->InheritsFrom( "TDirectory" ) ) {
1923 if ( msgLevel( MSG::VERBOSE ) ) { verbose() << " subdir [" << o->GetName() << "]..." << endmsg; }
1924 destination->cd();
1925 // Create directory if it does not exist yet
1926 TDirectory* destination_dir = destination->mkdir( o->GetName(), o->GetTitle() );
1927 if ( destination_dir == nullptr ) destination_dir = destination->GetDirectory( o->GetName() );
1928 copyFileLayout( destination_dir, source );
1929 }
1930 } // loop over keys
1931 return;
1932}
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 552 of file THistSvc.cpp.

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

◆ deReg() [2/2]

StatusCode THistSvc::deReg ( TObject * obj)
override

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

Definition at line 578 of file THistSvc.cpp.

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

◆ dump()

void THistSvc::dump ( ) const
private

Definition at line 1979 of file THistSvc.cpp.

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

◆ 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 658 of file THistSvc.cpp.

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

◆ existsEfficiency()

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

Check if TEfficiency with given name is managed by THistSvcMT.

Definition at line 662 of file THistSvc.cpp.

662 {
663 return ( getHist_i<TEfficiency>( name, 0, true ) != nullptr );
664}
T * getHist_i(const std::string &name, const size_t &ind=0, bool quiet=false) const
Definition THistSvc.h:562

◆ existsGraph()

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

Check if graph with given name is managed by THistSvcMT.

Definition at line 666 of file THistSvc.cpp.

666 {
667 return ( getHist_i<TGraph>( name, 0, true ) != nullptr );
668}

◆ existsHist()

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

Check if histogram with given name is managed by THistSvcMT.

Definition at line 660 of file THistSvc.cpp.

660{ 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 670 of file THistSvc.cpp.

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

◆ finalize()

StatusCode THistSvc::finalize ( )
override

Definition at line 180 of file THistSvc.cpp.

180 {
182
183 if ( msgLevel( MSG::DEBUG ) ) {
184 dump();
185 debug() << "THistSvc::finalize" << endmsg;
186 }
187
188#ifndef NDEBUG
189 if ( msgLevel( MSG::DEBUG ) ) {
190 const std::map<uidMap_t::key_type, uidMap_t::mapped_type> sorted_uids{ begin( m_uids ), end( m_uids ) };
191 for ( const auto& itr : sorted_uids ) {
192 THistID& thid = itr.second->at( 0 );
193 TObject* tobj = thid.obj;
194
195 std::string dirname( "none" );
196 if ( tobj && thid.type == ObjectType::TTREE ) {
197 TTree* tree = dynamic_cast<TTree*>( tobj );
198 if ( tree->GetDirectory() != 0 ) { dirname = tree->GetDirectory()->GetPath(); }
199 } else if ( tobj && thid.type == ObjectType::TGRAPH ) {
200 if ( !thid.temp ) {
201 dirname = thid.file->GetPath();
202 std::string id2( thid.id );
203 id2.erase( 0, id2.find( "/", 1 ) );
204 id2.erase( id2.rfind( "/" ), id2.length() );
205 if ( id2.starts_with( "/" ) ) { id2.erase( 0, 1 ); }
206 dirname += id2;
207 } else {
208 dirname = "/tmp";
209 }
210 } else if ( tobj && thid.type == ObjectType::TH1 ) {
211 TH1* th = dynamic_cast<TH1*>( tobj );
212 if ( th == nullptr ) {
213 error() << "Couldn't dcast: " << itr.first << endmsg;
214 } else {
215 if ( th->GetDirectory() != 0 ) { dirname = th->GetDirectory()->GetPath(); }
216 }
217 } else if ( !tobj ) {
218 warning() << itr.first << " has NULL TObject ptr" << endmsg;
219 }
220 debug() << "finalize: " << thid << endmsg;
221 }
222 }
223#endif
224
225 if ( writeObjectsToFile().isFailure() ) { error() << "problems writing histograms" << endmsg; }
226
227 if ( m_print ) { info() << "Listing contents of ROOT files: " << endmsg; }
228 std::vector<TFile*> deleted_files;
229 for ( auto& itr : m_files ) {
230 if ( std::find( deleted_files.begin(), deleted_files.end(), itr.second.first ) == deleted_files.end() ) {
231 deleted_files.push_back( itr.second.first );
232
233#ifndef NDEBUG
234 if ( msgLevel( MSG::DEBUG ) ) {
235 debug() << "finalizing stream/file " << itr.first << ":" << itr.second.first->GetName() << endmsg;
236 }
237#endif
238 } else {
239#ifndef NDEBUG
240 if ( msgLevel( MSG::DEBUG ) ) { debug() << "already finalized stream " << itr.first << endmsg; }
241#endif
242 continue;
243 }
244
245 if ( m_print && msgLevel( MSG::INFO ) ) {
246 info() << "==> File: " << itr.second.first->GetName() << " stream: " << itr.first << endmsg;
247
248 itr.second.first->Print( "base" );
249 }
250
251 std::string tmpfn = itr.second.first->GetName();
252
253 p_fileMgr->close( itr.second.first, name() );
254
255 if ( itr.second.second == SHARE ) {
256 // Merge File
257 void* vfile = nullptr;
258 int returncode =
259 p_fileMgr->open( Io::ROOT, name(), m_sharedFiles[itr.first], Io::WRITE | Io::APPEND, vfile, "HIST" );
260
261 if ( returncode ) {
262 error() << "unable to open Final Output File: \"" << m_sharedFiles[itr.first] << "\" for merging" << endmsg;
263 return StatusCode::FAILURE;
264 }
265
266 TFile* outputfile = (TFile*)vfile;
267 p_incSvc->fireIncident( FileIncident( name(), IncidentType::WroteToOutputFile, m_sharedFiles[itr.first] ) );
268
269 if ( msgLevel( MSG::DEBUG ) ) { debug() << "THistSvc::writeObjectsToFile()::Merging Rootfile " << endmsg; }
270
271 vfile = nullptr;
272 returncode = p_fileMgr->open( Io::ROOT, name(), tmpfn, Io::READ, vfile, "HIST" );
273
274 if ( returncode ) {
275 error() << "unable to open temporary file: \"" << tmpfn << endmsg;
276 return StatusCode::FAILURE;
277 }
278
279 TFile* inputfile = (TFile*)vfile;
280
281 outputfile->SetCompressionLevel( inputfile->GetCompressionLevel() );
282
283 MergeRootFile( outputfile, inputfile );
284
285 outputfile->Write();
286 p_fileMgr->close( outputfile, name() );
287 p_fileMgr->close( inputfile, name() );
288
289 if ( msgLevel( MSG::DEBUG ) ) { debug() << "Trying to remove temporary file \"" << tmpfn << "\"" << endmsg; }
290
291 std::remove( tmpfn.c_str() );
292 }
293 delete itr.second.first;
294 }
295
296 m_files.clear();
297 m_sharedFiles.clear();
298 m_fileStreams.clear();
299 m_hlist.clear(); // vhid* is deleted in m_tobjs
300 m_uids.clear(); // vhid* is deleted in m_tobjs
301 m_ids.clear(); // vhid* is deleted in m_tobjs
302
303 for ( auto& obj : m_tobjs ) {
304 // Delete temporary TObjects (not owned by any TFile)
305 // Non-temporary objects are owned by their TFile and already
306 // deleted when the file was closed above
307 THistID& hid = obj.second.first->at( obj.second.second );
308 if ( hid.temp ) { delete obj.first; }
309 // only delete vector if this object is index 0
310 if ( obj.second.second == 0 ) {
311 delete obj.second.first; // delete vhid*
312 }
313 }
314 m_tobjs.clear();
315
316 return Service::finalize();
317}
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:197
void MergeRootFile(TDirectory *, TDirectory *)
void dump() const
StatusCode writeObjectsToFile()
Gaudi::Property< bool > m_print
Definition THistSvc.h:369
THistSvcMutex_t m_svcMut
Definition THistSvc.h:395
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:234

◆ findHistID()

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

Definition at line 1934 of file THistSvc.cpp.

1934 {
1936
1937 std::string idr( id );
1938 removeDoubleSlash( idr );
1939
1940 hid = 0;
1941
1942 if ( idr.starts_with( "/" ) ) {
1943 // fully specified name, starts with "/"
1944 auto itr = m_uids.find( idr );
1945 if ( itr == m_uids.end() ) {
1946 // no matches found
1947 return 0;
1948 } else {
1949 // one or more matches found (clones).
1950 if ( index >= itr->second->size() ) {
1951 error() << "no index " << index << " found for Hist " << idr << endmsg;
1952 return 0;
1953 }
1954 hid = &( itr->second->at( index ) );
1955 return 1;
1956 }
1957 } else {
1958 // name not fully specified.
1959 auto mitr = m_ids.equal_range( idr );
1960 if ( mitr.first == mitr.second ) {
1961 // not found
1962 return 0;
1963 } else if ( distance( mitr.first, mitr.second ) == 1 ) {
1964 // one found
1965 if ( index >= mitr.first->second->size() ) {
1966 error() << "no index " << index << " found for Hist " << idr << endmsg;
1967 return 0;
1968 }
1969 hid = &( mitr.first->second->at( 0 ) );
1970 return 1;
1971 } else {
1972 // multiple matches
1973 hid = &( mitr.first->second->at( 0 ) );
1974 return distance( mitr.first, mitr.second );
1975 }
1976 }
1977}
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 1808 of file THistSvc.cpp.

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

◆ getEfficiencies()

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

Definition at line 696 of file THistSvc.cpp.

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

◆ getEfficiency()

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

Return TEfficiency with given name.

Definition at line 452 of file THistSvc.cpp.

452 {
453 eff = getHist_i<TEfficiency>( id );
454 if ( eff != nullptr ) {
455 return StatusCode::SUCCESS;
456 } else {
457 return StatusCode::FAILURE;
458 }
459}

◆ getGraph()

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

Return TGraph with given name.

Definition at line 429 of file THistSvc.cpp.

429 {
430 graph = getHist_i<TGraph>( id );
431 if ( graph != nullptr ) {
432 return StatusCode::SUCCESS;
433 } else {
434 return StatusCode::FAILURE;
435 }
436}

◆ getGraphs()

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

Definition at line 688 of file THistSvc.cpp.

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

◆ 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 335 of file THistSvc.cpp.

335 {
336 hist = getHist_i<TH1>( id, ind );
337 if ( hist != nullptr ) {
338 return StatusCode::SUCCESS;
339 } else {
340 return StatusCode::FAILURE;
341 }
342}

◆ 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 344 of file THistSvc.cpp.

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

◆ 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 353 of file THistSvc.cpp.

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

◆ 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 562 of file THistSvc.h.

562 {
563 // id starts with "/": unique
564
566
567 T* hist = nullptr;
568 const THistID* hid = nullptr;
569 size_t num = findHistID( id, hid, ind );
570 if ( num == 0 ) {
571 // no matches found
572 if ( !quiet ) { error() << "could not locate Hist with id \"" << id << "\"" << endmsg; }
573 return nullptr;
574 } else if ( num > 1 ) {
575 if ( !quiet ) {
576 // return failure if trying to GET a single hist
577 error() << "Multiple matches with id \"" << id << "\"."
578 << " Further specifications required." << endmsg;
579 return nullptr;
580 } else {
581 info() << "Found multiple matches with id \"" << id << "\"" << endmsg;
582 // return first match if just INQUIRING (i.e. != nullptr)
583 hist = dynamic_cast<T*>( hid->obj );
584 if ( hist == nullptr ) {
585 error() << "dcast failed, Hist id: \"" << id << "\"" << endmsg;
586 return nullptr;
587 }
588 }
589 } else {
590 hist = dynamic_cast<T*>( hid->obj );
591 if ( hist == nullptr ) {
592 error() << "dcast failed, Hist id: \"" << id << "\"" << endmsg;
593 return nullptr;
594 }
595 if ( msgLevel( MSG::VERBOSE ) ) {
596 verbose() << "found unique Hist title: \"" << hist->GetTitle() << "\" id: \"" << id << "\"" << endmsg;
597 }
598 }
599
600 return hist;
601}
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 672 of file THistSvc.cpp.

672 {
673 std::vector<std::string> names;
674 names.reserve( m_uids.size() );
675 transform_if( std::begin( m_uids ), std::end( m_uids ), std::back_inserter( names ), select1st,
676 []( uidMap_t::const_reference i ) { return i.second->at( 0 ).type == ObjectType::TH1; } );
677 return names;
678}

◆ 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 543 of file THistSvc.cpp.

543 {
545 if ( lh ) {
546 return StatusCode::SUCCESS;
547 } else {
548 return StatusCode::FAILURE;
549 }
550}
LockedHandle< T > getShared_i(const std::string &name) const
Definition THistSvc.h:692

◆ 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 534 of file THistSvc.cpp.

534 {
536 if ( lh ) {
537 return StatusCode::SUCCESS;
538 } else {
539 return StatusCode::FAILURE;
540 }
541}

◆ 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 507 of file THistSvc.cpp.

507 {
508 lh = getShared_i<TH1>( name );
509 if ( lh ) {
510 return StatusCode::SUCCESS;
511 } else {
512 return StatusCode::FAILURE;
513 }
514}

◆ 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 516 of file THistSvc.cpp.

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

◆ 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 525 of file THistSvc.cpp.

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

◆ getShared_i()

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

Definition at line 692 of file THistSvc.h.

692 {
694
695 const THistID* hid = nullptr;
696 size_t i = findHistID( name, hid );
697
698 LockedHandle<T> hist( nullptr, nullptr );
699
700 if ( i == 1 ) {
701 if ( !hid->shared ) {
702 error() << "getSharedHist: found Hist with id \"" << name << "\", but it's not marked as shared" << endmsg;
703 return hist;
704 }
705 T* h1 = dynamic_cast<T*>( hid->obj );
706 hist = LockedHandle<T>( h1, hid->mutex.get() );
707
708 if ( msgLevel( MSG::DEBUG ) ) { debug() << "getSharedHist: found THistID: " << *hid << endmsg; }
709 } else if ( i == 0 ) {
710 error() << "no histograms matching id \"" << name << "\" found" << endmsg;
711 } else {
712 info() << "multiple matches for id \"" << name << "\" found [" << i << "], probably from different streams"
713 << endmsg;
714 }
715 return hist;
716}

◆ getTEfficiencies() [1/4]

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

Definition at line 1130 of file THistSvc.cpp.

1130 {
1131
1133
1134 gErrorIgnoreLevel = kBreak;
1135
1136 StatusCode sc;
1137
1138 std::string stream, rem, r2;
1139 parseString( dir, stream, rem );
1140
1141 auto itr = m_files.find( stream );
1142 if ( itr != m_files.end() ) {
1143 r2 = itr->second.first->GetName();
1144 r2 += ":/";
1145 r2 += rem;
1146
1147 if ( msgLevel( MSG::DEBUG ) ) {
1148 debug() << "getTEfficiencies: \"" << dir << "\" looks like a stream name."
1149 << " associated TFile: \"" << itr->second.first->GetName() << "\"" << endmsg;
1150 }
1151
1152 if ( gDirectory->cd( r2.c_str() ) ) {
1154 sc = getTEfficiencies( gDirectory, tl, rcs );
1155 m_curstream = "";
1156 return sc;
1157 } else {
1158 if ( msgLevel( MSG::DEBUG ) ) { debug() << "getTEfficiencies: no such TDirectory \"" << r2 << "\"" << endmsg; }
1159 }
1160
1161 } else {
1162 if ( msgLevel( MSG::DEBUG ) ) { debug() << "getTEfficiencies: stream \"" << stream << "\" not found" << endmsg; }
1163 }
1164
1165 if ( !gDirectory->cd( dir.c_str() ) ) {
1166 error() << "getTEfficiencies: No such TDirectory/stream \"" << dir << "\"" << endmsg;
1168 } else {
1169 sc = getTHists( gDirectory, tl, rcs );
1170 }
1171
1172 return sc;
1173}
std::string m_curstream
Definition THistSvc.h:393
StatusCode getTHists(TDirectory *td, TList &, bool recurse=false) const override
Definition THistSvc.cpp:704
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 1238 of file THistSvc.cpp.

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

◆ getTEfficiencies() [3/4]

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

Definition at line 1084 of file THistSvc.cpp.

1084 {
1086
1087 gErrorIgnoreLevel = kBreak;
1088
1089 if ( !td->cd() ) {
1090 error() << "getTEfficiencies: No such TDirectory \"" << td->GetPath() << "\"" << endmsg;
1091 return StatusCode::FAILURE;
1092 }
1093
1094 if ( msgLevel( MSG::DEBUG ) ) {
1095 debug() << "getTEfficiencies: \"" << td->GetPath() << "\": found " << td->GetListOfKeys()->GetSize() << " keys"
1096 << endmsg;
1097 }
1098
1099 TIter nextkey( td->GetListOfKeys() );
1100 while ( TKey* key = (TKey*)nextkey() ) {
1101 auto& log = debug();
1102 if ( msgLevel( MSG::DEBUG ) ) log << " key: " << key->GetName();
1103 TObject* obj = key->ReadObj();
1104 if ( obj != 0 && obj->IsA()->InheritsFrom( "TDirectory" ) ) {
1105 if ( msgLevel( MSG::DEBUG ) ) log << " (" << obj->IsA()->GetName() << ")";
1106 } else if ( obj != 0 && obj->IsA()->InheritsFrom( "TEfficiency" ) ) {
1107 if ( msgLevel( MSG::DEBUG ) ) log << " (" << obj->IsA()->GetName() << ")";
1108 tl.Add( obj );
1109 } else if ( obj != 0 ) {
1110 if ( msgLevel( MSG::DEBUG ) ) log << " [" << obj->IsA()->GetName() << "]";
1111 }
1112 if ( msgLevel( MSG::DEBUG ) ) log << endmsg;
1113 }
1114
1115 // operate recursively
1116 if ( rcs ) {
1117 nextkey = td->GetListOfKeys();
1118 while ( TKey* key = (TKey*)nextkey() ) {
1119 TObject* obj = key->ReadObj();
1120 if ( obj && obj->IsA()->InheritsFrom( "TDirectory" ) ) {
1121 TDirectory* tt = dynamic_cast<TDirectory*>( obj );
1122 getTHists( tt, tl, rcs ).ignore( /* AUTOMATICALLY ADDED FOR gaudi/Gaudi!763 */ );
1123 }
1124 }
1125 }
1126
1127 return StatusCode::SUCCESS;
1128}
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 1175 of file THistSvc.cpp.

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

◆ getTHists() [1/4]

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

Definition at line 749 of file THistSvc.cpp.

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

◆ getTHists() [2/4]

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

Definition at line 856 of file THistSvc.cpp.

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

◆ getTHists() [3/4]

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

Definition at line 704 of file THistSvc.cpp.

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

◆ getTHists() [4/4]

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

Definition at line 794 of file THistSvc.cpp.

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

◆ getTree()

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

Return TTree with given name.

Definition at line 388 of file THistSvc.cpp.

388 {
389 tree = getHist_i<TTree>( id );
390 if ( tree != nullptr ) {
391 return StatusCode::SUCCESS;
392 } else {
393 return StatusCode::FAILURE;
394 }
395}

◆ getTrees()

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

Definition at line 680 of file THistSvc.cpp.

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

◆ getTTrees() [1/4]

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

Definition at line 948 of file THistSvc.cpp.

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

◆ getTTrees() [2/4]

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

Definition at line 1046 of file THistSvc.cpp.

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

◆ getTTrees() [3/4]

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

Definition at line 903 of file THistSvc.cpp.

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

◆ getTTrees() [4/4]

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

Definition at line 984 of file THistSvc.cpp.

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

◆ handle()

void THistSvc::handle ( const Incident & )
override

Definition at line 1287 of file THistSvc.cpp.

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

◆ initialize()

StatusCode THistSvc::initialize ( )
override

Definition at line 69 of file THistSvc.cpp.

69 {
71
72 StatusCode status = Service::initialize();
73
74 if ( status.isFailure() ) {
75 error() << "initializing service" << endmsg;
76 return status;
77 }
78
79 StatusCode st( StatusCode::SUCCESS );
80
81 try {
83 } catch ( GaudiException& err ) {
84 error() << "Caught: " << err << endmsg;
86 }
87
88 try {
90 } catch ( GaudiException& err ) {
91 error() << "Caught: " << err << endmsg;
93 }
94
95 // Protect against multiple instances of TROOT
96 if ( !gROOT ) {
97 static TROOT root( "root", "ROOT I/O" );
98 // gDebug = 99;
99 } else {
100 if ( msgLevel( MSG::VERBOSE ) ) { verbose() << "ROOT already initialized, debug = " << gDebug << endmsg; }
101 }
102
103 if ( p_incSvc.retrieve().isFailure() ) {
104 error() << "unable to get the IncidentSvc" << endmsg;
106 } else {
107 p_incSvc->addListener( this, "EndEvent", 100, true );
108 }
109
110 if ( p_fileMgr.retrieve().isFailure() ) {
111 error() << "unable to get the FileMgr" << endmsg;
113 } else {
114 if ( msgLevel( MSG::DEBUG ) ) { debug() << "got the FileMgr" << endmsg; }
115 }
116
117 // Register open/close callback actions
118 using namespace std::placeholders;
119 auto boa = [this]( const Io::FileAttr* fa, const std::string& caller ) { return this->rootOpenAction( fa, caller ); };
120 if ( p_fileMgr->regAction( boa, Io::OPEN, Io::ROOT ).isFailure() ) {
121 error() << "unable to register ROOT file open action with FileMgr" << endmsg;
122 }
123 auto bea = [this]( const Io::FileAttr* fa, const std::string& caller ) {
124 return this->rootOpenErrAction( fa, caller );
125 };
126 if ( p_fileMgr->regAction( bea, Io::OPEN_ERR, Io::ROOT ).isFailure() ) {
127 error() << "unable to register ROOT file open Error action with FileMgr" << endmsg;
128 }
129
130 m_okToConnect = true;
131 if ( m_delayConnect ) {
132 if ( !m_inputfile.value().empty() ) setupInputFile();
133 if ( !m_outputfile.value().empty() ) setupOutputFile();
134 m_delayConnect = false;
135 }
138
139 auto iomgr = service<IIoComponentMgr>( "IoComponentMgr" );
140 if ( !iomgr ) {
141 error() << "unable to get the IoComponentMgr" << endmsg;
143 } else {
144 if ( !iomgr->io_register( this ).isSuccess() ) {
145 error() << "could not register with the I/O component manager !" << endmsg;
147 } else {
148 bool all_good = true;
149 // register input/output files...
150 for ( const auto& reg : m_files ) {
151 const std::string& fname = reg.second.first->GetName();
152 const IIoComponentMgr::IoMode::Type iomode =
154 if ( !iomgr->io_register( this, iomode, fname ).isSuccess() ) {
155 warning() << "could not register file [" << fname << "] with the I/O component manager..." << endmsg;
156 all_good = false;
157 } else {
158 info() << "registered file [" << fname << "]... [ok]" << endmsg;
159 }
160 }
161 if ( !all_good ) {
162 error() << "problem while registering input/output files with "
163 << "the I/O component manager !" << endmsg;
165 }
166 }
167 }
168
169 if ( st.isFailure() ) { fatal() << "Unable to initialize THistSvc" << endmsg; }
170
171 return st;
172}
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:381
bool m_delayConnect
Definition THistSvc.h:389
bool m_okToConnect
Definition THistSvc.h:390
Gaudi::Property< std::vector< std::string > > m_outputfile
Definition THistSvc.h:379
StatusCode rootOpenAction(FILEMGR_CALLBACK_ARGS)
std::set< std::string > m_alreadyConnectedOutFiles
list of already connected files.
Definition THistSvc.h:273
std::set< std::string > m_alreadyConnectedInFiles
list of already connected files.
Definition THistSvc.h:269
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 1325 of file THistSvc.cpp.

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

638 {
639 uidMap_t::iterator itr = m_uids.find( name );
640 if ( itr == m_uids.end() ) {
641 error() << "merge: id \"" << name << "\" not found" << endmsg;
642 return StatusCode::FAILURE;
643 }
644
645 return merge( itr->second );
646}
StatusCode merge(const std::string &id) override
Merge all clones for object with a given id.
Definition THistSvc.cpp:638

◆ merge() [2/4]

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

Helper method to merge THistID objects.

Definition at line 2015 of file THistSvc.cpp.

2015{ return merge( hid.id ); }

◆ merge() [3/4]

StatusCode THistSvc::merge ( TObject * obj)
override

Merge all clones for given TObject*.

Definition at line 648 of file THistSvc.cpp.

648 {
649 objMap_t::iterator itr = m_tobjs.find( obj );
650 if ( itr != m_tobjs.end() ) {
651 return merge( itr->second.first );
652 } else {
653 error() << "merge: unknown object " << obj << endmsg;
654 return StatusCode::FAILURE;
655 }
656}

◆ merge() [4/4]

StatusCode THistSvc::merge ( vhid_t * vh)
private

Helper method to merge vectors of THistID.

Definition at line 2017 of file THistSvc.cpp.

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

◆ MergeRootFile()

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

Definition at line 1761 of file THistSvc.cpp.

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

◆ parseString()

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

Definition at line 1844 of file THistSvc.cpp.

1844 {
1845 auto pos = id.find( "/" );
1846
1847 if ( pos == std::string::npos ) {
1848 root.clear();
1849 rem = id;
1850 } else if ( pos == 0 ) {
1851 parseString( id.substr( 1 ), root, rem );
1852 } else {
1853 root = id.substr( 0, pos );
1854 rem = id.substr( pos + 1 );
1855 }
1856}

◆ readHist()

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

Definition at line 1442 of file THistSvc.cpp.

1442 {
1443 return dynamic_cast<T*>( readHist_i<T>( id ) );
1444}
T * readHist_i(const std::string &name) const
Definition THistSvc.h:604

◆ readHist_i()

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

Definition at line 604 of file THistSvc.h.

604 {
606
607 std::string idr( id );
608 removeDoubleSlash( idr );
609
610 std::string stream, rem, dir, fdir, bdir, fdir2;
611 TFile* file = nullptr;
612
613 if ( !findStream( idr, stream, rem, file ) ) { return nullptr; }
614
615 if ( !file ) {
616 error() << "no associated file found" << endmsg;
617 return nullptr;
618 }
619
620 file->cd( "/" );
621
622 fdir = idr;
623 bdir = stripDirectoryName( fdir );
624 fdir2 = fdir;
625 while ( ( dir = stripDirectoryName( fdir ) ) != "" ) {
626 if ( !gDirectory->GetKey( dir.c_str() ) ) {
627 error() << "Directory \"" << fdir2 << "\" doesnt exist in " << file->GetName() << endmsg;
628 return nullptr;
629 }
630 gDirectory->cd( dir.c_str() );
631 }
632
633 TObject* to = nullptr;
634 gDirectory->GetObject( fdir.c_str(), to );
635
636 if ( !to ) {
637 error() << "Could not get obj \"" << fdir << "\" in " << gDirectory->GetPath() << endmsg;
638 return nullptr;
639 }
640
641 T* hist = dynamic_cast<T*>( to );
642 if ( hist == nullptr ) {
643 error() << "Could not convert \"" << idr << "\" to a " << System::typeinfoName( typeid( *hist ) ) << " as is a "
644 << to->IsA()->GetName() << endmsg;
645 return nullptr;
646 }
647
648 if ( msgLevel( MSG::DEBUG ) ) {
649 debug() << "Read in " << hist->IsA()->GetName() << " \"" << hist->GetName() << "\" from file " << file->GetName()
650 << endmsg;
651 hist->Print();
652 }
653
654 return hist;
655}
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 1446 of file THistSvc.cpp.

1446{ 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 438 of file THistSvc.cpp.

438 {
439 std::unique_ptr<TEfficiency> eff = nullptr;
440 return regHist_i( std::move( eff ), id, false );
441}
StatusCode regHist_i(std::unique_ptr< T > hist, const std::string &name, bool shared)
Definition THistSvc.h:399

◆ 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 443 of file THistSvc.cpp.

443 {
444 return regHist_i( std::move( eff ), id, false );
445}

◆ 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 447 of file THistSvc.cpp.

447 {
448 std::unique_ptr<TEfficiency> eff( eff_ptr );
449 return regHist_i( std::move( eff ), id, false );
450}

◆ regGraph() [1/3]

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

Register a new TGraph with a given name.

Definition at line 397 of file THistSvc.cpp.

397 {
398 std::unique_ptr<TGraph> graph = std::make_unique<TGraph>();
399 return regHist_i( std::move( graph ), id, false );
400}

◆ 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 402 of file THistSvc.cpp.

402 {
403 if ( strcmp( graph->GetName(), "Graph" ) == 0 ) {
404 std::string id2( id );
405 std::string::size_type i = id2.rfind( "/" );
406 if ( i != std::string::npos ) { id2.erase( 0, i + 1 ); }
407
408 info() << "setting name of TGraph id: \"" << id << "\" to \"" << id2 << "\" since it is unset" << endmsg;
409 graph->SetName( id2.c_str() );
410 }
411
412 return regHist_i( std::move( graph ), id, false );
413}

◆ 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 415 of file THistSvc.cpp.

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

◆ regHist() [1/3]

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

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

Definition at line 321 of file THistSvc.cpp.

321 {
322 std::unique_ptr<TH1> hist = nullptr;
323 return regHist_i( std::move( hist ), id, false );
324}

◆ 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 326 of file THistSvc.cpp.

326 {
327 return regHist_i( std::move( hist ), id, false );
328}

◆ 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 330 of file THistSvc.cpp.

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

◆ 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 399 of file THistSvc.h.

399 {
400 THistID* hid = nullptr;
401 return regHist_i( std::move( hist ), id, shared, hid );
402}

◆ 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 405 of file THistSvc.h.

405 {
407 phid = nullptr;
408
409 // It is sad that we lose propper memory management here
410 T* hist = nullptr;
411 if ( hist_unique.get() != nullptr ) { hist = hist_unique.release(); }
412 if ( msgLevel( MSG::DEBUG ) ) {
413 debug() << "regHist_i obj: " << hist << " id: " << id << " s: " << shared << endmsg;
414 }
415
416 std::string idr( id );
417 removeDoubleSlash( idr );
418
419 if ( idr.find( "/" ) == idr.length() ) {
420 error() << "Badly formed identifier \"" << idr << "\": "
421 << "Must not end with a /" << endmsg;
422 delete hist;
423 return StatusCode::FAILURE;
424 }
425
426 TFile* f = nullptr;
427 std::string stream, name;
428 if ( !findStream( idr, stream, name, f ) ) {
429 error() << "Could not register id: \"" << idr << "\"" << endmsg;
430 delete hist;
431 return StatusCode::FAILURE;
432 }
433
434 std::string uid = "/" + stream + "/" + name;
435
436 uidMap_t::iterator uitr = m_uids.find( uid );
437 bool exists( false );
438 if ( uitr != m_uids.end() ) {
439 exists = true;
440 TObject* t1 = uitr->second->at( 0 ).obj;
441 if ( hist->Compare( t1 ) != 0 ) {
442 error() << "previously registered object with identifier \"" << uid << "\" does not compare to this one"
443 << endmsg;
444 delete hist;
445 return StatusCode::FAILURE;
446 } else {
447 if ( msgLevel( MSG::DEBUG ) ) {
448 debug() << "previously registered id \"" << uid << "\": num " << uitr->second->size() << endmsg;
449 }
450 }
451 }
452
453 bool temp = false;
454 if ( !f ) {
455 temp = true;
456 if ( msgLevel( MSG::DEBUG ) ) { debug() << "Historgram with id \"" << idr << "\" is temporary" << endmsg; }
457 }
458
459 TObject* to = nullptr;
460 THistID hid;
461 // check to see if this hist is to be read in;
462 if ( !temp && m_files.find( stream )->second.second == READ ) {
463 if ( hist != 0 ) { warning() << "Registering id: \"" << idr << "\" with non zero pointer!" << endmsg; }
464
465 hist = readHist_i<T>( idr );
466 if ( hist == nullptr ) {
467 error() << "Unable to read in hist" << endmsg;
468 delete hist;
469 return StatusCode::FAILURE;
470 }
471 to = dynamic_cast<TObject*>( hist );
472 hid = THistID( uid, temp, to, f, m_files.find( stream )->second.second );
473 } else if ( !hist ) {
474 error() << "Unable to read in hist with id: \"" << idr << "\"" << endmsg;
475 delete hist;
476 return StatusCode::FAILURE;
477 } else {
478 to = dynamic_cast<TObject*>( hist );
479 if ( to == nullptr ) {
480 error() << "Could not dcast to TObject. id: \"" << idr << "\"" << endmsg;
481 delete hist;
482 return StatusCode::FAILURE;
483 }
484
485 auto oitr = m_tobjs.find( to );
486 if ( oitr != m_tobjs.end() ) {
487 error() << "already registered id: \"" << idr << "\" with identifier \""
488 << oitr->second.first->at( oitr->second.second ).id << "\"" << endmsg;
489 delete hist;
490 return StatusCode::FAILURE;
491 }
492 }
493
494 const auto findF = m_files.find( stream );
495 hid = ( findF != m_files.end() ? THistID( uid, temp, to, f, findF->second.second ) : THistID( uid, temp, to, f ) );
496
497 hid.shared = shared;
498 TDirectory* dir = changeDir( hid );
499
500 if ( TTree* tree = dynamic_cast<TTree*>( hist ) ) {
501 tree->SetDirectory( dir );
502 hid.type = ObjectType::TTREE;
503 m_hasTTrees = true; // at least one TTree is registered
504 } else if ( TH1* th1 = dynamic_cast<TH1*>( hist ) ) {
505 th1->SetDirectory( dir );
506 hid.type = ObjectType::TH1;
507 } else if ( TEfficiency* teff = dynamic_cast<TEfficiency*>( hist ) ) {
508 teff->SetDirectory( dir );
509 hid.type = ObjectType::TEFFICIENCY;
510 } else if ( dynamic_cast<TGraph*>( hist ) ) {
511 dir->Append( hist );
512 hid.type = ObjectType::TGRAPH;
513 } else {
514 error() << "id: \"" << idr << "\" is not a TH, TTree, TGraph, or TEfficiency. Attaching it to current dir."
515 << endmsg;
516 dir->Append( hist );
517 hid.type = ObjectType::UNKNOWN;
518 }
519
520 std::string fname;
521 if ( !f ) {
522 fname = "none";
523 } else {
524 fname = f->GetName();
525 }
526
527 if ( msgLevel( MSG::DEBUG ) ) {
528 debug() << "Registering" << ( shared ? " shared " : " " ) << System::typeinfoName( typeid( *hist ) ) << " title: \""
529 << hist->GetTitle() << "\" id: \"" << uid
530 << "\" dir: "
531 // << hist->GetDirectory()->GetPath() << " "
532 << changeDir( hid )->GetPath() << " file: " << fname << endmsg;
533 }
534
535 // create a mutex for all shared histograms
536 if ( shared ) { hid.mutex = std::make_unique<histMut_t>(); }
537
538 if ( exists ) {
539 vhid_t* vi = uitr->second;
540 vi->push_back( std::move( hid ) );
541 phid = &( vi->back() );
542
543 m_tobjs.emplace( to, std::pair<vhid_t*, size_t>( vi, vi->size() - 1 ) );
544 } else {
545 vhid_t* vi = new vhid_t;
546 vi->push_back( std::move( hid ) );
547 m_hlist.emplace( m_hlist.end(), vi );
548
549 phid = &( vi->back() );
550 m_uids.emplace( uid, vi );
551 m_ids.emplace( name, vi );
552
553 m_tobjs.emplace( to, std::pair<vhid_t*, size_t>( vi, 0 ) );
554 }
555
556 if ( msgLevel( MSG::DEBUG ) ) { debug() << "regHist_i THistID: " << *phid << endmsg; }
557
558 return StatusCode::SUCCESS;
559}
TemplatedAlg< int, std::vector< std::string > > t1
bool m_hasTTrees
Definition THistSvc.h:391

◆ 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 497 of file THistSvc.cpp.

498 {
499 lh = regShared_i<TEfficiency>( id, std::move( eff ) );
500 if ( lh ) {
501 return StatusCode::SUCCESS;
502 } else {
503 return StatusCode::FAILURE;
504 }
505}
LockedHandle< T > regShared_i(const std::string &id, std::unique_ptr< T > hist)
Definition THistSvc.h:658

◆ 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 488 of file THistSvc.cpp.

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

◆ 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 461 of file THistSvc.cpp.

461 {
462 lh = regShared_i<TH1>( id, std::move( hist ) );
463 if ( lh ) {
464 return StatusCode::SUCCESS;
465 } else {
466 return StatusCode::FAILURE;
467 }
468}

◆ 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 470 of file THistSvc.cpp.

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

◆ 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 479 of file THistSvc.cpp.

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

◆ regShared_i()

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

Definition at line 658 of file THistSvc.h.

658 {
659 LockedHandle<T> lh( nullptr, nullptr );
660 const THistID* hid = nullptr;
661 if ( findHistID( id, hid ) == 0 ) {
662 T* phist = hist.get();
663 THistID* phid = nullptr;
664 if ( regHist_i( std::move( hist ), id, true, phid ).isSuccess() ) {
665 lh.set( phist, phid->mutex.get() );
666
667 } else {
668 error() << "regSharedHist: unable to register shared hist with id \"" << id << "\"" << endmsg;
669 }
670 } else {
671 if ( !hid->shared ) {
672 error() << "regSharedHist: previously register Hist with id \"" << id << "\" was not marked shared" << endmsg;
673 }
674
675 if ( hist->Compare( hid->obj ) != 0 ) {
676 error() << "regSharedHist: Histogram " << id << " does not compare with " << hid << endmsg;
677 } else {
678 T* phist = dynamic_cast<T*>( hid->obj );
679 if ( phist == 0 ) {
680 error() << "regSharedHist: unable to dcast retrieved shared hist \"" << id << "\" of type "
681 << hid->obj->IsA()->GetName() << " to requested type " << System::typeinfoName( typeid( T ) ) << endmsg;
682 } else {
683 lh.set( phist, hid->mutex.get() );
684 delete hist.release();
685 }
686 }
687 }
688 return lh;
689}

◆ regTree() [1/3]

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

Register a new TTree with a given name.

Definition at line 362 of file THistSvc.cpp.

362 {
363 std::unique_ptr<TTree> tree = nullptr;
364 return regHist_i( std::move( tree ), id, false );
365}

◆ 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 367 of file THistSvc.cpp.

367 {
368 StatusCode sc = regHist_i( std::move( tree ), id, false );
369 TTree* tr = nullptr;
370 if ( getTree( id, tr ).isSuccess() && sc.isSuccess() ) {
371 if ( m_autoSave != 0 ) { tr->SetAutoSave( m_autoSave ); }
372 tr->SetAutoFlush( m_autoFlush );
373 }
374 return sc;
375}
bool isSuccess() const
Definition StatusCode.h:314
Gaudi::Property< int > m_autoSave
Definition THistSvc.h:367
Gaudi::Property< int > m_autoFlush
Definition THistSvc.h:368
StatusCode getTree(const std::string &name, TTree *&) const override
Return TTree with given name.
Definition THistSvc.cpp:388

◆ 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 377 of file THistSvc.cpp.

377 {
378 std::unique_ptr<TTree> tree( tree_ptr );
379 StatusCode sc = regHist_i( std::move( tree ), id, false );
380 TTree* tr = nullptr;
381 if ( getTree( id, tr ).isSuccess() && sc.isSuccess() ) {
382 if ( m_autoSave != 0 ) { tr->SetAutoSave( m_autoSave ); }
383 tr->SetAutoFlush( m_autoFlush );
384 }
385 return sc;
386}

◆ reinitialize()

StatusCode THistSvc::reinitialize ( )
override

Definition at line 174 of file THistSvc.cpp.

174 {
176 warning() << "reinitialize not implemented" << endmsg;
177 return StatusCode::SUCCESS;
178}

◆ removeDoubleSlash()

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

Definition at line 1757 of file THistSvc.cpp.

1757 {
1758 while ( id.find( "//" ) != std::string::npos ) { id.replace( id.find( "//" ), 2, "/" ); }
1759}

◆ rootOpenAction()

StatusCode THistSvc::rootOpenAction ( FILEMGR_CALLBACK_ARGS )
private

Definition at line 2059 of file THistSvc.cpp.

2059 {
2060 if ( fa->tech() != Io::ROOT ) {
2061 // This should never happen
2062 return StatusCode::SUCCESS;
2063 }
2064
2065 if ( fa->desc() != "HIST" ) { return StatusCode::SUCCESS; }
2066
2067 p_incSvc->fireIncident( FileIncident( caller, "OpenHistFile", fa->name() ) );
2068
2069 if ( fa->flags().isRead() ) {
2070 p_incSvc->fireIncident( FileIncident( caller, "BeginHistFile", fa->name() ) );
2071 } else if ( fa->flags().isWrite() ) {
2072 p_incSvc->fireIncident( FileIncident( caller, IncidentType::BeginOutputFile, fa->name() ) );
2073 } else {
2074 // for Io::RW
2075 p_incSvc->fireIncident( FileIncident( caller, IncidentType::BeginOutputFile, fa->name() ) );
2076 }
2077
2078 return StatusCode::SUCCESS;
2079}

◆ rootOpenErrAction()

StatusCode THistSvc::rootOpenErrAction ( FILEMGR_CALLBACK_ARGS )
private

Definition at line 2081 of file THistSvc.cpp.

2081 {
2082 if ( fa->tech() != Io::ROOT ) {
2083 // This should never happen
2084 return StatusCode::SUCCESS;
2085 }
2086
2087 if ( fa->desc() != "HIST" ) { return StatusCode::SUCCESS; }
2088
2089 if ( fa->flags().isRead() ) {
2090 p_incSvc->fireIncident( FileIncident( caller, IncidentType::FailInputFile, fa->name() ) );
2091 } else if ( fa->flags().isWrite() ) {
2092 p_incSvc->fireIncident( FileIncident( caller, IncidentType::FailOutputFile, fa->name() ) );
2093 } else {
2094 // for Io::RW
2095 p_incSvc->fireIncident( FileIncident( caller, "FailRWFile", fa->name() ) );
2096 }
2097
2098 return StatusCode::SUCCESS;
2099}

◆ setupInputFile()

void THistSvc::setupInputFile ( )
private

call-back method to handle input stream property

Definition at line 1858 of file THistSvc.cpp.

1858 {
1860 debug() << "Delaying connection of Input Files until Initialize"
1861 << ". now in " << FSMState() << endmsg;
1862
1863 m_delayConnect = true;
1864 } else {
1865 debug() << "Now connecting of Input Files" << endmsg;
1866
1867 StatusCode sc = StatusCode::SUCCESS;
1868
1869 for ( const auto& itr : m_inputfile.value() ) {
1870 if ( m_alreadyConnectedInFiles.end() != m_alreadyConnectedInFiles.find( itr ) ) { continue; }
1871 if ( connect( itr ).isFailure() ) {
1873 } else {
1874 m_alreadyConnectedInFiles.insert( itr );
1875 }
1876 }
1877
1878 if ( !sc.isSuccess() ) { throw GaudiException( "Problem connecting inputfile !!", name(), StatusCode::FAILURE ); }
1879 }
1880}
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 1882 of file THistSvc.cpp.

1882 {
1884 debug() << "Delaying connection of Output Files until Initialize"
1885 << ". now in " << FSMState() << endmsg;
1886 m_delayConnect = true;
1887 } else {
1888 StatusCode sc = StatusCode::SUCCESS;
1889 for ( const auto& itr : m_outputfile.value() ) {
1890 if ( m_alreadyConnectedOutFiles.end() != m_alreadyConnectedOutFiles.find( itr ) ) { continue; }
1891 if ( connect( itr ).isFailure() ) {
1893 } else {
1894 m_alreadyConnectedOutFiles.insert( itr );
1895 }
1896 }
1897
1898 if ( !sc.isSuccess() ) { throw GaudiException( "Problem connecting outputfile !!", name(), StatusCode::FAILURE ); }
1899 }
1900}

◆ stripDirectoryName()

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

Definition at line 1741 of file THistSvc.cpp.

1741 {
1742 std::string::size_type i = dir.find( "/" );
1743
1744 if ( i == std::string::npos ) return {};
1745
1746 if ( i == 0 ) {
1747 dir.erase( 0, 1 );
1748 return stripDirectoryName( dir );
1749 }
1750
1751 std::string root = dir.substr( 0, i );
1752 dir.erase( 0, i );
1753
1754 return root;
1755}

◆ updateFiles()

void THistSvc::updateFiles ( )
private

Handle case where TTree grows beyond TTree::fgMaxTreeSize.

Definition at line 1448 of file THistSvc.cpp.

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

◆ writeObjectsToFile()

StatusCode THistSvc::writeObjectsToFile ( )
private

Definition at line 1518 of file THistSvc.cpp.

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

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 269 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 273 of file THistSvc.h.

◆ m_autoFlush

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

Definition at line 368 of file THistSvc.h.

368{ this, "AutoFlush", 0 };

◆ m_autoSave

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

Definition at line 367 of file THistSvc.h.

367{ 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 373 of file THistSvc.h.

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

◆ m_curstream

std::string THistSvc::m_curstream
mutableprivate

Definition at line 393 of file THistSvc.h.

◆ m_delayConnect

bool THistSvc::m_delayConnect = false
private

Definition at line 389 of file THistSvc.h.

◆ m_files

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

Definition at line 293 of file THistSvc.h.

◆ m_fileStreams

streamMap THistSvc::m_fileStreams
private

Definition at line 295 of file THistSvc.h.

◆ m_hasTTrees

bool THistSvc::m_hasTTrees = false
private

Definition at line 391 of file THistSvc.h.

◆ m_hlist

hlist_t THistSvc::m_hlist
private

Definition at line 286 of file THistSvc.h.

◆ m_ids

idMap_t THistSvc::m_ids
private

Definition at line 288 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 381 of file THistSvc.h.

381 {
382 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 370 of file THistSvc.h.

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

◆ m_okToConnect

bool THistSvc::m_okToConnect = false
private

Definition at line 390 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 379 of file THistSvc.h.

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

◆ m_print

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

Definition at line 369 of file THistSvc.h.

369{ this, "PrintAll", false };

◆ m_Rstream

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

Definition at line 265 of file THistSvc.h.

◆ m_sharedFiles

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

Definition at line 298 of file THistSvc.h.

◆ m_svcMut

THistSvcMutex_t THistSvc::m_svcMut
mutableprivate

Definition at line 395 of file THistSvc.h.

◆ m_tobjs

objMap_t THistSvc::m_tobjs
private

Definition at line 291 of file THistSvc.h.

◆ m_uids

uidMap_t THistSvc::m_uids
private

Definition at line 287 of file THistSvc.h.

◆ m_Wstream

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

Definition at line 265 of file THistSvc.h.

◆ p_fileMgr

ServiceHandle<IFileMgr> THistSvc::p_fileMgr
private

Definition at line 387 of file THistSvc.h.

◆ p_incSvc

ServiceHandle<IIncidentSvc> THistSvc::p_incSvc
private

Definition at line 386 of file THistSvc.h.


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