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