KaliVeda
Toolkit for HIC analysis
KVSimReader.cpp
1 //Created by KVClassFactory on Wed Jun 30 17:45:01 2010
2 //Author: bonnet
3 
4 #include "KVSimReader.h"
5 #include "TDirectory.h"
6 #include "TStopwatch.h"
7 
8 ClassImp(KVSimReader)
9 
10 
11 
14  : evt{new KVSimEvent}
15 {
16  linked_info.SetName("Simulation info");
17  linked_objects.SetName("List of objects");
18 }
19 
20 
21 
23 
25 {
26  if (!OpenFileToRead(filename)) return;
27  if(!ReadFileHeader())
28  {
29  KVError::Error(this,"ReadFileHeader","Error reading the file header");
30  return;
31  }
32  Run();
33  CloseFile();
34 }
35 
36 
37 
58 
60 {
61  // The usual loop for reading, converting and saving events is
62  //
63  //~~~{.cpp}
64  // ReadEventHeader();
65  // ReadEvent();
66  // FillTree();
67  //~~~
68  //
69  // If several separate events share the same header and need to be read
70  // sequentially, this can be achieved if this method is overriden to return true
71  // as many times as needed, by adding this effective loop:
72  //
73  //~~~{.cpp}
74  // ReadEventHeader();
75  // do {
76  // ReadEvent();
77  // FillTree();
78  // } while( NeedToIterateEvents() );
79  //~~~
80  return false;
81 }
82 
83 
84 
96 
97 void KVSimReader::InitializeOutputFileAndTree()
98 {
99  // Create a new TFile containing a TTree with a branch for storing KVSimEvent objects
100  //
101  // The file will be written in the directory given to SetOutputDirectory() (local working directory if not).
102  //
103  // ROOT files and TTrees will be generated with names/titles according to the values which can be set with:
104  //
105  // + SetTreeName()
106  // + SetTreeTitle()
107  // + SetROOTFileName()
108  // + SetBranchName()
109 
110 
111  auto filename = GetCurrentRootFileName();
112  if (!fOutputDirectory.EndsWith("/")) fOutputDirectory += "/";
113  filename.Prepend(fOutputDirectory);
114  file = new TFile(filename, "recreate");
115  KVError::Info(this, "InitializeOutputFileAndTree", "Opened output file: %s", filename.Data());
116 
117  tree = new TTree(tree_name, tree_title);
118  KVEvent::MakeEventBranch(tree, branch_name, evt);
119 }
120 
121 
122 
125 
126 void KVSimReader::ReadEventsInFile()
127 {
128  // Method driving the main loop to read and convert all events in file
129 
130  total_nevents=total_nevents_current_output_file=0;
131  while (IsOK()) {
132  if (ReadEventHeader(evt))
133  {
134  bool ok = true;
135  do {
136  if((ok = ReadEvent(evt)))
137  {
138  ++total_nevents;
139  if(NeedNewOutputFile())
140  {
142  InitializeOutputFileAndTree();
143  total_nevents_current_output_file=0;
144  }
145  ++total_nevents_current_output_file;
146  FillTree();
147  if(OutputFileIsFull())
148  {
149  SaveTree();
150  }
151  evt->Clear();
152  }
153  else
154  break;
155  } while(ok && NeedToIterateReadEvent());
156  }
157  else
158  break;
159  }
160 }
161 
162 
163 
176 
178 {
179  // Implement as needed to read informations at the beginning of the input file, if present.
180  //
181  // Such informations may be used in ReadFileHeader() to set the names of output files/TTrees,
182  // using the methods
183  //
184  // + SetTreeName()
185  // + SetTreeTitle()
186  // + SetROOTFileName()
187  // + SetBranchName()
188  //
189  // \returns true unless there is a problem reading the header (inconsistent file structure, end of file, etc.)
190  return true;
191 }
192 
193 
194 
201 
203 {
204  // Implement as needed to read informations present at the beginning of each new event, if present.
205  //
206  // There is no need to call KVSimEvent::Clear(): the event object will be ready to be filled with new informations.
207  //
208  // \returns true unless there is a problem reading the header (inconsistent file structure, end of file, etc.)
209  return true;
210 }
211 
212 
213 
218 
220 {
221  // If required, this method can be implemented in child classes, to be used in ReadEvent().
222  // As the implementation of ReadEvent() is the user's responsibility, the meaning of the returned
223  // bool value is also up to the user.
224  return true;
225 }
226 
227 
228 
235 
237 {
238  // This method will be called just before initialising a new output file during
239  // conversion of events (note that the previous file will already have been written to
240  // disk and closed at this point).
241  //
242  // It can be overridden in child classes if necessary, e.g. to reset histograms or other statistics.
243 }
244 
245 
246 
248 
249 TString KVSimReader::GetCurrentRootFileName()
250 {
251  TString filename;
252  filename = root_file_name;
253  if (fMultiFiles) filename += Form(".%d", fFileIndex);
254  if(max_number_events_per_output_file)
255  filename += Form(".%d", current_output_file_index++);
256  filename += ".root";
257  return filename;
258 }
259 
260 
261 
264 
266 {
267  // Read events, convert and save in ROOT file(s)
268  ConvertEventsInFile(filename);
269  if(!NeedNewOutputFile())
270  SaveTree();
271 }
272 
273 
274 
277 
279 {
280  // Returns an instance of a child class specific to given model.
281 
282  TPluginHandler* ph = LoadPlugin("KVSimReader", model_uri);
283  if (!ph) {
284  ::Error("KVSimReader::MakeSimReader", "No plugin defined with name %s", model_uri);
285  return nullptr;
286  }
287  return (KVSimReader*)ph->ExecPlugin(0);
288 }
289 
290 
291 
293 
294 void KVSimReader::Run()
295 {
296 
297  AddInfo({"ascii file read", GetFileName()});
298 
299  TStopwatch chrono;
300  chrono.Start();
301 
302  InitializeOutputFileAndTree();
303 
304  ReadEventsInFile();
305 
306  chrono.Stop();
307 
308  AddInfo({"date", GetDate()});
309  AddInfo({"user", gSystem->GetUserInfo()->fUser});
310 
311 }
312 
313 
314 
316 
317 void KVSimReader::SaveTree()
318 {
319  WriteObjects();
320  WriteInfo();
321  GetTree()->Write();
322  KVError::Info(this, "SaveTree", "Writing %d events in file : %s", total_nevents_current_output_file, file->GetName());
323  file->Close();
324  file = nullptr;
325 }
326 
327 
328 
330 
331 KVSeqCollection* KVSimReader::GetSimuInfo()
332 {
333  return &linked_info;
334 }
335 
336 
337 
347 
348 void KVSimReader::AddInfo(const KVNamedParameter& info)
349 {
350  // Add information on simulation using KVNamedParameter, can be int, double, bool or string:
351  //~~~{.cpp}
352  // AddInfo({"model", "AMD"});
353  // AddInfo({"sigma_NN_screen_factor", 0.85});
354  // AddInfo({"N_part_test", 150});
355  //~~~
356  // This information will be written to disk with the TTree and can be retrieved
357  // using TTree::GetUserInfo().
358  linked_info.Add(new KVNamedParameter(info));
359 }
360 
361 
362 
364 
365 void KVSimReader::WriteInfo()
366 {
367  TList* list = GetTree()->GetUserInfo();
368  Int_t nentries = linked_info.GetEntries();
369  for (Int_t ii = 0; ii < nentries; ii += 1) {
370  // copy informations to TTree user info list
371  list->Add(new KVNamedParameter(*static_cast<KVNamedParameter*>(linked_info.At(ii))));
372  }
373 }
374 
375 
376 
378 
379 KVSeqCollection* KVSimReader::GetLinkedObjects()
380 {
381  return &linked_objects;
382 }
383 
384 
385 
390 
391 void KVSimReader::AddObject(TObject* obj)
392 {
393  // Adds an object to a list which will be written to disk with the TTree.
394  //
395  // These objects can be retrieved from the list returned by TTree::GetUserInfo().
396  GetLinkedObjects()->Add(obj);
397 }
398 
399 
400 
402 
403 void KVSimReader::WriteObjects()
404 {
405 
406  TList* list = GetTree()->GetUserInfo();
407  Int_t nentries = linked_objects.GetEntries();
408  for (Int_t ii = 0; ii < nentries; ii += 1)
409  {
410  list->Add(linked_objects.At(ii));
411  }
412 
413 }
414 
415 
static TPluginHandler * LoadPlugin(const Char_t *base, const Char_t *uri="0")
Definition: KVBase.cpp:795
static void MakeEventBranch(TTree *tree, const TString &branchname, T &event, Int_t bufsize=10000000)
Definition: KVEvent.h:211
void Clear(Option_t *opt="") override
Definition: KVEvent.h:239
KVString GetFileName()
Definition: KVFileReader.h:190
void CloseFile()
Definition: KVFileReader.h:237
Bool_t IsOK()
Definition: KVFileReader.h:231
Bool_t OpenFileToRead(const KVString &filename)
Definition: KVFileReader.h:210
A generic named parameter storing values of different types.
KaliVeda extensions to ROOT collection classes.
void Add(TObject *obj) override
TObject * At(Int_t idx) const override
Container class for simulated nuclei, KVSimNucleus.
Definition: KVSimEvent.h:22
Nucleus in a simulated event.
Definition: KVSimNucleus.h:32
Base class to convert output from different simulation codes into TTrees containing KVSimEvent event ...
Definition: KVSimReader.h:117
virtual Bool_t ReadEventHeader(KVSimEvent *)
virtual Bool_t ReadNucleus(KVSimNucleus *)
virtual Bool_t ReadFileHeader()
static KVSimReader * MakeSimReader(const char *model_uri)
Returns an instance of a child class specific to given model.
virtual void NotifyChangeOfOutputFile()
void ConvertEventsInFile(KVString filename)
Definition: KVSimReader.cpp:24
virtual Bool_t ReadEvent(KVSimEvent *evt)=0
void ConvertAndSaveEventsInFile(KVString filename)
Read events, convert and save in ROOT file(s)
virtual bool NeedToIterateReadEvent()
Definition: KVSimReader.cpp:59
Extension of ROOT TString class which allows backwards compatibility with ROOT v3....
Definition: KVString.h:73
void Error(UserClass p, const char *location, const char *va_(fmt),...)
Definition: KVError.h:116
void Info(UserClass p, const char *location, const char *va_(fmt),...)
Definition: KVError.h:134