KaliVeda
Toolkit for HIC analysis
KVINDRAReconDataAnalyser.cpp
1 /*
2 $Id: KVINDRAReconDataAnalyser.cpp,v 1.4 2007/11/15 14:59:45 franklan Exp $
3 $Revision: 1.4 $
4 $Date: 2007/11/15 14:59:45 $
5 */
6 
7 //Created by KVClassFactory on Wed Apr 5 23:50:04 2006
8 //Author: John Frankland
9 
10 #include "KVBase.h"
11 #include "KVINDRAReconDataAnalyser.h"
12 #include "KVINDRADBRun.h"
13 #include "KVINDRADB.h"
14 #include "KVDataAnalysisTask.h"
15 #include "KVDataSet.h"
16 #include "TChain.h"
17 #include "TObjString.h"
18 #include "TChain.h"
19 #include "KVAvailableRunsFile.h"
20 #include "KVINDRA.h"
21 #ifdef WITH_PROOF
22 #include "TProof.h"
23 #endif
24 #include "KVINDRATriggerConditions.h"
25 #include "KVINDRAEventSelector.h"
26 
27 #include <KVReconEventSelector.h>
28 
29 using namespace std;
30 
32 
33 
34 
37  : fSelector(nullptr), fOldSelector(nullptr), theChain(nullptr),
38  theRawData(nullptr), theGeneData(nullptr),
39  ParVal(nullptr), ParNum(nullptr), parList(nullptr)
40 {
41 }
42 
43 
44 
47 
49 {
50  //Reset task variables
52  theChain = nullptr;
53  theRawData = nullptr;
54  theGeneData = nullptr;
55  ParVal = nullptr;
56  ParNum = nullptr;
57  fSelector = nullptr;
58  fOldSelector = nullptr;
59  TotalEntriesToRead = 0;
60 }
61 
62 
63 
64 
65 
66 
69 
71 {
72  // Checks the task variables
73 
75 
76  cout << "============> Analysis summary <=============" << endl;
77  cout << "Analysis of runs " << GetRunList().
78  GetList() << " with the class ";
79  cout << "\"" << GetUserClassName() << "\"." << endl;
80  if (GetNbEventToRead()) {
81  cout << GetNbEventToRead() << " events will be processed." << endl;
82  }
83  else {
84  cout << "All events will be processed." << endl;
85  }
86  cout << "=============================================" << endl;
87 
88  return kTRUE;
89 }
90 
91 
92 
93 
98 
100 {
101  //Run the interactive analysis
102 
103  //make the chosen dataset the active dataset ( = gDataSet; note this also opens database
104  //and positions gDataBase & gIndraDB).
105  GetDataSet()->cd();
106  fSelector = nullptr;
107  fOldSelector = nullptr;
108 
109  theChain = new TChain("ReconstructedEvents");
110  theChain->SetDirectory(0); // we handle delete
111 
112  // open and add to TChain all required files
113  // we force the opening of the files to avoid problems with xrootd which sometimes
114  // seems to have a little difficulty
115  for (auto& run : GetRunList()) {
116  TString fullPathToRunfile = gDataSet->GetFullPathToRunfile(GetDataType(), run);
117  cout << "Opening file " << fullPathToRunfile << endl;
118  TFile* f = gDataSet->OpenRunfile<TFile>(GetDataType(), run);
119  cout << "Adding file " << fullPathToRunfile;
120  cout << " to the TChain." << endl;
121  dynamic_cast<TChain*>(theChain)->Add(fullPathToRunfile);
122  if (f && !f->IsZombie()) {
123  // update run infos in available runs file if necessary
125  if (ARF->InfosNeedUpdate(run, gSystem->BaseName(fullPathToRunfile))) {
126  if (!((TTree*)f->Get("ReconstructedEvents"))) {
127  KVError::Error(this, "SubmitTask", "No tree named ReconstructedEvents is present in the current file");
128  delete theChain;
129  return;
130  }
131  TEnv* treeInfos = (TEnv*)((TTree*)f->Get("ReconstructedEvents"))->GetUserInfo()->FindObject("TEnv");
132  if (treeInfos) {
133  TString kvversion = treeInfos->GetValue("KVBase::GetKVVersion()", "");
134  TString username = treeInfos->GetValue("gSystem->GetUserInfo()->fUser", "");
135  if (kvversion != "") ARF->UpdateInfos(run, gSystem->BaseName(fullPathToRunfile), kvversion, username);
136  }
137  else {
138  Info("SubmitTask", "No TEnv object associated to the tree");
139  }
140  }
141  }
142  }
143  TotalEntriesToRead = theChain->GetEntries();
144  TString option("");
145 
146  // Add the total run list in option
147  if (!(option.IsNull())) option += ",";
148  option += Form("FullRunList=%s", GetFullRunList().GetList().Data());
149 
150  // Add any user-defined options
151  if (GetUserClassOptions() != "") {
152  option += ",";
153  option += GetUserClassOptions();
154  }
155 
156  set_up_analyser_for_task(this);
157 
158  // for backwards compatibility, we allow user class to inherit from
159  // KVOldINDRASelector instead of KVINDRAEventSelector
160  // for forwards compatibility, we allow it to inherit from KVReconEventSelector too!
161  TObject* new_selector = GetInstanceOfUserClass("KVOldINDRASelector,KVReconEventSelector");
162 
163  if (!new_selector || !new_selector->InheritsFrom("TSelector")) {
164  cout << "The selector \"" << GetUserClassName() << "\" is not valid." << endl;
165  cout << "Process aborted." << endl;
166  SafeDelete(new_selector);
167  }
168  else {
169  SafeDelete(new_selector);
170  Info("SubmitTask", "Beginning TChain::Process...");
171 #ifdef WITH_PROOF
172 #ifdef WITH_CPP11
173  if (GetProofMode() != KVDataAnalyser::EProofMode::None) dynamic_cast<TChain*>(theChain)->SetProof(kTRUE);
174 #else
175  if (GetProofMode() != KVDataAnalyser::None) dynamic_cast<TChain*>(theChain)->SetProof(kTRUE);
176 #endif
177 #endif
178  TString analysis_class;
179  if (GetAnalysisTask()->WithUserClass()) analysis_class.Form("%s%s", GetUserClass().full_path_imp().Data(), GetACliCMode());
180  else analysis_class = GetUserClassName();
181 
182  if (GetNbEventToRead()) {
183  theChain->Process(analysis_class, option.Data(), GetNbEventToRead());
184  }
185  else {
186  theChain->Process(analysis_class, option.Data());
187  }
188  }
189  delete theChain;
190  fSelector = nullptr; //deleted by TChain/TTreePlayer
191  fOldSelector = nullptr; //deleted by TChain/TTreePlayer
192 }
193 
194 
195 
196 
202 
204 {
205  //Save (in the TEnv fBatchEnv) all necessary information on analysis task which can be used to execute it later
206  //(i.e. when batch processing system executes the job).
207  //If save=kTRUE (default), write the information in a file whose name is given by ".jobname"
208  //where 'jobname' is the name of the job as given to the batch system.
209 
211  // backwards-compatible fix for old KVSelector analysis classes
212  // for forwards compatibility, we allow it to inherit from KVReconEventSelector too!
213  GetBatchInfoFile()->SetValue("UserClassAlternativeBaseClass", "KVOldINDRASelector,KVReconEventSelector");
214  if (save) GetBatchInfoFile()->SaveLevel(kEnvUser);
215 }
216 
217 
218 
219 
229 
231 {
232  // Called by currently-processed KVEventSelector before user's InitAnalysis() method.
233  // We build the multidetector for the current dataset in case informations on
234  // detector are needed e.g. to define histograms in InitAnalysis().
235  // Note that at this stage we are not analysing a given run, so the parameters
236  // of the array are not set (they will be set in preInitRun()).
237  //
238  // Note for PROOF: as this will be called both on master and on slave workers,
239  // in order to reduce memory footprint we only build INDRA on the slaves
240 
241 #ifdef WITH_PROOF
242  if (!gProof || !gProof->IsMaster())
243 #endif
244  if (!gIndra) KVMultiDetArray::MakeMultiDetector(GetDataSet()->GetName());
245 
246  // in case data is being analysed with a "vanilla" KVReconEventSelector, we need
247  // to set the correct branch name for reconstructed INDRA data which is "INDRAReconEvent"
248  // instead of the default "ReconEvent"
249  if (fSelector) fSelector->SetBranchName("INDRAReconEvent");
250  else KVError::Warning(this, "preInitAnalysis", "could not set branch name correctly");
251 }
252 
253 
254 
256 
258 {
259  if (fSelector) {
260  if (fSelector->InheritsFrom("KVINDRAEventSelector"))
261  dynamic_cast<KVINDRAEventSelector*>(fSelector)->SetCurrentRun(CurrentRun);
262  // WARNING - horrible kludge...
263  else if (fSelector->InheritsFrom("KVReconEventSelector"))
264  dynamic_cast<KVReconEventSelector*>(fSelector)->SetCurrentRun(CurrentRun);
265  }
266  else {
267  fOldSelector->SetCurrentRun(CurrentRun);
268  }
269 }
270 
271 
272 
288 
290 {
291  // Called by currently-processed TSelector when a new file in the TChain is opened.
292  // We call gIndra->SetParameters for the current run: whether only physics parameters will be set,
293  // or the full set of identification/calibration parameters depends on the value of the
294  // environment variable
295  //~~~
296  // [dataset].ReconAnalysis.WithCalibInfos: [yes/no]
297  //~~~
298  //This can be overridden for any individual analysis by setting the analysis class option
299  //~~~~
300  // WithCalibInfos=yes
301  //~~~~
302  // We connect the acquisition parameter objects to the branches of the raw data tree.
303  // Infos on currently read file/tree are printed.
304  // Any required data patches ("rustines") are initialized.
305 
306  Bool_t physics_parameters_only = !gDataSet->GetDataSetEnv("ReconAnalysis.WithCalibInfos", kTRUE);
307  if (fSelector->IsOptGiven("WithCalibInfos"))
308  physics_parameters_only = (fSelector->GetOpt("WithCalibInfos") != "yes");
309 
310  Int_t run = gDataSet->GetRunNumberFromFileName(GetDataType(), theChain->GetCurrentFile()->GetName()).value().run();
311  gIndra->SetParameters(run, physics_parameters_only);
312  KVINDRADBRun* CurrentRun = gIndraDB->GetRun(run);
313  SetCurrentRun(CurrentRun);
314  SetSelectorCurrentRun(CurrentRun);
315  cout << endl << " =================== New Run =================== " <<
316  endl << endl;
317 
318  CurrentRun->Print();
319  if (CurrentRun->GetSystem()) {
320  SetSystem(CurrentRun->GetSystem());
321  if (CurrentRun->GetSystem()->GetKinematics())
322  CurrentRun->GetSystem()->GetKinematics()->Print();
323  }
324 
325  cout << endl << " ================================================= " <<
326  endl << endl;
327 
328  ConnectRawDataTree();
329  ConnectGeneDataTree();
330  PrintTreeInfos();
331  Info("preInitRun", "Data written with series %s, release %d", GetDataSeries().Data(),
332  GetDataReleaseNumber());
333  fRustines.InitializePatchList(GetDataSet()->GetName(), GetDataType(), run, GetDataSeries(),
334  GetDataReleaseNumber(), theChain->GetCurrentFile()->GetStreamerInfoCache());
335  fRustines.Print();
336 }
337 
338 
339 
341 
343 {
344  Long64_t rawEntry = (fSelector ? fSelector->GetEventNumber() - 1
345  : fOldSelector->GetEventNumber() - 1);
346 
347  return rawEntry;
348 }
349 
350 
351 
353 
355 {
356  return (fSelector ? dynamic_cast<KVReconstructedEvent*>(fSelector->GetEvent()) : fOldSelector->GetEvent());
357 }
358 
359 
360 #ifdef USING_ROOT6
361 
363 
365 {
367  trig.SetTriggerConditionsForRun(fSelector, run);
368 }
369 
370 #endif
371 
372 
377 
379 {
380  // Read and set raw data for the current reconstructed event
381  //
382  // Any required data patches ("rustines") are applied.
383 
384  if (!theRawData) return;
385  // all recon events are numbered 1, 2, ... : therefore entry number is N-1
386  Long64_t rawEntry = GetRawEntryNumber();
387  theRawData->GetEntry(rawEntry);
389  for (int i = 0; i < NbParFired; i++)
390  gIndra->handle_ebyedat_raw_data_parameter((*parList)[ParNum[i]]->GetName(), ParVal[i]);
391 
392  KVINDRAReconEvent* event = (KVINDRAReconEvent*)GetReconstructedEvent();
393  // randomization of particle angles is no longer applied in the KVReconstructedEvent::Streamer
394  // and the momentum vectors as written on disk are used. For old INDRA converted DST data
395  // this seems to not be enough: therefore we randomize here (unless mean angles are explicitly requested)
396  if(event->HasRandomAngles())
397  for(auto& nuc : ReconEventIterator(event))
398  nuc.GetAnglesFromReconstructionTrajectory("random");
399 
400  // as rustines often depend on a knowledge of the original raw data,
401  // we apply them after it has been read in
402  if (fRustines.HasActivePatches()) fRustines.Apply(event);
403 }
404 
405 
406 
413 
414 void KVINDRAReconDataAnalyser::ConnectRawDataTree()
415 {
416  // Called by preInitRun().
417  // When starting to read a new run (=new file), we look for the TTree "RawData" in the
418  // current file (it should have been created by KVINDRARawDataReconstructor).
419  // If found, it will be used by ReadRawData() to set the values of all acquisition parameters
420  // for each event.
421 
422  theRawData = (TTree*)theChain->GetCurrentFile()->Get("RawData");
423  if (!theRawData) {
424  KVError::Warning(this, "ConnectRawDataTree", "RawData tree not found in file; raw data parameters of detectors will not be available in analysis");
425  return;
426  }
427  else
428  Info("ConnectRawDataTree", "Found RawData tree in file");
429  Int_t maxNopar = theRawData->GetMaximum("NbParFired");
430  if (ParVal) delete [] ParVal;
431  if (ParNum) delete [] ParNum;
432  ParVal = new UShort_t[maxNopar];
433  ParNum = new UInt_t[maxNopar];
434  parList = (TObjArray*)theRawData->GetUserInfo()->FindObject("ParameterList");
435  theRawData->SetBranchAddress("NbParFired", &NbParFired);
436  theRawData->SetBranchAddress("ParNum", ParNum);
437  theRawData->SetBranchAddress("ParVal", ParVal);
438  Info("ConnectRawDataTree", "Connected raw data parameters");
439  Entry = 0;
440 }
441 
442 
443 
448 
449 void KVINDRAReconDataAnalyser::ConnectGeneDataTree()
450 {
451  // Called by preInitRun().
452  // When starting to read a new run (=new file), we look for the TTree "GeneData" in the
453  // current file (it should have been created by KVINDRARawDataReconstructor).
454 
455  theGeneData = (TTree*)theChain->GetCurrentFile()->Get("GeneData");
456  if (!theGeneData) {
457  cout << " --> No pulser & laser data for this run !!!" << endl << endl;
458  }
459  else {
460  cout << " --> Pulser & laser data tree contains " << theGeneData->GetEntries()
461  << " events" << endl << endl;
462  }
463 }
464 
465 
466 
468 
470 {
471  return (TEnv*)theChain->GetTree()->GetUserInfo()->FindObject("TEnv");
472 }
473 
474 
475 
478 
480 {
481  // Print informations on currently analysed TTree
482  TEnv* treeInfos = GetReconDataTreeInfos();
483  if (!treeInfos) return;
484  cout << endl << "----------------------------------------------------------------------------------------------------" << endl;
485  cout << "INFORMATIONS ON VERSION OF KALIVEDA USED TO GENERATE FILE:" << endl << endl;
486  fDataVersion = treeInfos->GetValue("KVBase::GetKVVersion()", "(unknown)");
487  cout << "version = " << fDataVersion << endl ;
488  cout << "build date = " << treeInfos->GetValue("KVBase::GetKVBuildDate()", "(unknown)") << endl ;
489  cout << "source directory = " << treeInfos->GetValue("KVBase::GetKVSourceDir()", "(unknown)") << endl ;
490  cout << "KVROOT = " << treeInfos->GetValue("KVBase::GetKVRoot()", "(unknown)") << endl ;
491  cout << "BZR branch name = " << treeInfos->GetValue("KVBase::bzrBranchNick()", "(unknown)") << endl ;
492  cout << "BZR revision #" << treeInfos->GetValue("KVBase::bzrRevisionNumber()", "(unknown)") << endl ;
493  cout << "BZR revision ID = " << treeInfos->GetValue("KVBase::bzrRevisionId()", "(unknown)") << endl ;
494  cout << "BZR revision date = " << treeInfos->GetValue("KVBase::bzrRevisionDate()", "(unknown)") << endl ;
495  cout << endl << "INFORMATIONS ON GENERATION OF FILE:" << endl << endl;
496  cout << "Generated by : " << treeInfos->GetValue("gSystem->GetUserInfo()->fUser", "(unknown)") << endl ;
497  cout << "Analysis task : " << treeInfos->GetValue("AnalysisTask", "(unknown)") << endl ;
498  cout << "Job name : " << treeInfos->GetValue("BatchSystem.JobName", "(unknown)") << endl ;
499  cout << "Job submitted from : " << treeInfos->GetValue("LaunchDirectory", "(unknown)") << endl ;
500  cout << "Runs : " << treeInfos->GetValue("Runs", "(unknown)") << endl ;
501  cout << "Number of events requested : " << treeInfos->GetValue("NbToRead", "(unknown)") << endl ;
502  cout << endl << "----------------------------------------------------------------------------------------------------" << endl;
503 
504  // if possible, parse fDataVersion into series and release number
505  // e.g. if fDataVersion = "1.8.10":
506  // => fDataSeries = "1.8" fDataReleaseNum = 10
507  Int_t a, b, c;
508  if (fDataVersion != "(unknown)") {
509  if (sscanf(fDataVersion.Data(), "%d.%d.%d", &a, &b, &c) == 3) {
510  fDataSeries.Form("%d.%d", a, b);
511  fDataReleaseNum = c;
512  }
513  }
514  else {
515  fDataSeries = "";
516  fDataReleaseNum = -1;
517  }
518 }
519 
520 
521 
523 
525 {
526  if (theRawData) theRawData->CloneTree(-1, "fast"); //copy raw data tree to file
527  if (theGeneData) theGeneData->CloneTree(-1, "fast"); //copy pulser & laser (gene) tree to file
528 }
529 
530 
531 
538 
540 {
541  // Overrides KVDataAnalyser method, for backwards & forwards compatibility.
542  //
543  // Old user analysis classes may derive from KVOldINDRASelector (aka KVSelector) instead of KVINDRAEventSelector.
544  //
545  // It is also possible to analyse data with a "vanilla" KVReconEventSelector analysis class.
546  return KVDataAnalyser::CheckIfUserClassIsValid("KVOldINDRASelector,KVReconEventSelector");
547 }
548 
549 
int Int_t
unsigned int UInt_t
#define SafeDelete(p)
#define f(i)
#define c(i)
bool Bool_t
unsigned short UShort_t
constexpr Bool_t kFALSE
constexpr Bool_t kTRUE
kEnvUser
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t b
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
R__EXTERN TProof * gProof
char * Form(const char *fmt,...)
R__EXTERN TSystem * gSystem
void Print(Option_t *opt="") const override
Definition: KV2Body.cpp:874
Handles lists of available runs for different datasets and types of data.
Bool_t InfosNeedUpdate(const run_index_t &run, const KVString &filename)
void UpdateInfos(const run_index_t &run, const KVString &filename, const KVString &kvversion, const KVString &username)
void Print(Option_t *option="") const override
Definition: KVDBRun.cpp:61
KVDBSystem * GetSystem() const
Definition: KVDBRun.cpp:240
KV2Body * GetKinematics()
Definition: KVDBSystem.cpp:103
virtual void Reset()
virtual Bool_t CheckTaskVariables()
void WriteBatchEnvFile(const TString &jobname, Bool_t save=kTRUE) override
TString GetFullPathToRunfile(const KVString &type, const run_index_t &run) const
Definition: KVDataSet.cpp:885
KVAvailableRunsFile * GetAvailableRunsFile(const TString &type) const
Definition: KVDataSet.cpp:49
std::optional< run_index_t > GetRunNumberFromFileName(const TString &datatype, const TString &filename)
Definition: KVDataSet.cpp:978
FileType * OpenRunfile(const KVString &type, const run_index_t &run)
Definition: KVDataSet.h:285
ValType GetDataSetEnv(const Char_t *type, const ValType &defval={}) const
Definition: KVDataSet.h:270
Database entry for each run of an INDRA experiment.
Definition: KVINDRADBRun.h:30
KVINDRADBRun * GetRun(Int_t run) const
Definition: KVINDRADB.h:136
Base class for analysis of reconstructed INDRA events.
Manage analysis of reconstructed INDRA data.
void SetTriggerConditionsForRun(int) override
void SetSelectorCurrentRun(KVINDRADBRun *CurrentRun)
void WriteBatchEnvFile(const TString &, Bool_t sav=kTRUE) override
void PrintTreeInfos()
Print informations on currently analysed TTree.
KVReconstructedEvent * GetReconstructedEvent()
Bool_t CheckIfUserClassIsValid(const KVString &="") override
Bool_t CheckTaskVariables(void) override
Checks the task variables.
void Reset() override
Reset task variables.
Event reconstructed from energy losses in INDRA multidetector.
Set trigger conditions for analysis of reconstructed INDRA data.
void SetTriggerConditionsForRun(KVEventSelector *, Int_t, Bool_t=kFALSE) override
void handle_ebyedat_raw_data_parameter(const char *param_name, uint16_t val)
Definition: KVINDRA.cpp:422
static KVMultiDetArray * MakeMultiDetector(const Char_t *dataset_name, Int_t run=-1, TString classname="KVMultiDetArray", KVExpDB *db=nullptr)
void prepare_to_handle_new_raw_data()
reset acquisition parameters etc. before reading new raw data event
virtual void SetParameters(UInt_t n, Bool_t physics_parameters_only=kFALSE)
Base class for user analysis of reconstructed data.
void SetCurrentRun(KVDBRun *r) override
Event containing KVReconstructedNucleus nuclei reconstructed from hits in detectors.
Extension of ROOT TString class which allows backwards compatibility with ROOT v3....
Definition: KVString.h:73
Wrapper class for iterating over nuclei in KVReconstructedEvent accessed through base pointer or refe...
virtual void SetProof(Bool_t on=kTRUE, Bool_t refresh=kFALSE, Bool_t gettreeheader=kFALSE)
virtual const char * GetValue(const char *name, const char *dflt) const
virtual TObject * FindObject(const char *name) const
virtual Bool_t InheritsFrom(const char *classname) const
Bool_t IsMaster() const
void Form(const char *fmt,...)
virtual const char * BaseName(const char *pathname)
long long Long64_t
void Error(UserClass p, const char *location, const char *va_(fmt),...)
Definition: KVError.h:116
void Warning(UserClass p, const char *location, const char *va_(fmt),...)
Definition: KVError.h:125
BinData::ErrorType GetDataType(const TGraph *gr, DataOptions &fitOpt)
void Info(const char *location, const char *fmt,...)
Add
TArc a
ClassImp(TPyArg)