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