KaliVeda
Toolkit for HIC analysis
KVEventFiltering.cpp
1 //Created by KVClassFactory on Thu Jun 21 17:01:26 2012
2 //Author: John Frankland,,,
3 
4 #include "KVEventFiltering.h"
5 #include "KVMultiDetArray.h"
6 #include "KV2Body.h"
7 #include "KVDBSystem.h"
8 #include "KVDBRun.h"
9 #include "KVDataSet.h"
10 #include "KVDataSetManager.h"
11 #include "KVGeoNavigator.h"
12 #include "TRandom.h"
13 
15 
16 
17 
18 
19 
23 {
24  // Default constructor
25  fTransformKinematics = kTRUE;
26  fNewFrame = "";
27  fRotate = kTRUE;
28 #ifdef WITH_GEMINI
29  fGemini = kFALSE;
30  fGemDecayPerEvent = 1;
31  fGemAddRotEner = kFALSE;
32 #endif
33 #ifdef DEBUG_FILTER
34  memory_check = KVClassMonitor::GetInstance();
35  SetEventsReadInterval(100);
36 #endif
37 }
38 
39 
40 
41 
48 
50 {
51  // Copy constructor
52  // This ctor is used to make a copy of an existing object (for example
53  // when a method returns an object), and it is always a good idea to
54  // implement it.
55  // If your class allocates memory in its constructor(s) then it is ESSENTIAL :-)
56 
58  fNewFrame = "";
59  obj.Copy(*this);
60 }
61 
62 
63 
66 
68 {
69  // Destructor
70 #ifdef DEBUG_FILTER
71  delete memory_check;
72 #endif
73 }
74 
75 
76 
77 
85 
87 {
88  // This method copies the current state of 'this' object into 'obj'
89  // You should add here any member variables, for example:
90  // (supposing a member variable KVEventFiltering::fToto)
91  // CastedObj.fToto = fToto;
92  // or
93  // CastedObj.SetToto( GetToto() );
94 
96  KVEventFiltering& CastedObj = (KVEventFiltering&)obj;
97  CastedObj.fRotate = fRotate;
98 #ifdef WITH_GEMINI
99  CastedObj.fGemini = fGemini;
101 #endif
102 }
103 
104 
105 
111 
112 void KVEventFiltering::RandomRotation(KVEvent* to_rotate, const TString& frame_name) const
113 {
114  // do random phi rotation around z-axis
115  // if frame_name is given, apply rotation to that frame
116  //
117  // store phi rotation angle [radians] in event parameter "RANDOM_PHI"
118  TRotation r;
120  r.RotateZ(phi);
121  if (frame_name != "") to_rotate->SetFrame("rotated_frame", frame_name, r);
122  else to_rotate->SetFrame("rotated_frame", r);
123  to_rotate->SetParameter("RANDOM_PHI", phi);
124 }
125 
126 
127 
137 
139 {
140  // Event-by-event filtering of simulated data.
141  // If needed (fTransformKinematics = kTRUE), kinematics of event are transformed
142  // to laboratory frame using C.M. velocity calculated in InitAnalysis().
143  // Detection of particles in event is simulated with KVMultiDetArray::DetectEvent,
144  // then the reconstructed detected event is treated by the same identification and calibration
145  // procedures as for experimental data.
146 
147  // few event counter print at the beginning to be sure the process started properly
148  // because in case GEMINI decay is used, it sometimes stops (randomly) after few events
149  if ((fEVN <= 10)) Info("Analysis", "%d events processed", (int)fEVN);
150  else if ((fEVN <= 1000) && !(fEVN % 100)) Info("Analysis", "%d events processed", (int)fEVN);
151 
152 #ifdef DEBUG_FILTER
153  if (fEVN == 2500) memory_check->SetInitStatistics();
154  else if (fEVN > 4995) memory_check->CompareToInit();
155 #endif
156  KVEvent* to_be_detected = GetEvent();
157 #ifdef WITH_GEMINI
158  Int_t iterations = 1;
159  if (fGemini) iterations = fGemDecayPerEvent;
160 #endif
161  if (to_be_detected->GetNumber()) to_be_detected->SetParameter("SIMEVENT_NUMBER", (int)to_be_detected->GetNumber());
162  to_be_detected->SetParameter("SIMEVENT_TREE_ENTRY", (int)fTreeEntry);
163 #ifdef WITH_GEMINI
164  do {
165  if (fGemini) {
166  try {
168  }
169  catch (...) {
170  continue;
171  }
172  //Copy any parameters associated with simulated event into the Gemini-decayed event
174  to_be_detected = &fGemEvent;
175  }
176 #endif
177  if (fTransformKinematics) {
178  if (fNewFrame == "proj") to_be_detected->SetFrame("lab", fProjVelocity);
179  else to_be_detected->SetFrame("lab", fCMVelocity);
180  }
181  else {
182  // default kinematics is lab frame. make sure name is set.
183  to_be_detected->SetFrameName("lab");
184  }
185  if (fRotate) {
186  RandomRotation(to_be_detected, "lab");
187  fDetSimulator.DetectEvent(to_be_detected, "rotated_frame");
188  }
189  else {
190  fDetSimulator.DetectEvent(to_be_detected, "lab");
191  }
192 
194  fEventReconstructor->SetSimEvent(to_be_detected);
195  fEventReconstructor->ReconstructEvent();
196 
198  fReconEvent->SetFrameName("lab");
199 
200  FillTree();
201 #ifdef WITH_GEMINI
202  }
203  while (fGemini && --iterations);
204 #endif
205 
206 
207  return kTRUE;
208 }
209 
210 
211 
213 
215 {
216  gEnv->SetValue(Form("%s.HasCalibIdentInfos", GetOpt("Dataset").Data()), fIdCalMode.Data());
217 }
218 
219 
220 
222 
224 {
225 }
226 
227 
228 
242 
244 {
245  // Select required dataset for filtering (option "Dataset")
246  // Build the associated multidetector geometry.
247  // Calculate C.M. velocity associated with required experimental collision
248  // kinematics (option "System").
249  //
250  // Set the parameters of the detectors according to the required run
251  // if given (option "Run"), or the first run of the given system otherwise.
252  //
253  // Open file for filtered data (see KVEventFiltering::OpenOutputFile), which will
254  // be stored in a TTree with name 'ReconstructedEvents', in a branch with name
255  // 'ReconEvent'. The class used for reconstructed events depends on the dataset,
256  // it is given by KVDataSet::GetReconstructedEventClassName().
257 
258  if (fDisableCreateTreeFile) return; //when running with PROOF, only execute on workers
259 
260  TString dataset = GetOpt("Dataset").Data();
261  if (!gDataSetManager) {
262  gDataSetManager = new KVDataSetManager;
263  gDataSetManager->Init();
264  }
265  gDataSetManager->GetDataSet(dataset)->cd();
266 
267  TString system;
268  if (IsOptGiven("System")) system = GetOpt("System").Data();
269  KVDBSystem* sys = (gExpDB && system != "" ? gExpDB->GetSystem(system) : nullptr);
270 
271  KV2Body* tb = nullptr;
272 
273  Bool_t justcreated = kFALSE;
274  if (sys) tb = sys->GetKinematics();
275  else if (system != "") {
276  tb = new KV2Body(system);
277  tb->CalculateKinematics();
278  justcreated = kTRUE;
279  }
280 
281  fCMVelocity = (tb ? tb->GetCMVelocity() : TVector3(0, 0, 0));
282  fCMVelocity *= -1.0;
283 
284  fProjVelocity = (tb ? tb->GetNucleus(1)->GetVelocity() : TVector3(0, 0, 0));
285  fProjVelocity *= -1.0;
286 
287  if (justcreated)
288  delete tb;
289 
290  Int_t run = 0;
291  if (IsOptGiven("Run")) {
292  run = GetOpt("Run").Atoi();
293  Info("InitAnalysis", "Run given in options = %d", run);
294  }
295  if (!run) {
296  if (sys) {
297  run = ((KVDBRun*)sys->GetRuns()->First())->GetNumber();
298  Info("InitAnalysis", "Using first run for system = %d", run);
299  }
300  else {
301  Info("InitAnalysis", "No run information");
302  run = -1;
303  }
304  }
305 
306  fIdCalMode = gEnv->GetValue(Form("%s.HasCalibIdentInfos", dataset.Data()), "no");
307 
308  TString filt = GetOpt("Filter").Data();
309  if (filt == "GeoThresh") {
310  // in geo+thresholds mode, we ignore any calibration/identification parameters for the dataset,
311  // i.e. all detectors and all identification ntelescopes are supposed to work
312  gEnv->SetValue(Form("%s.HasCalibIdentInfos", dataset.Data()), "no");
313  }
314 
316  if (run == -1) gMultiDetArray->InitializeIDTelescopes();
317 
318  fDetSimulator.SetArray(gMultiDetArray);
319 
320  if (filt == "Geo") {
322  Info("InitAnalysis", "Geometric filter");
323  }
324  else if (filt == "GeoThresh") {
326  Info("InitAnalysis", "Geometry + thresholds filter");
327  }
328  else if (filt == "Full") {
330  Info("InitAnalysis", "Geometry + thresholds filter + implemented identifications and calibrations.");
331  }
332  TString kine = GetOpt("Kinematics").Data();
333  if (kine == "lab") {
335  Info("InitAnalysis", "Simulation is in laboratory/detector frame");
336  }
337  else {
338  fNewFrame = kine;
339  Info("InitAnalysis", "Simulation will be transformed to laboratory/detector frame");
340  }
341 
342  if (IsOptGiven("PhiRot")) {
343  if (GetOpt("PhiRot") == "no") fRotate = kFALSE;
344  }
345  if (fRotate) Info("InitAnalysis", "Random phi rotation around beam axis performed for each event");
346 #ifdef WITH_GEMINI
347  if (IsOptGiven("Gemini")) {
348  if (GetOpt("Gemini") == "yes") fGemini = kTRUE;
350  if (IsOptGiven("GemDecayPerEvent")) fGemDecayPerEvent = GetOpt("GemDecayPerEvent").Atoi();
351  else fGemDecayPerEvent = 1;
352  if (IsOptGiven("GemAddRotEner")) {
353  if (GetOpt("GemAddRotEner") == "yes") fGemAddRotEner = kTRUE;
354  }
355  }
356  if (fGemini) {
357  Info("InitAnalysis", "Statistical decay with Gemini++ for each event before detection");
358  if (fGemDecayPerEvent > 1) Info("InitAnalysis", " -- %d decays per primary event", fGemDecayPerEvent);
359  if (fGemAddRotEner) Info("InitAnalysis", " -- Rotational energy will be added to excitation energy");
360  }
361 #endif
362  if (filt == "Full" && !gDataSet->HasCalibIdentInfos()) {
363  // for old data without implementation of calibration/identification
364  // we set status of identifications according to experimental informations in IdentificationBilan.dat
365  // this "turns off" any telescopes which were not working during the experimental run
366 
367  // beforehand we have to "turn on" all identification telescopes by initializing them
368  // as this will not have been done yet
369  gMultiDetArray->InitializeIDTelescopes();
370  // this will also set informations on (simulated) mass identification capabilities for
371  // certain telescopes
372 
373  TString fullpath;
374  if (sys && KVBase::SearchKVFile("IdentificationBilan.dat", fullpath, gDataSet->GetName())) {
375  Info("InitAnalysis", "Setting identification bilan...");
376  TString sysname = sys->GetBatchName();
378  TIter next(gMultiDetArray->GetListOfIDTelescopes());
379  KVIDTelescope* idt;
380  while ((idt = (KVIDTelescope*)next())) {
381  idt->CheckIdentificationBilan(sysname);
382  }
383  }
384  }
385  gMultiDetArray->PrintStatusOfIDTelescopes();
386 
387  OpenOutputFile(sys, run);
388  TTree* t{nullptr};
389  if (sys) t = AddTree("ReconstructedEvents", Form("%s filtered with %s (%s)", GetOpt("SimTitle").Data(), gMultiDetArray->GetTitle(), sys->GetName()));
390  else t = AddTree("ReconstructedEvents", Form("%s filtered with %s", GetOpt("SimTitle").Data(), gMultiDetArray->GetTitle()));
391 
392  TString reconevclass = gDataSet->GetReconstructedEventClassName();
394  KVEvent::MakeEventBranch(t, "ReconEvent", fReconEvent);
395 
396  auto fer = new KVFilterEventReconstructor(gMultiDetArray, fReconEvent);
397 
398  // look for data quality audit for system
399  if (IsOptGiven("DataQualityAudit")) {
400  auto dqaf = TFile::Open(gDataSet->GetFullPathToDataSetFile("DataQualityAudit.root"));
401  auto dqa = dqaf->Get<KVDataQualityAudit>(GetOpt("DataQualityAudit"));
402  fer->SetDataQualityAudit(dqa);
403  }
404 
405  fEventReconstructor.reset(fer);
406 }
407 
408 
409 
411 
413 {
414  fEVN = 0;
415 #ifdef DEBUG_FILTER
417 #endif
418 }
419 
420 
421 
443 
445 {
446  // Open ROOT file for new filtered events TTree.
447  //
448  // The filename is built up from the original simulation filename and the values
449  // of various options:
450  //
451  // [simfile]_[Gemini]_filt=[filter-type]_[dataset]_[system]_run=[run-number].root
452  //
453  // In addition, informations on the filtered data are stored in the file as
454  // TNamed objects. These can be read by KVSimDir::AnalyseFile:
455  //
456  // KEY: TNamed System;1 title=[full system name]
457  // KEY: TNamed Dataset;1 title=[dataset name]
458  // KEY: TNamed Run;1 title=[run-number]
459  // KEY: TNamed Filter;1 title=[filter-type]
460  // KEY: TNamed Origin;1 title=[name of simulation file]
461  // KEY: TNamed RandomPhi;1 title=[yes/no, random rotation about beam axis]
462  // KEY: TNamed Gemini++;1 title=[yes/no, Gemini++ decay before detection]
463  // KEY: TNamed GemDecayPerEvent;1 title=[number of Gemini++ decays per primary event]
464  // KEY: TNamed GemAddRotEner;1 title=[Enable or not the addition of the rotational energy to the excitation energy]
465  //
466  TString basefile = GetOpt("SimFileName");
467  basefile.Remove(basefile.Index(".root"), 5);
468  TString outfile = basefile;
469 #ifdef WITH_GEMINI
470  if (fGemini) {
471  outfile += "_Gemini";
472  if (fGemDecayPerEvent > 1) outfile += fGemDecayPerEvent;
473  if (fGemAddRotEner) outfile += "AddedRotEner";
474  }
475 #endif
476  outfile += "_filt=";
477  outfile += GetOpt("Filter");
478  outfile += "_";
479  outfile += gDataSet->GetName();
480 
481  if (S) {
482  outfile += "_";
483  outfile += S->GetBatchName();
484  }
485  else if (GetOpt("System")) {
486  TString tmp = GetOpt("System");
487  tmp.ReplaceAll(" ", "");
488  tmp.ReplaceAll("@", "");
489  tmp.ReplaceAll("MeV/A", "");
490  tmp.ReplaceAll("+", "");
491  outfile += "_";
492  outfile += tmp.Data();
493  }
494  if (run > 0) {
495  outfile += "_run=";
496  outfile += Form("%d", run);
497  }
498  outfile += ".root";
499 
500  TString fullpath;
501  AssignAndDelete(fullpath, gSystem->ConcatFileName(GetOpt("OutputDir").Data(), outfile.Data()));
502 
503  SetJobOutputFileName(fullpath);
504 
505  TDirectory* curdir = gDirectory;
506  writeFile->cd();
507  if (S) {
508  TNamed* system = new TNamed("System", S->GetName());
509  system->Write();
510  }
511  else if (GetOpt("System"))(new TNamed("System", GetOpt("System").Data()))->Write();
512 
513  (new TNamed("Dataset", gDataSet->GetName()))->Write();
514  if (run > 0)(new TNamed("Run", Form("%d", run)))->Write();
515  (new TNamed("Filter", GetOpt("Filter").Data()))->Write();
516  if (IsOptGiven("DataQualityAudit"))(new TNamed("DataQualityAudit", Form("%s/%s", gDataSet->GetName(), GetOpt("DataQualityAudit").Data())))->Write();
517  (new TNamed("Origin", (basefile + ".root").Data()))->Write();
518  (new TNamed("RandomPhi", (fRotate ? "yes" : "no")))->Write();
519 #ifdef WITH_GEMINI
520  (new TNamed("Gemini++", (fGemini ? "yes" : "no")))->Write();
521  (new TNamed("GemDecayPerEvent", Form("%d", fGemDecayPerEvent)))->Write();
522  (new TNamed("GemAddRotEner", (fGemAddRotEner ? "yes" : "no")))->Write();
523 #endif
524  curdir->cd();
525 }
526 
527 
int Int_t
ROOT::R::TRInterface & r
bool Bool_t
constexpr Bool_t kFALSE
double Double_t
constexpr Bool_t kTRUE
#define gDirectory
R__EXTERN TEnv * gEnv
R__EXTERN TRandom * gRandom
char * Form(const char *fmt,...)
void AssignAndDelete(TString &target, char *tobedeleted)
R__EXTERN TSystem * gSystem
Relativistic binary kinematics calculator.
Definition: KV2Body.h:166
TVector3 GetCMVelocity() const
Return vector velocity of centre of mass of reaction (units: cm/ns)
Definition: KV2Body.cpp:572
void CalculateKinematics()
Definition: KV2Body.cpp:677
KVNucleus * GetNucleus(Int_t i) const
Definition: KV2Body.cpp:456
virtual void SetNumber(UInt_t num)
Definition: KVBase.h:215
static Bool_t SearchKVFile(const Char_t *name, TString &fullpath, const Char_t *kvsubdir="")
Definition: KVBase.cpp:517
UInt_t GetNumber() const
Definition: KVBase.h:219
static KVClassMonitor * GetInstance()
Return pointer to unique instance of class monitor class.
Description of an experimental run in database ,,.
Definition: KVDBRun.h:40
Database class used to store information on different colliding systems studied during an experiment....
Definition: KVDBSystem.h:52
KVUnownedList * GetRuns() const
Returns a sorted list of all the runs associated with this system.
Definition: KVDBSystem.h:118
TString GetBatchName()
Definition: KVDBSystem.cpp:613
KV2Body * GetKinematics()
Definition: KVDBSystem.cpp:80
Audit of experimental data identification and calibrations.
Manage all datasets contained in a given data repository.
virtual Bool_t Init(KVDataRepository *=0)
KVDataSet * GetDataSet(Int_t) const
Return pointer to DataSet using index in list of all datasets, index>=0.
virtual KVString GetReconstructedEventClassName() const
Definition: KVDataSet.h:214
Bool_t HasCalibIdentInfos() const
Definition: KVDataSet.h:229
TString GetFullPathToDataSetFile(const Char_t *filename)
Definition: KVDataSet.cpp:1926
void cd() const
Definition: KVDataSet.cpp:762
void SetArray(KVMultiDetArray *a, Double_t e_cut_off=1.e-3)
void DetectEvent(KVEvent *event, const Char_t *detection_frame="")
TString GetDetectionFrame() const
Filter simulated events with multidetector response.
void InitRun() override
TString fNewFrame
allow the definition of a specific frame
std::unique_ptr< KVFilterEventReconstructor > fEventReconstructor
KVSimEvent fGemEvent
event after decay with Gemini
void EndRun() override
void OpenOutputFile(KVDBSystem *, Int_t)
Bool_t fTransformKinematics
=kTRUE if simulation not in lab frame
void RandomRotation(KVEvent *to_rotate, const TString &frame_name="") const
Bool_t fGemini
true if Gemini++ decay should be performed before detection [default: no]
void EndAnalysis() override
TString fIdCalMode
original exp setup hasIDandCalib to be reset in case of modifications
KVReconstructedEvent * fReconEvent
KVEventFiltering()
Default constructor.
Bool_t fGemAddRotEner
true if rotational energy has to be added to excitation energy [default: no]
Int_t fGemDecayPerEvent
number of Gemini++ decays to be performed for each event [default:1]
void Copy(TObject &) const override
void InitAnalysis() override
KVDetectionSimulator fDetSimulator
Bool_t Analysis() override
virtual ~KVEventFiltering()
Destructor.
Long64_t fEVN
event number counter
Bool_t fRotate
true if random phi rotation should be applied [default: yes]
General purpose analysis base class for TTree containing KVEvent objects.
Bool_t fDisableCreateTreeFile
used with PROOF
Long64_t fTreeEntry
current tree entry number
void AddTree(TTree *tree)
void SetEventsReadInterval(Long64_t N)
void SetJobOutputFileName(const TString &filename)
Bool_t IsOptGiven(const Char_t *option)
KVEvent * GetEvent() const
TString GetOpt(const Char_t *option) const
void FillTree(const Char_t *tree_name="")
Abstract base class container for multi-particle events.
Definition: KVEvent.h:67
KVNameValueList * GetParameters() const
Definition: KVEvent.h:179
virtual void SetFrameName(const KVString &name)=0
static void MakeEventBranch(TTree *tree, const TString &branchname, T &event, Int_t bufsize=10000000)
Definition: KVEvent.h:210
virtual void SetFrame(const Char_t *, const KVFrameTransform &)=0
void SetParameter(const Char_t *name, ValType value) const
Definition: KVEvent.h:197
virtual KVDBSystem * GetSystem(const Char_t *system) const
Definition: KVExpDB.h:109
Reconstruct events after filtering a simulation.
void DecayEvent(const KVSimEvent *, KVSimEvent *, bool=true)
Definition: KVGemini.cpp:173
Base class for all detectors or associations of detectors in array which can identify charged particl...
Definition: KVIDTelescope.h:84
void CheckIdentificationBilan(const TString &system)
Set status of ID Telescope for given system.
static void OpenIdentificationBilan(const TString &path)
Open IdentificationBilan.dat file with given path.
KVSeqCollection * GetListOfIDTelescopes() const
void SetFilterType(Int_t t)
static KVMultiDetArray * MakeMultiDetector(const Char_t *dataset_name, Int_t run=-1, TString classname="KVMultiDetArray")
virtual void InitializeIDTelescopes()
void PrintStatusOfIDTelescopes()
void Copy(TObject &nvl) const override
TVector3 GetVelocity() const
returns velocity vector in cm/ns units
Event containing KVReconstructedNucleus nuclei reconstructed from hits in detectors.
TObject * First() const override
Container class for simulated nuclei, KVSimNucleus.
Definition: KVSimEvent.h:22
void SetFrameName(const KVString &name)
const char * GetName() const override
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
static TClass * GetClass(Bool_t load=kTRUE, Bool_t silent=kFALSE)
Bool_t cd() override
virtual Bool_t cd()
virtual const char * GetValue(const char *name, const char *dflt) const
virtual void SetValue(const char *name, const char *value, EEnvLevel level=kEnvChange, const char *type=nullptr)
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
const char * GetName() const override
const char * GetTitle() const override
virtual Int_t Write(const char *name=nullptr, Int_t option=0, Int_t bufsize=0)
virtual void Copy(TObject &object) const
virtual void Info(const char *method, const char *msgfmt,...) const
virtual Double_t Uniform(Double_t x1, Double_t x2)
Int_t Atoi() const
const char * Data() const
TString & Remove(EStripType s, char c)
TString & ReplaceAll(const char *s1, const char *s2)
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
virtual char * ConcatFileName(const char *dir, const char *name)
RooArgSet S(Args_t &&... args)
constexpr Double_t TwoPi()
ClassImp(TPyArg)