The Gaudi Framework  master (fb0007c6)
Loading...
Searching...
No Matches
RFileCnv.cpp
Go to the documentation of this file.
1/***********************************************************************************\
2* (c) Copyright 1998-2024 CERN for the benefit of the LHCb and ATLAS collaborations *
3* *
4* This software is distributed under the terms of the Apache version 2 licence, *
5* copied verbatim in the file "LICENSE". *
6* *
7* In applying this licence, CERN does not waive the privileges and immunities *
8* granted to it by virtue of its status as an Intergovernmental Organization *
9* or submit itself to any jurisdiction. *
10\***********************************************************************************/
11// Include files
18
20
21// ROOT
22#include "RFileCnv.h"
23#include <TFile.h>
24#include <TROOT.h>
25
26// local
29#include <map>
30#include <string>
31
32// Instantiation of a static factory class used by clients to create
33// instances of this service
35
36// Standard constructor
38
39//------------------------------------------------------------------------------
41 // Set compression level property ...
42 const auto& optsSvc = serviceLocator()->getOptsSvc();
43 if ( optsSvc.has( "RFileCnv.GlobalCompression" ) ) {
44 auto sc = Gaudi::Parsers::parse( m_compLevel, optsSvc.get( "RFileCnv.GlobalCompression" ) );
45 if ( !sc ) return sc;
46 }
47 // initialise base class
48 return RDirectoryCnv::initialize().andThen( [&]() {
49 m_incSvc = service( "IncidentSvc" );
50 if ( !m_incSvc ) {
51 MsgStream( msgSvc() ) << MSG::ERROR << "Cannot access IncidentSvc" << endmsg;
53 }
55 } );
56}
57//------------------------------------------------------------------------------
58
59//------------------------------------------------------------------------------
61//------------------------------------------------------------------------------
62{
63 MsgStream log( msgSvc(), "RFileCnv" );
64 unsigned long* ipar = (unsigned long*)pAddress->ipar();
65 char mode[2] = { char( ipar[1] ), 0 };
66
67 std::string fname = pAddress->par()[0]; // Container name
68 std::string ooname = pAddress->par()[1]; // Object name
69
70 const std::string* spar = pAddress->par();
71 // Strip of store name to get the top level RZ directory
72 std::string oname = spar[1].substr( spar[1].find( "/", 1 ) + 1 );
73
74 // Protect against multiple instances of TROOT
75 if ( !gROOT ) {
76 static TROOT root( "root", "ROOT I/O" );
77 // gDebug = 99;
78 } else {
79 log << MSG::VERBOSE << "ROOT already initialized, debug = " << gDebug << endmsg;
80 }
81
82 // Determine access mode:
83
84 if ( mode[0] == 'O' ) {
85
86 if ( findTFile( ooname, rfile ).isFailure() ) {
87
88 log << MSG::INFO << "opening Root file \"" << fname << "\" for reading" << endmsg;
89
90 rfile = TFile::Open( fname.c_str(), "READ" );
91 if ( rfile && rfile->IsOpen() ) {
92 regTFile( ooname, rfile ).ignore();
93
94 ipar[0] = (unsigned long)rfile;
95 NTuple::File* pFile = new NTuple::File( objType(), fname, oname );
96 pFile->setOpen( true );
97 refpObject = pFile;
98
100
101 } else {
102 log << MSG::ERROR << "Couldn't open \"" << fname << "\" for reading" << endmsg;
103 return StatusCode::FAILURE;
104 }
105
106 } else {
107 log << MSG::DEBUG << "Root file \"" << fname << "\" already opened" << endmsg;
108 return StatusCode::SUCCESS;
109 }
110
111 } else if ( mode[0] == 'U' ) {
112
113 log << MSG::INFO << "opening Root file \"" << fname << "\" for updating" << endmsg;
114
115 log << MSG::ERROR << "don't know how to do this yet. Aborting." << endmsg;
116 exit( 1 );
117
118 } else if ( mode[0] == 'N' ) {
119
120 log << MSG::INFO << "opening Root file \"" << fname << "\" for writing";
121 if ( !m_compLevel.empty() ) { log << ", CompressionLevel='" << m_compLevel << "'"; }
122 log << endmsg;
123
124 rfile = TFile::Open( fname.c_str(), "RECREATE", "Gaudi Trees" );
125 if ( !( rfile && rfile->IsOpen() ) ) {
126 log << MSG::ERROR << "Could not open file " << fname << " for writing" << endmsg;
127 return StatusCode::FAILURE;
128 }
129 if ( !m_compLevel.empty() ) {
130 const RootCompressionSettings settings( m_compLevel );
131 rfile->SetCompressionSettings( settings.level() );
132 }
133
134 regTFile( ooname, rfile ).ignore();
135
136 log << MSG::DEBUG << "creating ROOT file " << fname << endmsg;
137 m_incSvc->fireIncident( ContextIncident<TFile*>( fname, "CONNECTED_NTUPLE_OUTPUT", rfile ) );
138
139 ipar[0] = (unsigned long)rfile;
140 NTuple::File* pFile = new NTuple::File( objType(), fname, oname );
141 pFile->setOpen( true );
142 refpObject = pFile;
143 return StatusCode::SUCCESS;
144
145 } else {
146
147 log << MSG::ERROR << "Uknown mode to access ROOT file" << endmsg;
148 return StatusCode::FAILURE;
149 }
150
151 return StatusCode::FAILURE;
152}
153
154//------------------------------------------------------------------------------
156//------------------------------------------------------------------------------
157{
158 refpAddress = pObject->registry()->address();
159 return RFileCnv::updateRep( refpAddress, pObject );
160}
161
162//-----------------------------------------------------------------------------
164//-----------------------------------------------------------------------------
165{
166 MsgStream log( msgSvc(), "RFileCnv" );
167 std::string ooname = pAddress->par()[1];
168
169 NTuple::File* pFile = dynamic_cast<NTuple::File*>( pObject );
170 if ( pFile && pFile->isOpen() ) {
171
172 unsigned long* ipar = (unsigned long*)pAddress->ipar();
173 if ( findTFile( ooname, rfile ).isFailure() ) {
174 log << MSG::ERROR << "Problems closing TFile " << ooname << endmsg;
175 return StatusCode::FAILURE;
176 }
177
178 rfile->Write( nullptr, TObject::kOverwrite );
179 if ( log.level() <= MSG::INFO ) {
180 log << MSG::INFO << "dumping contents of " << ooname << endmsg;
181 rfile->Print();
182 }
183
184 /*
185 * MetaData
186 * Ana Trisovic
187 * March 2015
188 * */
190 mds = serviceLocator()->service( "Gaudi::MetaDataSvc", false );
191 // auto mds = service<IMetaDataSvc>("MetaDataSvc", false);
192 if ( mds ) {
193 std::map<std::string, std::string> m_metadata = mds->getMetaDataMap();
194 if ( !rfile->WriteObject( &m_metadata, "info" ) ) { return StatusCode::FAILURE; }
195 }
196 /* */
197
198 rfile->Close();
199 delete rfile;
200
201 ipar[0] = 0;
202 pFile->setOpen( false );
203 return StatusCode::SUCCESS;
204
205 } else {
206 log << MSG::ERROR << "TFile " << ooname << " is not open" << endmsg;
207 }
208 return StatusCode::FAILURE;
209}
#define DECLARE_CONVERTER(x)
Definition Converter.h:142
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition MsgStream.h:198
StatusCode initialize() override
Initialize the converter.
Definition Converter.cpp:52
SmartIF< ISvcLocator > & serviceLocator() const
Retrieve pointer to service locator.
SmartIF< IMessageSvc > & msgSvc() const
Retrieve pointer to message service.
const CLID & objType() const override
Retrieve the class type of objects the converter produces.
Definition Converter.cpp:22
SmartIF< IService > service(const std::string &name, const bool createIf=true) const
Return a pointer to the service identified by name (or "type/name")
A DataObject is the base class of any identifiable object on any data store.
Definition DataObject.h:37
IRegistry * registry() const
Get pointer to Registry.
Definition DataObject.h:79
Opaque address interface definition.
virtual const unsigned long * ipar() const =0
Access to generic link parameters.
virtual const std::string * par() const =0
Retrieve String parameters.
virtual IOpaqueAddress * address() const =0
Retrieve opaque storage address.
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition ISvcLocator.h:42
Gaudi::Interfaces::IOptionsSvc & getOptsSvc()
Direct access to Gaudi::Interfaces::IOptionsSvc implementation.
Definition of the MsgStream class used to transmit messages.
Definition MsgStream.h:29
Small class representing an N tuple file in the transient store.
Definition NTuple.h:915
void setOpen(bool flag)
Set "open" flag.
Definition NTuple.h:949
bool isOpen() const
Access "open" flag.
Definition NTuple.h:951
StatusCode findTFile(const std::string &, TFile *&)
StatusCode regTFile(const std::string &, const TFile *)
RDirectoryCnv(ISvcLocator *svc)
Standard constructor.
NTuple converter class definition.
StatusCode initialize() override
Initialise.
Definition RFileCnv.cpp:40
std::string m_compLevel
Compression setting, property RFileCnv.GlobalCompression.
Definition RFileCnv.h:55
TFile * rfile
Pointer to ROOT file.
Definition RFileCnv.h:54
SmartIF< IIncidentSvc > m_incSvc
Definition RFileCnv.h:56
StatusCode createRep(DataObject *pObject, IOpaqueAddress *&refpAddress) override
Convert the transient object to the requested representation.
Definition RFileCnv.cpp:155
static const CLID & classID()
Inquire class type.
Definition RFileCnv.h:48
StatusCode createObj(IOpaqueAddress *pAddress, DataObject *&refpObject) override
Create the transient representation of an object.
Definition RFileCnv.cpp:60
RFileCnv(ISvcLocator *svc)
Standard constructor.
Definition RFileCnv.cpp:37
StatusCode updateRep(IOpaqueAddress *pAddress, DataObject *pObject) override
Convert the transient object to the requested representation.
Definition RFileCnv.cpp:163
Simple class to decode a ROOT compression settings string, of the form '<Alg>:<level>' into the integ...
Small smart pointer class with automatic reference counting for IInterface.
Definition SmartIF.h:28
This class is used for returning status codes from appropriate routines.
Definition StatusCode.h:64
StatusCode andThen(F &&f, ARGS &&... args) const
Chain code blocks making the execution conditional a success result.
Definition StatusCode.h:163
constexpr static const auto SUCCESS
Definition StatusCode.h:99
constexpr static const auto FAILURE
Definition StatusCode.h:100
StatusCode parse(GaudiUtils::HashMap< K, V > &result, std::string_view input)
Basic parser for the types of HashMap used in DODBasicMapper.
@ DEBUG
Definition IMessageSvc.h:22
@ ERROR
Definition IMessageSvc.h:22
@ INFO
Definition IMessageSvc.h:22
@ VERBOSE
Definition IMessageSvc.h:22