Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 10:31:47

0001 /***********************************************************************************\
0002 * (c) Copyright 1998-2024 CERN for the benefit of the LHCb and ATLAS collaborations *
0003 *                                                                                   *
0004 * This software is distributed under the terms of the Apache version 2 licence,     *
0005 * copied verbatim in the file "LICENSE".                                            *
0006 *                                                                                   *
0007 * In applying this licence, CERN does not waive the privileges and immunities       *
0008 * granted to it by virtue of its status as an Intergovernmental Organization        *
0009 * or submit itself to any jurisdiction.                                             *
0010 \***********************************************************************************/
0011 #pragma once
0012 
0013 // Framework include files
0014 #include <Gaudi/Property.h>
0015 #include <GaudiKernel/ClassID.h>
0016 #include <GaudiKernel/IIncidentSvc.h>
0017 #include <GaudiKernel/SmartIF.h>
0018 #include <GaudiUtils/IIODataManager.h>
0019 #include <map>
0020 #include <set>
0021 #include <string>
0022 #include <string_view>
0023 #include <vector>
0024 
0025 #include <RootCnv/RootRefs.h>
0026 #include <TFile.h>
0027 #include <TTreePerfStats.h>
0028 
0029 // Forward declarations
0030 class TTree;
0031 class TClass;
0032 class TBranch;
0033 
0034 class MsgStream;
0035 class IRegistry;
0036 class DataObject;
0037 class IIncidentSvc;
0038 
0039 /*
0040  *  Gaudi namespace declaration
0041  */
0042 namespace Gaudi {
0043 
0044   /** @class RootConnectionSet RootDataConnection.h GaudiRootCnv/RootDataConnection.h
0045    *
0046    *  Class describing the setup parameters of a ROOT data connection.
0047    *  The parameters are filled by the conversion service (using properties)
0048    *  and is then passed to all data connections served by this service.
0049    *
0050    *  @author  M.Frank
0051    *  @version 1.0
0052    *  @date    20/12/2009
0053    */
0054   class GAUDI_API RootConnectionSetup final {
0055   private:
0056     /// Reference to message service
0057     std::unique_ptr<MsgStream> m_msgSvc;
0058     /// Reference to incident service
0059     SmartIF<IIncidentSvc> m_incidentSvc = nullptr;
0060 
0061   public:
0062     /// Type definition for string maps
0063     typedef std::vector<std::string> StringVec;
0064 
0065     /// Vector of strings with branches to be cached for input files
0066     StringVec cacheBranches;
0067     /// Vector of strings with branches to NOT be cached for input files
0068     StringVec vetoBranches;
0069     /// RootCnvSvc Property: Root data cache size
0070     std::string loadSection;
0071     /// RootCnvSvc Property: Root data cache size
0072     int cacheSize{ 0 };
0073     /// RootCnvSvc Property: ROOT cache learn entries
0074     int learnEntries{ 0 };
0075 
0076     Gaudi::Property<bool> produceReproducibleFiles{ "ProduceReproducibleFiles", true,
0077                                                     "configure output files to be more reproducible" };
0078 
0079     Gaudi::Property<bool> root630ForwardCompatibility{
0080         "ROOT630ForwardCompatibility", false,
0081         "When opening a file for CREATE or RECREATE, enable ROOT 6.30 forward compatibility "
0082         "(i.e. write a file that is readable with ROOT 6.24). Requires ROOT >= 6.30.06, see "
0083         "<https://github.com/root-project/root/issues/14793>." };
0084 
0085     /// Standard constructor
0086     RootConnectionSetup() = default;
0087 
0088     /// Set the global compression level
0089     static StatusCode setCompression( std::string_view compression );
0090     /// Access to global compression level
0091     static int compression();
0092 
0093     /// Set message service reference
0094     void setMessageSvc( MsgStream* m );
0095     /// Retrieve message service
0096     MsgStream& msgSvc() const { return *m_msgSvc; }
0097 
0098     /// Set incident service reference
0099     void setIncidentSvc( IIncidentSvc* m );
0100     /// Retrieve incident service
0101     IIncidentSvc* incidentSvc() const { return m_incidentSvc.get(); }
0102   };
0103 
0104   /** @class RootDataConnection RootDataConnection.h GaudiRootCnv/RootDataConnection.h
0105    *
0106    *  Concrete implementation of the IDataConnection interface to access ROOT files.
0107    *
0108    *  @author  M.Frank
0109    *  @version 1.0
0110    *  @date    20/12/2009
0111    */
0112   class GAUDI_API RootDataConnection : virtual public Gaudi::IDataConnection {
0113   public:
0114     enum class Status : StatusCode::code_t { ROOT_READ_ERROR = 0x2, ROOT_OPEN_ERROR = 0x4 };
0115 
0116     /** @class ContainerSection RootDataConnection.h GaudiRootCnv/RootDataConnection.h
0117      *
0118      *  Internal helper class, which described a TBranch section in a ROOT file.
0119      *  TBranch sections (ie. an interval of events) are used to describe
0120      *  files using the ROOT fast merge mechanism.
0121      *
0122      *  @author  M.Frank
0123      *  @version 1.0
0124      *  @date    20/12/2009
0125      */
0126     struct ContainerSection {
0127       /// Default constructor
0128       ContainerSection() : start( -1 ), length( 0 ) {}
0129       /// Initializing constructor
0130       ContainerSection( int s, int l ) : start( s ), length( l ) {}
0131       /// Copy constructor
0132       ContainerSection( const ContainerSection& s ) : start( s.start ), length( s.length ) {}
0133       /// Assignment operator to copy objects
0134       ContainerSection& operator=( const ContainerSection& s ) {
0135         if ( this != &s ) {
0136           start  = s.start;
0137           length = s.length;
0138         }
0139         return *this;
0140       }
0141       /// The start entry of the section
0142       int start;
0143       /// The length of the section
0144       int length;
0145     };
0146 
0147     /// Type definition for string maps
0148     typedef std::vector<std::string> StringVec;
0149     /// Type definition for the parameter map
0150     typedef std::vector<std::pair<std::string, std::string>> ParamMap;
0151     /// Definition of tree sections
0152     typedef std::map<std::string, TTree*, std::less<>> Sections;
0153     /// Definition of container sections to handle merged files
0154     typedef std::vector<ContainerSection> ContainerSections;
0155     /// Definition of database section to handle merged files
0156     typedef std::map<std::string, ContainerSections, std::less<>> MergeSections;
0157     /// Link sections definition
0158     typedef std::vector<RootRef> LinkSections;
0159     /// Client set
0160     typedef std::set<const IInterface*> Clients;
0161 
0162     /// Allow access to printer service
0163     MsgStream&    msgSvc() const { return m_setup->msgSvc(); }
0164     IIncidentSvc* incidentSvc() const { return m_setup->incidentSvc(); }
0165 
0166   protected:
0167     /// Reference to the setup structure
0168     std::shared_ptr<RootConnectionSetup> m_setup;
0169     /// I/O read statistics from TTree
0170     std::unique_ptr<TTreePerfStats> m_statistics;
0171     /// Reference to ROOT file
0172     std::unique_ptr<TFile> m_file;
0173     /// Pointer to the reference tree
0174     TTree* m_refs = nullptr;
0175     /// Tree sections in TFile
0176     Sections m_sections;
0177     /// Map containing external database file names (fids)
0178     StringVec m_dbs;
0179     /// Map containing external container names
0180     StringVec m_conts;
0181     /// Map containing internal links names
0182     StringVec m_links;
0183     /// Map containing merge FIDs
0184     StringVec m_mergeFIDs;
0185     /// Parameter map for file parameters
0186     ParamMap m_params;
0187     /// Database section map for merged files
0188     MergeSections m_mergeSects;
0189     /// Database link sections
0190     LinkSections m_linkSects;
0191     /// Client list
0192     Clients m_clients;
0193     /// Buffer for empty string reference
0194     std::string m_empty;
0195 
0196     /// Empty string reference
0197     const std::string& empty() const;
0198 
0199     /// Internal helper to save/update reference tables
0200     StatusCode saveRefs();
0201 
0202   public:
0203     /** @class Tool RootDataConnection.h src/RootDataConnection.h
0204      *
0205      * Helper class to facilitate an abstraction layer for reading
0206      * POOL style files with this package.
0207      * YES: This class obsoletes POOL.
0208      *
0209      * @author  M.Frank
0210      * @version 1.0
0211      */
0212     class Tool {
0213     protected:
0214       typedef RootDataConnection::StringVec         StringVec;
0215       typedef RootDataConnection::ParamMap          ParamMap;
0216       typedef RootDataConnection::Sections          Sections;
0217       typedef RootDataConnection::MergeSections     MergeSections;
0218       typedef RootDataConnection::LinkSections      LinkSections;
0219       typedef RootDataConnection::ContainerSection  ContainerSection;
0220       typedef RootDataConnection::ContainerSections ContainerSections;
0221 
0222       /// Pointer to containing data connection object
0223       RootDataConnection* c;
0224 
0225     public:
0226       TTree*             refs() const { return c->m_refs; }
0227       StringVec&         dbs() const { return c->m_dbs; }
0228       StringVec&         conts() const { return c->m_conts; }
0229       StringVec&         links() const { return c->m_links; }
0230       ParamMap&          params() const { return c->m_params; }
0231       MsgStream&         msgSvc() const { return c->msgSvc(); }
0232       IIncidentSvc*      incidentSvc() const { return c->incidentSvc(); }
0233       const std::string& name() const { return c->m_name; }
0234       Sections&          sections() const { return c->m_sections; }
0235       LinkSections&      linkSections() const { return c->m_linkSects; }
0236       MergeSections&     mergeSections() const { return c->m_mergeSects; }
0237 
0238       /// Default destructor
0239       virtual ~Tool() = default;
0240       /// Access data branch by name: Get existing branch in read only mode
0241       virtual TBranch* getBranch( std::string_view section, std::string_view n ) = 0;
0242       /// Internal overload to facilitate the access to POOL files
0243       virtual RootRef poolRef( size_t /* which */ ) const { return RootRef(); }
0244 
0245       /// Read references section when opening data file
0246       virtual StatusCode readRefs() = 0;
0247       /// Save references section when closing data file
0248       virtual StatusCode saveRefs() = 0;
0249       /// Load references object
0250       virtual int loadRefs( std::string_view section, std::string_view cnt, unsigned long entry,
0251                             RootObjectRefs& refs ) = 0;
0252     };
0253     std::unique_ptr<Tool> m_tool;
0254     friend class Tool;
0255 
0256     /// Create file access tool to encapsulate POOL compatibiliy
0257     Tool* makeTool();
0258 
0259   public:
0260     /// Standard constructor
0261     RootDataConnection( const IInterface* own, std::string_view nam, std::shared_ptr<RootConnectionSetup> setup );
0262 
0263     /// Direct access to TFile structure
0264     TFile* file() const { return m_file.get(); }
0265     /// Check if connected to data source
0266     bool isConnected() const override { return bool( m_file ); }
0267     /// Is the file writable?
0268     bool isWritable() const { return m_file && m_file->IsWritable(); }
0269     /// Access tool
0270     Tool* tool() const { return m_tool.get(); }
0271     /// Access merged data section inventory
0272     const MergeSections& mergeSections() const { return m_mergeSects; }
0273     /// Access merged FIDs
0274     const StringVec& mergeFIDs() const { return m_mergeFIDs; }
0275 
0276     /// Add new client to this data source
0277     void addClient( const IInterface* client );
0278     /// Remove client from this data source
0279     size_t removeClient( const IInterface* client );
0280     /// Lookup client for this data source
0281     bool lookupClient( const IInterface* client ) const;
0282 
0283     /// Error handler when bad write statements occur
0284     void badWriteError( std::string_view msg ) const;
0285 
0286     /// Access link section for single container and entry
0287     std::pair<const RootRef*, const ContainerSection*> getMergeSection( std::string_view container, int entry ) const;
0288 
0289     /// Enable TTreePerStats
0290     void enableStatistics( std::string_view section );
0291     /// Save TTree access statistics if required
0292     void saveStatistics( std::string_view statisticsFile );
0293 
0294     /// Load object
0295     int loadObj( std::string_view section, std::string_view cnt, unsigned long entry, DataObject*& pObj );
0296 
0297     /// Load references object
0298     int loadRefs( std::string_view section, std::string_view cnt, unsigned long entry, RootObjectRefs& refs );
0299 
0300     /// Save object of a given class to section and container
0301     std::pair<int, unsigned long> saveObj( std::string_view section, std::string_view cnt, TClass* cl, DataObject* pObj,
0302                                            int minBufferSize, int maxBufferSize, int approxEventsPerBasket,
0303                                            int split_lvl, bool fill_missing = false );
0304     /// Save object of a given class to section and container
0305     std::pair<int, unsigned long> save( std::string_view section, std::string_view cnt, TClass* cl, void* pObj,
0306                                         int minBufferSize, int maxBufferSize, int approxEventsPerBasket, int split_lvl,
0307                                         bool fill_missing = false );
0308 
0309     /// Open data stream in read mode
0310     StatusCode connectRead() override;
0311     /// Open data stream in write mode
0312     StatusCode connectWrite( IoType typ ) override;
0313     /// Release data stream and release implementation dependent resources
0314     StatusCode disconnect() override;
0315     /// Read root byte buffer from input stream
0316     StatusCode read( void* const, size_t ) override { return StatusCode::FAILURE; }
0317     /// Write root byte buffer to output stream
0318     StatusCode write( const void*, int ) override { return StatusCode::FAILURE; }
0319     /// Seek on the file described by ioDesc. Arguments as in ::seek()
0320     long long int seek( long long int, int ) override { return -1; }
0321 
0322     /// Access TTree section from section name. The section is created if required.
0323     TTree* getSection( std::string_view sect, bool create = false );
0324 
0325     /// Access data branch by name: Get existing branch in read only mode
0326     TBranch* getBranch( std::string_view section, std::string_view branch_name ) {
0327       return m_tool->getBranch( section, branch_name );
0328     }
0329     /// Access data branch by name: Get existing branch in write mode
0330     TBranch* getBranch( std::string_view section, std::string_view branch_name, TClass* cl, void* ptr, int buff_siz,
0331                         int split_lvl );
0332 
0333     /// Create reference object from registry entry
0334     void makeRef( const IRegistry& pA, RootRef& ref );
0335     /// Create reference object from values
0336     void makeRef( std::string_view name, long clid, int tech, std::string_view db, std::string_view cnt, int entry,
0337                   RootRef& ref );
0338 
0339     /// Convert path string to path index
0340     int makeLink( std::string_view p );
0341 
0342     /// Access database/file name from saved index
0343     const std::string& getDb( int which ) const;
0344 
0345     /// Access container name from saved index
0346     const std::string& getCont( int which ) const {
0347       return ( which >= 0 ) && ( size_t( which ) < m_conts.size() ) ? *( m_conts.begin() + which ) : empty();
0348     }
0349 
0350     /// Access link name from saved index
0351     const std::string& getLink( int which ) const {
0352       return ( which >= 0 ) && ( size_t( which ) < m_links.size() ) ? *( m_links.begin() + which ) : empty();
0353     }
0354   };
0355 } // End namespace Gaudi
0356 
0357 STATUSCODE_ENUM_DECL( Gaudi::RootDataConnection::Status )