BOSS 8.0.0
BESIII Offline Software System
Loading...
Searching...
No Matches
RootCalBaseCnv.cxx
Go to the documentation of this file.
1// $Header: /bes/bes/BossCvs/Calibration/CalibSvc/CalibROOTCnv/src/cnv/RootCalBaseCnv.cxx,v 1.8
2// 2022/03/04 03:49:16 maqm Exp $
3/**
4 @file RootCalBaseCnv.cxx
5
6 Implementation file for Root calibration converter base class
7*/
8
9#include "RootCalBaseCnv.h"
10
11#include "GaudiKernel/DataObject.h"
12#include "GaudiKernel/IAddressCreator.h"
13#include "GaudiKernel/IConversionSvc.h"
14#include "GaudiKernel/IDataProviderSvc.h"
15#include "GaudiKernel/IOpaqueAddress.h"
16#include "GaudiKernel/MsgStream.h"
17
18#include "CalibData/CalibBase.h"
19#include "CalibData/CalibBase1.h"
20#include "CalibDataSvc/ICalibMetaCnvSvc.h"
21#include "CalibDataSvc/ICalibRootSvc.h"
22#include "CalibDataSvc/IInstrumentName.h"
23#include "facilities/Util.h" // for translating env variables
24// Guessing at needed Root includes
25#include "TFile.h"
26#include "TObject.h"
27#include "TROOT.h" // need this for cd??
28#include "TTree.h"
29
31 // release TFile, TTree if they need releasing. With normal
32 // termination they should already have been released.
33
34 // doClean();
35}
36
37// static CnvFactory<RootCalBaseCnv> s_factory;
38// const ICnvFactory& RootCalBaseCnvFactory = s_factory;
39RootCalBaseCnv::RootCalBaseCnv( ISvcLocator* svc, const CLID& clid )
40 : Converter( CALIBROOT_StorageType, clid, svc )
41 , m_rootSvc( 0 )
42 , m_metaSvc( 0 )
43 , m_instrSvc( 0 )
44 , m_vstart( 0 )
45 , m_vend( 0 )
46 , m_outFile( 0 )
47 , m_ttree( 0 )
48 , m_inFile( 0 )
49 , m_saveDir( 0 ) {}
50
52 StatusCode status = Converter::initialize();
53
54 IDataProviderSvc* dp;
55
56 // I guess the service names are assigned in jobOptions?
57
58 /*serviceLocator()->getService ("CalibDataSvc",
59 IID_IDataProviderSvc,
60 (IInterface*&)dp);*/
61 serviceLocator()->getService( "CalibDataSvc", IDataProviderSvc::interfaceID(),
62 (IInterface*&)dp );
63 setDataProvider( dp );
64 // Locate the Root Conversion Service
65 serviceLocator()->getService( "CalibRootCnvSvc", ICalibRootSvc::interfaceID(),
66 (IInterface*&)m_rootSvc );
67
68 // Locate meta conversion service
69 // Will anything need to be changed here to accommodate possibility
70 // of two concrete implementations of ICalibMetaCnvSvc? Would
71 // have different storage types. Could specify type desired
72 // as job option. Ditto for name of class?
73 serviceLocator()->getService( "CalibMySQLCnvSvc", ICalibMetaCnvSvc::interfaceID(),
74 (IInterface*&)m_metaSvc );
75 serviceLocator()->getService( "CalibDataSvc", IInstrumentName::interfaceID(),
76 (IInterface*&)m_instrSvc );
77
78 return status;
79}
80
81StatusCode RootCalBaseCnv::finalize() { return Converter::finalize(); }
82
83/****** ROOT services *****/
84
85StatusCode RootCalBaseCnv::createRoot( const std::string& /* fname */,
86 CalibData::CalibBase1* /* pTDSObj */ ) {
87 MsgStream log( msgSvc(), "RootCalBaseCnv" );
88 log << MSG::ERROR << "createRoot method not implemented for this calibration type" << endmsg;
89 return StatusCode::FAILURE;
90}
91
92StatusCode RootCalBaseCnv::openRead( const std::string& fname ) {
93
94 MsgStream log( msgSvc(), "RootCalBaseCnv" );
95
96 // Check fname isn't empty
97 if ( fname == std::string( "" ) ) return StatusCode::FAILURE;
98
99 if ( doClean() ) { log << MSG::WARNING << "Previous operation didn't clean up! " << endmsg; }
100 m_saveDir = gDirectory;
101
102 std::string ourName( fname );
104
105 m_inFile = new TFile( ourName.c_str() );
106
107 if ( !m_inFile->IsOpen() )
108 {
109 log << MSG::ERROR << "ROOT file " << ourName << "could not be opened for reading "
110 << endmsg;
111 delete m_inFile;
112 m_inFile = 0;
113 return StatusCode::FAILURE;
114 }
115 else
116 {
117 log << MSG::INFO << "Successfully opened ROOT file " << fname << " aka " << ourName
118 << " for reading " << endmsg;
119 }
120
121 m_inFile->cd(); // Maybe will need this
122
123 return StatusCode::SUCCESS;
124}
125
127 m_inFile->Close();
128
129 delete m_inFile;
130 m_inFile = 0;
131
132 if ( m_saveDir )
133 {
134 m_saveDir->cd();
135 m_saveDir = 0;
136 }
137 return StatusCode::SUCCESS;
138}
139
140StatusCode RootCalBaseCnv::openWrite( const std::string& fname ) {
141
142 MsgStream log( msgSvc(), "RootCalBaseCnv" );
143
144 // Check fname isn't empty
145 if ( fname == std::string( "" ) ) return StatusCode::FAILURE;
146
147 std::string ourName( fname );
149
150 if ( doClean() ) { log << MSG::WARNING << "Previous operation didn't clean up! " << endmsg; }
151
152 m_saveDir = gDirectory;
153
154 m_outFile = new TFile( ourName.c_str(), "RECREATE" );
155 if ( !m_outFile->IsOpen() )
156 {
157 log << MSG::ERROR << "ROOT file " << fname << " aka " << ourName
158 << " could not be opened for writing" << endmsg;
159 delete m_outFile;
160 m_outFile = 0;
161 return StatusCode::FAILURE;
162 }
163 else
164 {
165 log << MSG::INFO << "Successfully opened ROOT file " << fname << " aka " << ourName
166 << " for writing " << endmsg;
167 }
168 m_outFile->cd();
169 return StatusCode::SUCCESS;
170}
171
173
174 MsgStream log( msgSvc(), "RootCalBaseCnv" );
175
176 StatusCode ret = StatusCode::SUCCESS;
177
178 m_outFile->cd();
179 m_outFile->Close();
180 delete m_outFile;
181 m_outFile = 0;
182 if ( m_saveDir ) m_saveDir->cd();
183 m_saveDir = 0;
184 return ret;
185}
186
187StatusCode RootCalBaseCnv::readRootObj( const std::string& treename, const std::string& branch,
188 TObject*& pObj, unsigned ix ) {
189 TTree* pTree = (TTree*)m_inFile->Get( treename.c_str() );
190
191 return readRootObj( pTree, branch, pObj, ix );
192}
193
194StatusCode RootCalBaseCnv::readRootObj( TTree* pTree, const std::string& branch,
195 TObject*& pObj, unsigned ix ) {
196 TBranch* pBranch = pTree->GetBranch( branch.c_str() );
197 pBranch->SetAddress( &pObj );
198 int nBytes = pBranch->GetEntry( ix );
199 return ( nBytes > 0 ) ? StatusCode::SUCCESS : StatusCode::FAILURE;
200}
201
202bool RootCalBaseCnv::doClean() {
203 bool ret = false;
204
205 if ( m_outFile )
206 {
207 m_outFile->Close();
208 delete m_outFile;
209 m_outFile = 0;
210 ret = true;
211 }
212
213 if ( m_inFile )
214 {
215 m_inFile->Close();
216 delete m_inFile;
217 m_inFile = 0;
218 ret = true;
219 }
220 m_ttree = 0;
221 if ( m_saveDir )
222 {
223 m_saveDir->cd();
224 m_saveDir = 0;
225 }
226 return ret;
227}
228
229// Do our part to write out object -- which is nothing
231 TObject* /* pRootObj */ ) {
232
233 // Get instrument name from InstrumentName service Now handled by
234 // RootCalBaseCnv
235 // TString instr = TString((m_instrSvc->getInstrumentName()).c_str());
236 // pRootObj->setInstrument(instr);
237 return StatusCode::SUCCESS;
238}
239
240// (To TDS) Conversion stuff
241StatusCode RootCalBaseCnv::createObj( IOpaqueAddress* addr, DataObject*& refpObject ) {
242 // StatusCode ret;
243
244 // first do the things we always need:
245 // First string parameter of opaque address is file ident
246 MsgStream log( msgSvc(), "RootCalBaseCnv" );
247 log << MSG::DEBUG << "RootCalBaseCnv::createObj( starting ...." << endmsg;
248 const std::string* par = addr->par();
249
250 std::string par0 = par[0];
251
252 return internalCreateObj( par0, refpObject, addr );
253}
254
255StatusCode RootCalBaseCnv::internalCreateObj( const std::string& fname,
256 DataObject*& refpObject,
257 IOpaqueAddress* address ) {
258 MsgStream log( msgSvc(), "RootCalBaseCnv" );
259 log << MSG::DEBUG << "RootCalBaseCnv::internalCreateObj( starting ..... " << endmsg;
260 RootCalBaseCnv* converter = this;
261 CLID classId = address->clID();
262
263 IConverter* conv = this->conversionSvc()->converter( classId );
264 if ( 0 == conv )
265 {
266 log << MSG::WARNING << "No proper converter found for classID " << classId
267 << ", the default converter"
268 << " will be used. " << endmsg;
269 }
270 else
271 {
272 converter = dynamic_cast<RootCalBaseCnv*>( conv );
273 if ( 0 == converter )
274 {
275 log << MSG::ERROR << "The converter found for classID " << classId
276 << " was not a descendent of RootCalBaseCnv as it should be "
277 << "( was of type " << typeid( *converter ).name() << "). "
278 << "The default converter will be used" << endmsg;
279 converter = this;
280 }
281 }
282
283 m_runfrm = *( address->ipar() );
284 m_runto = *( address->ipar() + 1 );
285 // creates an object for the node found
286 StatusCode sc = converter->i_createObj( fname, refpObject );
287 if ( sc.isFailure() ) { return sc; }
288 CalibData::CalibBase1* tmpObject = dynamic_cast<CalibData::CalibBase1*>( refpObject );
289 setBaseInfo( tmpObject );
290 // ends up the object construction
291 sc = converter->i_processObj( refpObject, address );
292 if ( sc.isSuccess() )
293 { log << MSG::DEBUG << "Successfully created calib. object " << endmsg; }
294 closeRead();
295 return sc;
296}
297
298/*
299 Base class version of this routine shouldn't really be called
300 since it doesn't correspond to a TDS object.
301*/
302StatusCode RootCalBaseCnv::i_createObj( const std::string& /* fname */,
303 DataObject*& /* refpObject */ ) {
304 return StatusCode::FAILURE; // shouldn't ever get here
305}
306
307// Default is to do nothing. Derived classes may override.
308StatusCode RootCalBaseCnv::i_processObj( DataObject*, // pObject,
309 IOpaqueAddress* ) /* address */ {
310 return StatusCode::SUCCESS;
311}
312
313/// Another utility for derived classes to use
315 MsgStream log( msgSvc(), "RootCalBaseCnv" );
316 log << MSG::DEBUG << "set the runfrm and runto Numbers in the converter" << endmsg;
317 pObj->setrunfrm( m_runfrm );
318 pObj->setrunto( m_runto );
319}
IMessageSvc * msgSvc()
virtual StatusCode i_createObj(const std::string &fname, DataObject *&refpObject)
virtual StatusCode createRoot(const std::string &fname, CalibData::CalibBase1 *pTDSObj)
StatusCode openRead(const std::string &fname)
IInstrumentName * m_instrSvc
virtual StatusCode i_processObj(DataObject *pObject, IOpaqueAddress *address)
In case there is additional work to do on the created object.
virtual StatusCode finalize()
StatusCode closeRead()
virtual StatusCode createObj(IOpaqueAddress *addr, DataObject *&refpObject)
virtual StatusCode readRootObj(const std::string &treename, const std::string &branch, TObject *&pCalib, unsigned index=0)
virtual StatusCode internalCreateObj(const std::string &fname, DataObject *&refpObject, IOpaqueAddress *address)
ICalibMetaCnvSvc * m_metaSvc
RootCalBaseCnv(ISvcLocator *svc, const CLID &clid)
StatusCode closeWrite()
virtual StatusCode initialize()
virtual StatusCode fillRoot(CalibData::CalibBase *pTDSObj, TObject *pRootObj)
TDirectory * m_saveDir
virtual ~RootCalBaseCnv()
ICalibRootSvc * m_rootSvc
virtual StatusCode openWrite(const std::string &fname)
void setBaseInfo(CalibData::CalibBase1 *pObj)
Another utility for derived classes to use.
static int expandEnvVar(std::string *toExpand, const std::string &openDel=std::string("$("), const std::string &closeDel=std::string(")"))
#define ix(i)