CGEM BOSS 6.6.5.g
BESIII Offline Software System
Loading...
Searching...
No Matches
digiRootWriterAlg.h
Go to the documentation of this file.
1#include "GaudiKernel/MsgStream.h"
2#include "GaudiKernel/AlgFactory.h"
3#include "GaudiKernel/IDataProviderSvc.h"
4#include "GaudiKernel/SmartDataPtr.h"
5#include "GaudiKernel/Algorithm.h"
6
7#include "EventModel/Event.h"
10#include "MdcRawEvent/MdcDigi.h"
12
13#include "RootCnvSvc/Util.h"
14
15#include "TROOT.h"
16#include "TFile.h"
17#include "TTree.h"
18#include "TDirectory.h"
19
20#include "DigiRootData/DigiEvent.h"
21
23
24#include "RootIO/IRootIoSvc.h"
25
26/** @class digiRootWriterAlg
27 * @brief Writes Digi TDS data to a persistent ROOT file.
28 * @Based on the digiRootWriterAlg of GLAST.
29 *
30 */
31
32class digiRootWriterAlg : public Algorithm
33{
34public:
35
36 digiRootWriterAlg(const std::string& name, ISvcLocator* pSvcLocator);
37
38 /// Handles setup by opening ROOT file in write mode and creating a new TTree
39 StatusCode initialize();
40
41 /// Orchastrates reading from TDS and writing to ROOT for each event
42 StatusCode execute();
43
44 /// Closes the ROOT file and cleans up
45 StatusCode finalize();
46
47private:
48
49 /// Retrieves event Id and run Id from TDS and fills the McEvent ROOT object
50 StatusCode writeDigiEvent();
51
52
53 /// Retrieves TKR digitization data from the TDS and fills the TkrDigi
54 /// ROOT collection
55 StatusCode writeMdcDigi();
56 StatusCode writeCgemDigi();
57
58 /// Calls TTree::Fill for each event and clears m_digiEvt
59 void writeEvent();
60 /// Performs the final write to the ROOT file and closes
61 void close();
62
63 /// ROOT file pointer
64 TFile *m_digiFile;
65 /// ROOT tree pointer
66 TTree *m_digiTree;
67 /// Top-level Monte Carlo ROOT object
68 DigiEvent *m_digiEvt;
69 /// name of the output ROOT file
70 std::string m_fileName;
71 /// name of the TTree in the ROOT file
72 std::string m_treeName;
73 /// ROOT split mode
74 int m_splitMode;
75 /// Buffer Size for the ROOT file
76 int m_bufSize;
77 /// Compression level for the ROOT file
78 int m_compressionLevel;
79 /// auto save every events
80 int m_autoSaveEvents;
81
82 commonData m_common;
83 IRootIoSvc* m_rootIoSvc;
84
85};
86
87static const AlgFactory<digiRootWriterAlg> Factory;
88const IAlgFactory& digiRootWriterAlgFactory = Factory;
89
90digiRootWriterAlg::digiRootWriterAlg(const std::string& name,
91 ISvcLocator* pSvcLocator) :
92Algorithm(name, pSvcLocator)
93{
94 // Input parameters available to be set via the jobOptions file
95 declareProperty("digiRootFile",m_fileName="digi.root");
96 declareProperty("splitMode", m_splitMode=1);
97 declareProperty("bufferSize", m_bufSize=64000);
98 declareProperty("compressionLevel", m_compressionLevel=1);
99 //declareProperty("treeName", m_treeName="Digi");
100 declareProperty("treeName", m_treeName="Rec"); //wensp modified on 20050515 for test
101 declareProperty("autoSave", m_autoSaveEvents=1000);
102
103}
104
106{
107 // Purpose and Method: Called once before the run begins. This method
108 // opens a new ROOT file and prepares for writing.
109
110 StatusCode sc = StatusCode::SUCCESS;
111 MsgStream log(msgSvc(), name());
112
113 // Use the Job options service to set the Algorithm's parameters
114 // This will retrieve parameters set in the job options file
115 setProperties();
116
117 if ( service("RootIoSvc", m_rootIoSvc, true).isFailure() ){
118 log << MSG::INFO << "Couldn't find the RootIoSvc!" << endreq;
119 log << MSG::INFO << "No Auto Saving" << endreq;
120 m_rootIoSvc = 0;
121 }
122
124
125 // Save the current directory for the ntuple writer service
126 TDirectory *saveDir = gDirectory;
127 // Create the new ROOT file
128 m_digiFile = new TFile(m_fileName.c_str(), "RECREATE");
129 if (!m_digiFile->IsOpen()) {
130 log << MSG::ERROR << "ROOT file " << m_fileName
131 << " could not be opened for writing." << endreq;
132 return StatusCode::FAILURE;
133 }
134 m_digiFile->cd();
135 m_digiFile->SetCompressionLevel(m_compressionLevel);
136 m_digiTree = new TTree(m_treeName.c_str(), "Bes Digitization Data");
137 m_digiEvt = new DigiEvent();
138 m_common.m_digiEvt = m_digiEvt;
139 m_digiTree->Branch("DigiEvent","DigiEvent", &m_digiEvt, m_bufSize, m_splitMode);
140 saveDir->cd();
141 return sc;
142
143}
144
146{
147 // Purpose and Method: Called once per event. This method calls
148 // the appropriate methods to read data from the TDS and write data
149 // to the ROOT file.
150
151 MsgStream log(msgSvc(), name());
152
153 StatusCode sc = StatusCode::SUCCESS;
154
155 if (!m_digiFile->IsOpen()) {
156 log << MSG::ERROR << "ROOT file " << m_fileName
157 << " could not be opened for writing." << endreq;
158 return StatusCode::FAILURE;
159 }
160
161 m_digiEvt->Clear();
162
163 sc = writeDigiEvent();
164 if (sc.isFailure()) {
165 log << MSG::ERROR << "Failed to write DigiEvent" << endreq;
166 return sc;
167 }
168
169
170 sc = writeMdcDigi();
171 if (sc.isFailure()) {
172 log << MSG::ERROR << "Failed to write Tkr Digi Collection" << endreq;
173 return sc;
174 }
175
176 sc = writeCgemDigi();
177 if (sc.isFailure()) {
178 log << MSG::ERROR << "Failed to write Cgem Tkr Digi Collection" << endreq;
179 return sc;
180 }
181
182 writeEvent();
183 return sc;
184}
185
186
187StatusCode digiRootWriterAlg::writeDigiEvent() {
188 // Purpose and Method: Retrieve the Event object from the TDS and set the
189 // event and run numbers in the DigiEvent ROOT object
190
191 MsgStream log(msgSvc(), name());
192 StatusCode sc = StatusCode::SUCCESS;
193
194 // Retrieve the Event data for this event
195 SmartDataPtr<Event::EventHeader> eventHeader(eventSvc(),"/Event");
196 if (!eventHeader) return sc;
197
198 Short_t runId = eventHeader->runNumber();
199 Short_t evtId = eventHeader->eventNumber();
200 Bool_t fromMc = true;
201
202
203 m_digiEvt->initialize(evtId, runId, fromMc);
204 // m_digiEvt->Print();
205
206 return sc;
207}
208
209StatusCode digiRootWriterAlg::writeMdcDigi() {
210 // Purpose and Method: Retrieve the TkrDigi collection from the TDS and set the
211 // TkrDigi ROOT collection
212
213 MsgStream log(msgSvc(), name());
214 StatusCode sc = StatusCode::SUCCESS;
215
216 SmartDataPtr<MdcDigiCol> mdcDigiColTds(eventSvc(), EventModel::Digi::MdcDigiCol);
217 if (!mdcDigiColTds) return sc;
218 MdcDigiCol::const_iterator mdcDigiTds;
219
220 for (mdcDigiTds = mdcDigiColTds->begin(); mdcDigiTds != mdcDigiColTds->end(); mdcDigiTds++) {
221 UInt_t overflow = (*mdcDigiTds)->getOverflow();
222 UInt_t time = (*mdcDigiTds)->getTimeChannel();
223 UInt_t charge = (*mdcDigiTds)->getChargeChannel();
224 UInt_t id = (*mdcDigiTds)->getIntId();
225 TMdcDigi *mdcDigiRoot = new TMdcDigi();
226 m_common.m_mdcDigiMap[(*mdcDigiTds)] = mdcDigiRoot;
227
228 mdcDigiRoot->initialize(id, time ,charge);
229 mdcDigiRoot->setOverflow(overflow);
230 m_digiEvt->addMdcDigi(mdcDigiRoot);
231// mdcDigiRoot->Print();
232 }
233
234 return sc;
235}
236
237StatusCode digiRootWriterAlg::writeCgemDigi() {
238 // Purpose and Method: Retrieve the TkrDigi collection from the TDS and set the
239 // TkrDigi ROOT collection
240
241 MsgStream log(msgSvc(), name());
242 StatusCode sc = StatusCode::SUCCESS;
243
244 SmartDataPtr<CgemDigiCol> cgemDigiColTds(eventSvc(), EventModel::Digi::CgemDigiCol);
245 if (!cgemDigiColTds) return sc;
246 CgemDigiCol::const_iterator cgemDigiTds;
247
248 for (cgemDigiTds = cgemDigiColTds->begin(); cgemDigiTds != cgemDigiColTds->end(); cgemDigiTds++) {
249 UInt_t overflow = (*cgemDigiTds)->getOverflow();
250 UInt_t time = (*cgemDigiTds)->getTimeChannel();
251 UInt_t charge = (*cgemDigiTds)->getChargeChannel();
252 UInt_t idMSB = (*cgemDigiTds)->getIntIdMSB();
253 UInt_t idLSB = (*cgemDigiTds)->getIntIdLSB();
254 TCgemDigi *cgemDigiRoot = new TCgemDigi();
255 m_common.m_cgemDigiMap[(*cgemDigiTds)] = cgemDigiRoot;
256
257 cgemDigiRoot->initialize(idMSB, idLSB, time ,charge);
258 cgemDigiRoot->setOverflow(overflow);
259 m_digiEvt->addCgemDigi(cgemDigiRoot);
260// cgemDigiRoot->Print();
261 }
262
263 return sc;
264}
265
266void digiRootWriterAlg::writeEvent()
267{
268 // Purpose and Method: Stores the DigiEvent data for this event in the ROOT
269 // tree. The m_digiEvt object is cleared for the next event.
270 static int eventCounter = 0;
271 TDirectory *saveDir = gDirectory;
272 m_digiTree->GetCurrentFile()->cd();
273 //m_digiFile->cd();
274 m_digiTree->Fill();
275 //m_digiEvt->Clear();
276 saveDir->cd();
277 ++eventCounter;
278 if (m_rootIoSvc)
279 if (eventCounter % m_rootIoSvc->getAutoSaveInterval() == 0) m_digiTree->AutoSave();
280
281 return;
282}
283
284void digiRootWriterAlg::close()
285{
286 // Purpose and Method: Writes the ROOT file at the end of the run.
287 // The TObject::kWriteDelete parameter is used in the Write method
288 // replacing TObject::kOverwrite - supposed to be safer
289 // since ROOT will periodically write to the ROOT file when the bufSize
290 // is filled. Writing would create 2 copies of the same tree to be
291 // stored in the ROOT file, if we did not specify kOverwrite.
292
293 TDirectory *saveDir = gDirectory;
294 TFile *f = m_digiTree->GetCurrentFile();
295 //m_digiFile->cd();
296 f->cd();
297 m_digiTree->BuildIndex("m_runId", "m_eventId");
298 f->Write(0, TObject::kWriteDelete);
299 f->Close();
300 saveDir->cd();
301 return;
302}
303
305{
306 close();
307
308 StatusCode sc = StatusCode::SUCCESS;
309 return sc;
310}
311
Double_t time
definition of the interface for IRootIoSvc
IMessageSvc * msgSvc()
void initialize(bool fromMc)
Definition: DigiEvent.h:30
The RootIoSvc gaudi service interface.
Definition: IRootIoSvc.h:23
virtual int getAutoSaveInterval()=0
void setOverflow(const UInt_t overflow)
Definition: TCgemDigi.cxx:39
void setOverflow(const UInt_t overflow)
Definition: TMdcDigi.cxx:36
void initialize(UInt_t id, UInt_t time=0, UInt_t charge=0)
Definition: TRawData.cxx:34
static std::map< const CgemDigi *, TRef > m_cgemDigiMap
Definition: commonData.h:141
static std::map< const MdcDigi *, TRef > m_mdcDigiMap
Create a set of maps between Digi data in the TDS and the TRefs in the ROOT file.
Definition: commonData.h:140
Writes Digi TDS data to a persistent ROOT file. @Based on the digiRootWriterAlg of GLAST.
StatusCode initialize()
Handles setup by opening ROOT file in write mode and creating a new TTree.
StatusCode execute()
Orchastrates reading from TDS and writing to ROOT for each event.
digiRootWriterAlg(const std::string &name, ISvcLocator *pSvcLocator)
StatusCode finalize()
Closes the ROOT file and cleans up.
static int expandEnvVar(std::string *toExpand, const std::string &openDel=std::string("$("), const std::string &closeDel=std::string(")"))
const IAlgFactory & digiRootWriterAlgFactory
_EXTERN_ std::string MdcDigiCol
Definition: EventModel.h:61
_EXTERN_ std::string CgemDigiCol
Definition: EventModel.h:67