BOSS 7.0.3
BESIII Offline Software System
Loading...
Searching...
No Matches
RootEventBaseCnv.cxx
Go to the documentation of this file.
1#define _RootEventBaseCnv_CXX
2
3#include "TROOT.h"
4#include "TObject.h"
5#include "TClass.h"
6
7#include "GaudiKernel/IDataManagerSvc.h"
8#include "GaudiKernel/IService.h"
9#include "GaudiKernel/IEvtSelector.h"
10#include "GaudiKernel/ISvcLocator.h"
11#include "GaudiKernel/RegistryEntry.h"
12#include "GaudiKernel/MsgStream.h"
13#include "GaudiKernel/DataObject.h"
14#include "GaudiKernel/IConverter.h"
15#include "GaudiKernel/IAddressCreator.h"
16#include "GaudiKernel/SmartIF.h"
17
18
19#include "RootEventData/TDigiEvent.h"
20#include "RootCnvSvc/RootEvtSelector.h"
21#include "RootCnvSvc/RootEventBaseCnv.h"
22#include "RootCnvSvc/RootCnvSvc.h"
23#include "RootCnvSvc/RootAddress.h"
24
25extern const InterfaceID IID_IRootCnvSvc;
26
27using namespace DataSvcHelpers;
28
29RootEventBaseCnv::RootEventBaseCnv(const CLID& clid, ISvcLocator* svc)
30: Converter(ROOT_StorageType, clid, svc) ,m_cnvSvc(0),m_rootBranchname(""),m_rootTreename("Event"), m_evtsel(0)
31{
32
33 StatusCode sc;
34 MsgStream log(msgSvc(), "RootEventBaseCnv");
35
36 // Get DataSvc
37 IService* isvc = 0;
38 sc = serviceLocator()->getService("EventDataSvc", isvc, true);
39 if(sc.isSuccess() ) {
40 sc = isvc->queryInterface(IDataProviderSvc::interfaceID(), (void**)&m_eds);
41 }
42 if(sc.isFailure()){
43 log << MSG::ERROR << "Unable start EventData service within RootEventBaseCnv" << endreq;
44 }
45
47 if (!m_rootInterface) log << MSG::ERROR << "Unable to start Root interface within RootCnvSvc" << endreq;
48
49 ///////////////////// liangyt, try to get event id from evt selector ///////////////////////////////
50 //// the former method to retrieve the event number of one branch is to calculate///////////////////
51 //// division of branch number of one event (brN) and total readed branch num(entryN)///////////////
52 //// there are some disadvantages for this method. NOW, we try to get event id from evt selector////
53
54 sc = serviceLocator()->getService ("RootEvtSelector", isvc, false);
55 if (!sc.isSuccess()) sc = serviceLocator()->getService ("EventSelector", isvc, false);
56 if (sc.isSuccess()) {
57 sc = isvc->queryInterface(IID_IRootEvtSelector, (void**)&m_evtsel);
58 }
59 if(sc.isFailure()) {
60 log << MSG::WARNING << "Unable to start event selector service within RootCnvSvc" << endreq;
61 }
62 ////////////////////////
63
64
65 m_branchNr=-1;
67 m_branchNrMc=-1;
72 m_objRead=0;
73 CLID_top=0;
74 m_branchNumbers= new TArrayS(0);
75}
76
77
78StatusCode RootEventBaseCnv::createRep(DataObject* obj,
79 IOpaqueAddress*& addr) {
80 // Purpose and Method: Convert the transient object to ROOT
81
82 MsgStream log(msgSvc(), "RootEventBaseCnv");
83
84 StatusCode sc= StatusCode::SUCCESS;
85 // get the corresponding address
86 RootAddress *rootaddr;
87 sc=m_cnvSvc->createAddress(obj,addr);
88
89 rootaddr = dynamic_cast<RootAddress *>(addr);
90
91 if (sc.isFailure() || !rootaddr ) {
92 log << MSG::ERROR << "Could not create address for clid " <<obj->clID()<<", objname "<<obj->name()<<endreq;
93 return StatusCode::FAILURE;
94 }
95
96 // do the real conversion in the derived converter
97 sc = DataObjectToTObject(obj,rootaddr);
98
99 delete addr;
100 addr = NULL;
101
102 if (sc.isFailure()) {
103 log << MSG::ERROR << "Could not transform object" << endreq;
104 return sc;
105 }
106
107 return StatusCode::SUCCESS;
108}
109StatusCode RootEventBaseCnv::fillRepRefs(IOpaqueAddress* ,
110 DataObject* ) {
111 // Purpose and Method: Resolve the references of the converted object.
112 // It is expected that derived classes will override this method.
113 MsgStream log(msgSvc(), "RootEventBaseCnv");
114 return StatusCode::SUCCESS;
115}
116
117StatusCode RootEventBaseCnv::fillObjRefs(IOpaqueAddress* ,
118 DataObject* ) {
119 // Purpose and Method: Resolve the references of the converted object.
120 // It is expected that derived classes will override this method.
121 MsgStream log(msgSvc(), "RootEventBaseCnv");
122 return StatusCode::SUCCESS;
123}
124
125
127
128 StatusCode status = Converter::initialize();
129
130 if ( status.isSuccess() ) {
131 IService* isvc = 0;
132 status = serviceLocator()->service("RootCnvSvc", isvc, false);
133 if ( !status.isSuccess() ) status = serviceLocator()->service("EventCnvSvc", isvc, true);
134 if ( status.isSuccess() ) {
135 status = isvc->queryInterface(IID_IRootCnvSvc, (void**)&m_cnvSvc);
136 }
137 }
138
139 return status;
140}
141
143 if ( m_cnvSvc ) {
144 m_cnvSvc->release();
145 m_cnvSvc=0;
146 }
147 return Converter::finalize();
148}
149
150void RootEventBaseCnv::declareObject(const std::string& path, const CLID& cl,
151 const std::string& treename, const std::string& branchname) {
152 // Purpose and Method: Save the path on the TDS, treename, pathname in the m_leaves vector,
153 // corresponding to the DataObject that the converter handles.
154 m_leaves.push_back(RootCnvSvc::Leaf(path, cl,treename,branchname));
155}
156
157StatusCode RootEventBaseCnv::createObj(IOpaqueAddress* addr,
158 DataObject*& refpObject) {
159 // transform ROOT object to TDS object
160 MsgStream log(msgSvc(), "RootEventBaseCnv");
161 log << MSG::DEBUG << "RootEventBaseCnv::createObj with clid " <<addr->clID()<< endreq;
162 StatusCode sc;
163
164 // add 2005-11-29
165 // log<<MSG::INFO<<"######### RootEventBaseCnv ::createObj begin of createObj: m_branchNumbers "<<m_branchNumbers->GetSize()<<"###############"<<endreq;
166
167 RootAddress *raddr=dynamic_cast<RootAddress *>(addr);
168 if (!raddr) {
169 log << MSG::ERROR << "Could not downcast to Root address" << endreq;
170 return StatusCode::FAILURE;
171 }
172
173 static int temp =0; //control the begin of each files 2005-12-01
174 static int entryN =0; //control the event number of each files 2005-21-01
175 static int brN =0; //control munber of branch of the tree;
176 int lastBrn = brN;
177 //lastBrn = brN;
178 static int branchN=0;
179 static bool isSet=true;
180
181 static int entryBefore = 0;
182 static bool addEntryEachFile = true;
183
184
185 if(m_rootInterface->getENDFILE() || (temp >0 && temp < branchN)){ // if the file has get the end:y the go to next file to create a new tree
186
188 entryN = 0;
189 }
190
191 temp++;
192
193 delete m_branchNumbers;
194 m_branchNumbers = new TArrayS(0);
195
196 if(temp == branchN) {
197 temp =0;
198 }
199 }
200
201 if(m_rootInterface->getENDFILE()) addEntryEachFile = true;
202 // the 2nd method
203 if(m_evtsel->getRecId() - entryBefore == 0) { // first event in this file
204 delete m_branchNumbers;
205 m_branchNumbers = new TArrayS(0);
206 }
207
208 //new method to initialize the branchNumber
212 delete m_branchNumbers;
213 m_branchNumbers = new TArrayS(0);
214 }
215 //----------------------------------------
216
217 if (m_branchNumbers->GetSize()<=0) {
218 if(isSet) brN++;
219 int branchNumber;
220 for (int nb=0;nb<raddr->getNrBranches();nb++) {
221 sc=m_rootInterface->setBranchAddress(raddr->getTreename().c_str(),raddr->getBranchname(nb).c_str(),m_adresses[nb],branchNumber);
222 if (!sc.isSuccess())
223 {
224 if(isSet) brN--; //liangyt: if fail to retrieve this branch, this will be not a effective branch.
225 //entryN++; //liangyt: this is the second method
226 if(temp>0) temp--; //temp > 0 means recording effective branch number.
227 return sc;
228 }
229 m_branchNumbers->Set(nb+1);
230 m_branchNumbers->AddAt(branchNumber,nb);
231
232 }
233 }
234
235 //// after a file initialized, m_rootInterface get entries
236 if(addEntryEachFile&&(m_evtsel->getRecId()>entryBefore)){ // for a new file, add entry for ONLY one time.
237 entryBefore += m_rootInterface->getEntries();
238 addEntryEachFile = false;
239 }
240
241 if(lastBrn == brN && isSet ){
242 branchN = brN;
243 isSet=false;
244 }
245
246 if(isSet==false) log << MSG::INFO <<" 1st method set event as : "<<int(entryN/branchN)<<endreq;
247 if(isSet==false) raddr->setEntryNr(int(entryN/branchN));//former method, keep it to be backup.
248 if(m_evtsel) log << MSG::INFO <<" event id = "<<m_evtsel->getRecId()<<endreq;
249
250
251 int eventID = 0;
252 if(entryBefore > m_evtsel->getRecId())
253 eventID = m_evtsel->getRecId() + m_rootInterface->getEntries() - entryBefore;
254 else if(entryBefore == m_evtsel->getRecId()) eventID = 0;
255 else log << MSG::ERROR <<"eventId error!!!"<<endreq;
256
257 log << MSG::INFO <<" 2nd method set event as : "<<eventID<<endreq;
258
259 if(m_evtsel) raddr->setEntryNr(eventID);
260
261 //add dengzy
263 {
264 if(m_evtsel)
265 raddr->setEntryNr( m_evtsel->getRecId() );
266 }//end of add by dengzy
267
268 // read branch
269
270 if (m_branchNumbers->GetSize()>0) {
271 int nbtot=0,nb;
272 for (int ib=0;ib<m_branchNumbers->GetSize();ib++) {
273 //sc=m_rootInterface->getBranchEntry(m_branchNumbers->At(ib),raddr->getEntryNr(),nb);
274 //change to get branch entry with addr(set address for each entry) liangyt
276 if (sc.isFailure()) {
277 log << MSG::ERROR << "Could not read branch " << raddr->getBranchname(nb) << endreq;
278 return sc;
279 }
280 nbtot+=nb;
281 }
282 }
283
284 else { // get ROOT object
285 if (CLID_top) {
286 IConverter *p=conversionSvc()->converter(CLID_top);
287 RootEventBaseCnv *cnv=dynamic_cast<RootEventBaseCnv *>(p);
288 if (!cnv) {
289 log << MSG::ERROR << "Could not downcast to RootEventBaseCnv " << endreq;
290 return StatusCode::FAILURE;
291 }
293 }
294 }
295
296 //do concrete transformation in derived converter
297 sc = TObjectToDataObject(refpObject);
298 if (sc.isFailure()) {
299 log << MSG::ERROR << "Could not transform object" << endreq;
300 return sc;
301 }
302
303 // verify if we have to register
304 IRegistry* ent = addr->registry();
305 if ( ent == 0) {
306 sc=m_eds->registerObject(raddr->getPath(),refpObject);
307 if (sc.isFailure()) {
308 log << MSG::ERROR << "Could not register object " << raddr->getPath()<<" status "<<sc.getCode()<<endreq;
309 }
310 // }
311 }
312
313 entryN++;
314 return StatusCode::SUCCESS;
315}
const long int ROOT_StorageType
const InterfaceID IID_IRootCnvSvc
Definition of a Root address, derived from IOpaqueAddress.
std::string getBranchname(int i) const
Definition: RootAddress.cxx:31
object regrouping CLID and pathname with treename/branchname
virtual StatusCode createAddress(long int svc_type, const CLID &clid, const std::string *par, const unsigned long *ip, IOpaqueAddress *&refpAddress)
create address containing ROOT treename, branchname, entry number
Definition: RootCnvSvc.cxx:372
virtual StatusCode DataObjectToTObject(DataObject *dat, RootAddress *addr)=0
Do the concrete conversion from TDS to ROOT.
virtual StatusCode fillObjRefs(IOpaqueAddress *pAddress, DataObject *pObject)
Resolve the references of the converted object.
virtual StatusCode createObj(IOpaqueAddress *addr, DataObject *&dat)
Convert the persistent object to transient.
IDataProviderSvc * m_eds
pointer to eventdataservice
virtual StatusCode initialize()
TObject * getReadObject() const
get the object to be read
virtual StatusCode finalize()
std::vector< void * > m_adresses
each converter knows the corresponding adresses
TArrayS * m_branchNumbers
array with number of branches for reading
virtual StatusCode TObjectToDataObject(DataObject *&dat)=0
Do the concrete conversion from ROOT to TDS.
void declareObject(const std::string &fullPath, const CLID &clid, const std::string &treename, const std::string &branchname)
Store TDS path to link a particular converter to an object on the TDS.
int m_branchNr
the branchNr of this converter for writing
RootInterface * m_rootInterface
pointer to the RootInterface
virtual StatusCode fillRepRefs(IOpaqueAddress *pAddress, DataObject *pObject)
Resolve the references of the converted object.
RootEventBaseCnv(const CLID &clid, ISvcLocator *svc)
virtual StatusCode createRep(DataObject *pObject, IOpaqueAddress *&refpAddress)
Convert the transient object to the requested representation.
virtual StatusCode getBranchEntry(int nr, int entry, int &nb)
get entry from this branch
virtual StatusCode setBranchAddress(const std::string treename, const std::string branchname, void *addr, int &nb)
set branch address
static RootInterface * Instance(MsgStream log)
singleton behaviour