The Gaudi Framework  master (37c0b60a)
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
12 #include <GaudiKernel/Bootstrap.h>
15 #include <GaudiKernel/IRegistry.h>
17 #include <GaudiKernel/MsgStream.h>
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
37 RootHistCnv::RFileCnv::RFileCnv( ISvcLocator* svc ) : RDirectoryCnv( svc, classID() ) {}
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;
52  return StatusCode::FAILURE;
53  }
54  return StatusCode::SUCCESS;
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 
99  return StatusCode::SUCCESS;
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 }
MSG::DEBUG
@ DEBUG
Definition: IMessageSvc.h:25
RootHistCnv::RFileCnv::updateRep
StatusCode updateRep(IOpaqueAddress *pAddress, DataObject *pObject) override
Convert the transient object to the requested representation.
Definition: RFileCnv.cpp:163
NTuple::File
Small class representing an N tuple file in the transient store.
Definition: NTuple.h:923
std::string
STL class.
IOpaqueAddress::par
virtual const std::string * par() const =0
Retrieve String parameters.
Gaudi.Configuration.log
log
Definition: Configuration.py:28
StatusCode::andThen
StatusCode andThen(F &&f, ARGS &&... args) const
Chain code blocks making the execution conditional a success result.
Definition: StatusCode.h:163
MSG::INFO
@ INFO
Definition: IMessageSvc.h:25
Gaudi::Parsers::parse
StatusCode parse(GaudiUtils::HashMap< K, V > &result, std::string_view input)
Basic parser for the types of HashMap used in DODBasicMapper.
Definition: DODBasicMapper.cpp:21
RootHistCnv::RFileCnv::initialize
StatusCode initialize() override
Initialise.
Definition: RFileCnv.cpp:40
IOpaqueAddress
Definition: IOpaqueAddress.h:33
DECLARE_CONVERTER
#define DECLARE_CONVERTER(x)
Definition: Converter.h:163
ISvcLocator
Definition: ISvcLocator.h:46
ContextIncident
Definition: DataIncident.h:26
gaudiComponentHelp.root
root
Definition: gaudiComponentHelp.py:42
DataIncident.h
RootHistCnv::RDirectoryCnv
Definition: RDirectoryCnv.h:26
AvalancheSchedulerErrorTest.msgSvc
msgSvc
Definition: AvalancheSchedulerErrorTest.py:80
RootHistCnv::RFileCnv::m_incSvc
SmartIF< IIncidentSvc > m_incSvc
Definition: RFileCnv.h:57
RootHistCnv::RFileCnv::createRep
StatusCode createRep(DataObject *pObject, IOpaqueAddress *&refpAddress) override
Convert the transient object to the requested representation.
Definition: RFileCnv.cpp:155
RootHistCnv
Definition: DirectoryCnv.h:27
RootHistCnv::RFileCnv
Definition: RFileCnv.h:33
StatusCode
Definition: StatusCode.h:65
RootCompressionSettings.h
RootHistCnv::RFileCnv::createObj
StatusCode createObj(IOpaqueAddress *pAddress, DataObject *&refpObject) override
Create the transient representation of an object.
Definition: RFileCnv.cpp:60
IOpaqueAddress.h
std::string::c_str
T c_str(T... args)
RFileCnv.h
Converter::serviceLocator
SmartIF< ISvcLocator > & serviceLocator() const
Retrieve pointer to service locator.
Definition: Converter.cpp:102
SmartIF
Definition: IConverter.h:25
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:202
std::map< std::string, std::string >
IRegistry.h
MsgStream
Definition: MsgStream.h:33
RootHistCnv::RFileCnv::m_compLevel
std::string m_compLevel
Compression setting, property RFileCnv.GlobalCompression.
Definition: RFileCnv.h:56
std::string::substr
T substr(T... args)
IRegistry::address
virtual IOpaqueAddress * address() const =0
Retrieve opaque storage address.
MSG::VERBOSE
@ VERBOSE
Definition: IMessageSvc.h:25
StatusCode::SUCCESS
constexpr static const auto SUCCESS
Definition: StatusCode.h:100
Converter::service
StatusCode service(const std::string &name, T *&psvc, bool createIf=false) const
Access a service by name, creating it if it doesn't already exist.
Definition: Converter.h:99
MSG::ERROR
@ ERROR
Definition: IMessageSvc.h:25
DataObject
Definition: DataObject.h:36
Bootstrap.h
NTuple::File::setOpen
void setOpen(bool flag)
Set "open" flag.
Definition: NTuple.h:957
NTuple::File::isOpen
bool isOpen() const
Access "open" flag.
Definition: NTuple.h:959
RootHistCnv::RootCompressionSettings::level
int level() const
Get the level.
Definition: RootCompressionSettings.h:38
Converter::initialize
StatusCode initialize() override
Initialize the converter.
Definition: Converter.cpp:53
RootHistCnv::RootCompressionSettings
Definition: RootCompressionSettings.h:29
Converter::msgSvc
SmartIF< IMessageSvc > & msgSvc() const
Retrieve pointer to message service.
Definition: Converter.cpp:105
StatusCode::FAILURE
constexpr static const auto FAILURE
Definition: StatusCode.h:101
ISvcLocator.h
IMetaDataSvc.h
IOptionsSvc.h
DataObject::registry
IRegistry * registry() const
Get pointer to Registry.
Definition: DataObject.h:78
MsgStream.h
IOpaqueAddress::ipar
virtual const unsigned long * ipar() const =0
Access to generic link parameters.