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