The Gaudi Framework  v33r0 (d5ea422b)
RFileCnv.cpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2019 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 
19 // ROOT
20 #include "RFileCnv.h"
21 #include "TFile.h"
22 #include "TROOT.h"
23 
24 // local
27 #include <map>
28 #include <string>
29 
30 // Instantiation of a static factory class used by clients to create
31 // instances of this service
33 
34 // Standard constructor
35 RootHistCnv::RFileCnv::RFileCnv( ISvcLocator* svc ) : RDirectoryCnv( svc, classID() ) {}
36 
37 //------------------------------------------------------------------------------
39  // Set compression level property ...
40  ISvcLocator* svcLoc = Gaudi::svcLocator();
41  auto jobSvc = svcLoc->service<IJobOptionsSvc>( "JobOptionsSvc" );
42  auto prop = jobSvc->getClientProperty( "RFileCnv", "GlobalCompression" );
43  if ( prop ) m_compLevel = prop->toString();
44 
45  // initialise base class
47 }
48 //------------------------------------------------------------------------------
49 
50 //------------------------------------------------------------------------------
52 //------------------------------------------------------------------------------
53 {
54  MsgStream log( msgSvc(), "RFileCnv" );
55  unsigned long* ipar = (unsigned long*)pAddress->ipar();
56  char mode[2] = {char( ipar[1] ), 0};
57 
58  std::string fname = pAddress->par()[0]; // Container name
59  std::string ooname = pAddress->par()[1]; // Object name
60 
61  const std::string* spar = pAddress->par();
62  // Strip of store name to get the top level RZ directory
63  std::string oname = spar[1].substr( spar[1].find( "/", 1 ) + 1 );
64 
65  // Protect against multiple instances of TROOT
66  if ( !gROOT ) {
67  static TROOT root( "root", "ROOT I/O" );
68  // gDebug = 99;
69  } else {
70  log << MSG::VERBOSE << "ROOT already initialized, debug = " << gDebug << endmsg;
71  }
72 
73  // Determine access mode:
74 
75  if ( mode[0] == 'O' ) {
76 
77  if ( findTFile( ooname, rfile ).isFailure() ) {
78 
79  log << MSG::INFO << "opening Root file \"" << fname << "\" for reading" << endmsg;
80 
81  rfile = TFile::Open( fname.c_str(), "READ" );
82  if ( rfile && rfile->IsOpen() ) {
83  regTFile( ooname, rfile ).ignore();
84 
85  ipar[0] = (unsigned long)rfile;
86  NTuple::File* pFile = new NTuple::File( objType(), fname, oname );
87  pFile->setOpen( true );
88  refpObject = pFile;
89 
90  return StatusCode::SUCCESS;
91 
92  } else {
93  log << MSG::ERROR << "Couldn't open \"" << fname << "\" for reading" << endmsg;
94  return StatusCode::FAILURE;
95  }
96 
97  } else {
98  log << MSG::DEBUG << "Root file \"" << fname << "\" already opened" << endmsg;
99  return StatusCode::SUCCESS;
100  }
101 
102  } else if ( mode[0] == 'U' ) {
103 
104  log << MSG::INFO << "opening Root file \"" << fname << "\" for updating" << endmsg;
105 
106  log << MSG::ERROR << "don't know how to do this yet. Aborting." << endmsg;
107  exit( 1 );
108 
109  } else if ( mode[0] == 'N' ) {
110 
111  log << MSG::INFO << "opening Root file \"" << fname << "\" for writing";
112  if ( !m_compLevel.empty() ) { log << ", CompressionLevel='" << m_compLevel << "'"; }
113  log << endmsg;
114 
115  rfile = TFile::Open( fname.c_str(), "RECREATE", "Gaudi Trees" );
116  if ( !( rfile && rfile->IsOpen() ) ) {
117  log << MSG::ERROR << "Could not open file " << fname << " for writing" << endmsg;
118  return StatusCode::FAILURE;
119  }
120  if ( !m_compLevel.empty() ) {
121  const RootCompressionSettings settings( m_compLevel );
122  rfile->SetCompressionSettings( settings.level() );
123  }
124 
125  regTFile( ooname, rfile ).ignore();
126 
127  log << MSG::DEBUG << "creating ROOT file " << fname << endmsg;
128 
129  ipar[0] = (unsigned long)rfile;
130  NTuple::File* pFile = new NTuple::File( objType(), fname, oname );
131  pFile->setOpen( true );
132  refpObject = pFile;
133  return StatusCode::SUCCESS;
134 
135  } else {
136 
137  log << MSG::ERROR << "Uknown mode to access ROOT file" << endmsg;
138  return StatusCode::FAILURE;
139  }
140 
141  return StatusCode::FAILURE;
142 }
143 
144 //------------------------------------------------------------------------------
146 //------------------------------------------------------------------------------
147 {
148  refpAddress = pObject->registry()->address();
149  return RFileCnv::updateRep( refpAddress, pObject );
150 }
151 
152 //-----------------------------------------------------------------------------
154 //-----------------------------------------------------------------------------
155 {
156  MsgStream log( msgSvc(), "RFileCnv" );
157  std::string ooname = pAddress->par()[1];
158 
159  NTuple::File* pFile = dynamic_cast<NTuple::File*>( pObject );
160  if ( pFile && pFile->isOpen() ) {
161 
162  unsigned long* ipar = (unsigned long*)pAddress->ipar();
163  if ( findTFile( ooname, rfile ).isFailure() ) {
164  log << MSG::ERROR << "Problems closing TFile " << ooname << endmsg;
165  return StatusCode::FAILURE;
166  }
167 
168  rfile->Write( nullptr, TObject::kOverwrite );
169  if ( log.level() <= MSG::INFO ) {
170  log << MSG::INFO << "dumping contents of " << ooname << endmsg;
171  rfile->Print();
172  }
173 
174  /*
175  * MetaData
176  * Ana Trisovic
177  * March 2015
178  * */
180  mds = serviceLocator()->service( "Gaudi::MetaDataSvc", false );
181  // auto mds = service<IMetaDataSvc>("MetaDataSvc", false);
182  if ( mds ) {
184  if ( !rfile->WriteObject( &m_metadata, "info" ) ) { return StatusCode::FAILURE; }
185  }
186  /* */
187 
188  rfile->Close();
189  delete rfile;
190 
191  ipar[0] = 0;
192  pFile->setOpen( false );
193  return StatusCode::SUCCESS;
194 
195  } else {
196  log << MSG::ERROR << "TFile " << ooname << " is not open" << endmsg;
197  }
198  return StatusCode::FAILURE;
199 }
virtual const std::string * par() const =0
Retrieve String parameters.
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:34
Small smart pointer class with automatic reference counting for IInterface.
Definition: IConverter.h:25
void setOpen(bool flag)
Set "open" flag.
Definition: NTuple.h:954
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition: ISvcLocator.h:35
IRegistry * registry() const
Get pointer to Registry.
Definition: DataObject.h:82
StatusCode initialize() override
Initialise.
Definition: RFileCnv.cpp:38
StatusCode initialize() override
Initialize the converter.
Definition: Converter.cpp:53
StatusCode createRep(DataObject *pObject, IOpaqueAddress *&refpAddress) override
Convert the transient object to the requested representation.
Definition: RFileCnv.cpp:145
StatusCode updateRep(IOpaqueAddress *pAddress, DataObject *pObject) override
Convert the transient object to the requested representation.
Definition: RFileCnv.cpp:153
constexpr static const auto SUCCESS
Definition: StatusCode.h:96
virtual std::map< std::string, std::string > getMetaDataMap() const =0
#define DECLARE_CONVERTER(x)
Definition: Converter.h:160
STL class.
NTuple converter class definition.
Definition: RFileCnv.h:32
StatusCode createObj(IOpaqueAddress *pAddress, DataObject *&refpObject) override
Create the transient representation of an object.
Definition: RFileCnv.cpp:51
StatusCode service(const Gaudi::Utils::TypeNameString &name, T *&svc, bool createIf=true)
Templated method to access a service by name.
Definition: ISvcLocator.h:86
Main interface for the JobOptions service.
GAUDI_API ISvcLocator * svcLocator()
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:61
Create persistent and transient representations of data store directories.
Definition: RDirectoryCnv.h:26
Simple class to decode a ROOT compression settings string, of the form '<Alg>:<level>' into the integ...
std::string m_compLevel
Compression setting, property RFileCnv.GlobalCompression.
Definition: RFileCnv.h:55
virtual IOpaqueAddress * address() const =0
Retrieve opaque storage address.
virtual const Gaudi::Details::PropertyBase * getClientProperty(const std::string &client, const std::string &name) const =0
Get a property for a client.
T c_str(T... args)
constexpr static const auto FAILURE
Definition: StatusCode.h:97
T substr(T... args)
bool isOpen() const
Access "open" flag.
Definition: NTuple.h:956
Opaque address interface definition.
A DataObject is the base class of any identifiable object on any data store.
Definition: DataObject.h:40
virtual const unsigned long * ipar() const =0
Access to generic link parameters.
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:202
Small class representing an N tuple file in the transient store.
Definition: NTuple.h:920