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  fReconEvent->GetParameters()->Concatenate(*to_be_detected->GetParameters());
200 
201  FillTree();
202 #ifdef WITH_GEMINI
203  }
204  while (fGemini && --iterations);
205 #endif
206 
207 
208  return kTRUE;
209 }
210 
211 
212 
214 
216 {
217  gEnv->SetValue(Form("%s.HasCalibIdentInfos", GetOpt("Dataset").Data()), fIdCalMode.Data());
218 }
219 
220 
221 
223 
225 {
226 }
227 
228 
229 
243 
245 {
246  // Select required dataset for filtering (option "Dataset")
247  // Build the associated multidetector geometry.
248  // Calculate C.M. velocity associated with required experimental collision
249  // kinematics (option "System").
250  //
251  // Set the parameters of the detectors according to the required run
252  // if given (option "Run"), or the first run of the given system otherwise.
253  //
254  // Open file for filtered data (see KVEventFiltering::OpenOutputFile), which will
255  // be stored in a TTree with name 'ReconstructedEvents', in a branch with name
256  // 'ReconEvent'. The class used for reconstructed events depends on the dataset,
257  // it is given by KVDataSet::GetReconstructedEventClassName().
258 
259  if (fDisableCreateTreeFile) return; //when running with PROOF, only execute on workers
260 
261  TString dataset = GetOpt("Dataset").Data();
262  if (!gDataSetManager) {
263  gDataSetManager = new KVDataSetManager;
264  gDataSetManager->Init();
265  }
266  gDataSetManager->GetDataSet(dataset)->cd();
267 
268  TString system;
269  if (IsOptGiven("System")) system = GetOpt("System").Data();
270  KVDBSystem* sys = (gExpDB && system != "" ? gExpDB->GetSystem(system) : nullptr);
271 
272  KV2Body* tb = nullptr;
273 
274  Bool_t justcreated = kFALSE;
275  if (sys) tb = sys->GetKinematics();
276  else if (system != "") {
277  tb = new KV2Body(system);
278  tb->CalculateKinematics();
279  justcreated = kTRUE;
280  }
281 
282  fCMVelocity = (tb ? tb->GetCMVelocity() : TVector3(0, 0, 0));
283  fCMVelocity *= -1.0;
284 
285  fProjVelocity = (tb ? tb->GetNucleus(1)->GetVelocity() : TVector3(0, 0, 0));
286  fProjVelocity *= -1.0;
287 
288  if (justcreated)
289  delete tb;
290 
291  Int_t run = 0;
292  if (IsOptGiven("Run")) {
293  run = GetOpt("Run").Atoi();
294  Info("InitAnalysis", "Run given in options = %d", run);
295  }
296  if (!run) {
297  if (sys) {
298  run = ((KVDBRun*)sys->GetRuns().First())->GetNumber();
299  Info("InitAnalysis", "Using first run for system = %d", run);
300  }
301  else {
302  Info("InitAnalysis", "No run information");
303  run = -1;
304  }
305  }
306 
307  fIdCalMode = gEnv->GetValue(Form("%s.HasCalibIdentInfos", dataset.Data()), "no");
308 
309  TString filt = GetOpt("Filter").Data();
310  if (filt == "GeoThresh") {
311  // in geo+thresholds mode, we ignore any calibration/identification parameters for the dataset,
312  // i.e. all detectors and all identification ntelescopes are supposed to work
313  gEnv->SetValue(Form("%s.HasCalibIdentInfos", dataset.Data()), "no");
314  }
315 
317  if (run == -1) gMultiDetArray->InitializeIDTelescopes();
318 
319  fDetSimulator.SetArray(gMultiDetArray);
320 
321  if (filt == "Geo") {
323  Info("InitAnalysis", "Geometric filter");
324  }
325  else if (filt == "GeoThresh") {
327  Info("InitAnalysis", "Geometry + thresholds filter");
328  }
329  else if (filt == "Full") {
331  Info("InitAnalysis", "Geometry + thresholds filter + implemented identifications and calibrations.");
332  }
333  TString kine = GetOpt("Kinematics").Data();
334  if (kine == "lab") {
336  Info("InitAnalysis", "Simulation is in laboratory/detector frame");
337  }
338  else {
339  fNewFrame = kine;
340  Info("InitAnalysis", "Simulation will be transformed to laboratory/detector frame");
341  }
342 
343  if (IsOptGiven("PhiRot")) {
344  if (GetOpt("PhiRot") == "no") fRotate = kFALSE;
345  }
346  if (fRotate) Info("InitAnalysis", "Random phi rotation around beam axis performed for each event");
347 #ifdef WITH_GEMINI
348  if (IsOptGiven("Gemini")) {
349  if (GetOpt("Gemini") == "yes") fGemini = kTRUE;
351  if (IsOptGiven("GemDecayPerEvent")) fGemDecayPerEvent = GetOpt("GemDecayPerEvent").Atoi();
352  else fGemDecayPerEvent = 1;
353  if (IsOptGiven("GemAddRotEner")) {
354  if (GetOpt("GemAddRotEner") == "yes") fGemAddRotEner = kTRUE;
355  }
356  }
357  if (fGemini) {
358  Info("InitAnalysis", "Statistical decay with Gemini++ for each event before detection");
359  if (fGemDecayPerEvent > 1) Info("InitAnalysis", " -- %d decays per primary event", fGemDecayPerEvent);
360  if (fGemAddRotEner) Info("InitAnalysis", " -- Rotational energy will be added to excitation energy");
361  }
362 #endif
363  if (filt == "Full" && !gDataSet->HasCalibIdentInfos()) {
364  // for old data without implementation of calibration/identification
365  // we set status of identifications according to experimental informations in IdentificationBilan.dat
366  // this "turns off" any telescopes which were not working during the experimental run
367 
368  // beforehand we have to "turn on" all identification telescopes by initializing them
369  // as this will not have been done yet
370  gMultiDetArray->InitializeIDTelescopes();
371  // this will also set informations on (simulated) mass identification capabilities for
372  // certain telescopes
373 
374  TString fullpath;
375  if (sys && KVBase::SearchKVFile("IdentificationBilan.dat", fullpath, gDataSet->GetName())) {
376  Info("InitAnalysis", "Setting identification bilan...");
377  TString sysname = sys->GetBatchName();
379  TIter next(gMultiDetArray->GetListOfIDTelescopes());
380  KVIDTelescope* idt;
381  while ((idt = (KVIDTelescope*)next())) {
382  idt->CheckIdentificationBilan(sysname);
383  }
384  }
385  }
386  gMultiDetArray->PrintStatusOfIDTelescopes();
387 
388  OpenOutputFile(sys, run);
389  TTree* t{nullptr};
390  if (sys) t = AddTree("ReconstructedEvents", Form("%s filtered with %s (%s)", GetOpt("SimTitle").Data(), gMultiDetArray->GetTitle(), sys->GetName()));
391  else t = AddTree("ReconstructedEvents", Form("%s filtered with %s", GetOpt("SimTitle").Data(), gMultiDetArray->GetTitle()));
392 
393  TString reconevclass = gDataSet->GetReconstructedEventClassName();
395  KVEvent::MakeEventBranch(t, "ReconEvent", fReconEvent);
396 
397  auto fer = new KVFilterEventReconstructor(gMultiDetArray, fReconEvent);
398 
399  // look for required data quality audit given as
400  // [dataset][/[system]]
401  // [dataset] is not necessarily the same as the one used for detector geometry
402  if (IsOptGiven("DataQualityAudit"))
403  {
404  KVString audit = GetOpt("DataQualityAudit");
405  audit.Begin("/");
406  KVString dataset,system;
407  dataset = audit.Next();
408  if(!audit.End())
409  system = audit.Next();
410  auto dqaf = TFile::Open(KVDataSet::GetFullPathToDataSetFile(dataset,"DataQualityAudit.root"));
411  auto dqa = system.IsNull() ? dqaf->Get<KVDataQualityAudit>(dataset) : dqaf->Get<KVDataQualityAudit>(system);
412  fer->SetDataQualityAudit(dqa);
413 
414  if(IsOptGiven("ExtensibleID"))
415  {
416  // the ID telescopes in the ExtensibleID list can go beyond the largest identified Z in the audit
417  // using theoretical (calculated) identification thresholds
418  KVString idlabs = GetOpt("ExtensibleID");
419  idlabs.Begin("|");
420  while(!idlabs.End())
421  {
423  }
424  }
425  }
426 
427  fEventReconstructor.reset(fer);
428 }
429 
430 
431 
433 
435 {
436  fEVN = 0;
437 #ifdef DEBUG_FILTER
439 #endif
440 }
441 
442 
443 
465 
467 {
468  // Open ROOT file for new filtered events TTree.
469  //
470  // The filename is built up from the original simulation filename and the values
471  // of various options:
472  //
473  // [simfile]_[Gemini]_filt=[filter-type]_[dataset]_[system]_run=[run-number].root
474  //
475  // In addition, informations on the filtered data are stored in the file as
476  // TNamed objects. These can be read by KVSimDir::AnalyseFile:
477  //
478  // KEY: TNamed System;1 title=[full system name]
479  // KEY: TNamed Dataset;1 title=[dataset name]
480  // KEY: TNamed Run;1 title=[run-number]
481  // KEY: TNamed Filter;1 title=[filter-type]
482  // KEY: TNamed Origin;1 title=[name of simulation file]
483  // KEY: TNamed RandomPhi;1 title=[yes/no, random rotation about beam axis]
484  // KEY: TNamed Gemini++;1 title=[yes/no, Gemini++ decay before detection]
485  // KEY: TNamed GemDecayPerEvent;1 title=[number of Gemini++ decays per primary event]
486  // KEY: TNamed GemAddRotEner;1 title=[Enable or not the addition of the rotational energy to the excitation energy]
487  //
488  TString basefile = GetOpt("SimFileName");
489  basefile.Remove(basefile.Index(".root"), 5);
490  TString outfile = basefile;
491 #ifdef WITH_GEMINI
492  if (fGemini) {
493  outfile += "_Gemini";
494  if (fGemDecayPerEvent > 1) outfile += fGemDecayPerEvent;
495  if (fGemAddRotEner) outfile += "AddedRotEner";
496  }
497 #endif
498  outfile += "_filt=";
499  outfile += GetOpt("Filter");
500  outfile += "_";
501  outfile += gDataSet->GetName();
502 
503  if (S) {
504  outfile += "_";
505  outfile += S->GetBatchName();
506  }
507  else if (IsOptGiven("System")) {
508  TString tmp = GetOpt("System");
509  tmp.ReplaceAll(" ", "");
510  tmp.ReplaceAll("@", "");
511  tmp.ReplaceAll("MeV/A", "");
512  tmp.ReplaceAll("+", "");
513  outfile += "_";
514  outfile += tmp.Data();
515  }
516  if (run > 0) {
517  outfile += "_run=";
518  outfile += Form("%d", run);
519  }
520  if (IsOptGiven("DataQualityAudit"))
521  {
522  KVString tmp(GetOpt("DataQualityAudit"));
523  tmp.ReplaceAll("/",":");
524  outfile += "_DQA=" + tmp;
525  }
526  outfile += ".root";
527 
528  TString fullpath;
529  AssignAndDelete(fullpath, gSystem->ConcatFileName(GetOpt("OutputDir").Data(), outfile.Data()));
530 
531  SetJobOutputFileName(fullpath);
532 
533  TDirectory* curdir = gDirectory;
534  writeFile->cd();
535  if (S) {
536  TNamed* system = new TNamed("System", S->GetName());
537  system->Write();
538  }
539  else if (GetOpt("System"))(new TNamed("System", GetOpt("System").Data()))->Write();
540 
541  (new TNamed("Dataset", gDataSet->GetName()))->Write();
542  if (run > 0)(new TNamed("Run", Form("%d", run)))->Write();
543  (new TNamed("Filter", GetOpt("Filter").Data()))->Write();
544  if (IsOptGiven("DataQualityAudit"))(new TNamed("DataQualityAudit", GetOpt("DataQualityAudit").Data()))->Write();
545  (new TNamed("Origin", (basefile + ".root").Data()))->Write();
546  (new TNamed("RandomPhi", (fRotate ? "yes" : "no")))->Write();
547 #ifdef WITH_GEMINI
548  (new TNamed("Gemini++", (fGemini ? "yes" : "no")))->Write();
549  (new TNamed("GemDecayPerEvent", Form("%d", fGemDecayPerEvent)))->Write();
550  (new TNamed("GemAddRotEner", (fGemAddRotEner ? "yes" : "no")))->Write();
551 #endif
552  curdir->cd();
553 }
554 
555 
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:168
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:541
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:41
Database class used to store information on different colliding systems studied during an experiment....
Definition: KVDBSystem.h:51
TString GetBatchName()
Definition: KVDBSystem.cpp:657
KV2Body * GetKinematics()
Definition: KVDBSystem.cpp:103
KVUnownedList GetRuns() const
Returns a sorted list of all the runs associated with this system.
Definition: KVDBSystem.cpp:139
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.
TString GetFullPathToDataSetFile(const Char_t *filename) const
Definition: KVDataSet.cpp:2067
virtual KVString GetReconstructedEventClassName() const
Definition: KVDataSet.h:377
Bool_t HasCalibIdentInfos() const
Definition: KVDataSet.h:396
void cd() const
Definition: KVDataSet.cpp:784
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
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
void EndAnalysis() override
TString fIdCalMode
original exp setup hasIDandCalib to be reset in case of modifications
KVReconstructedEvent * fReconEvent
KVEventFiltering()
Default constructor.
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:180
virtual void SetFrameName(const KVString &name)=0
static void MakeEventBranch(TTree *tree, const TString &branchname, T &event, Int_t bufsize=10000000)
Definition: KVEvent.h:211
virtual void SetFrame(const Char_t *, const KVFrameTransform &)=0
void SetParameter(const Char_t *name, ValType value) const
Definition: KVEvent.h:198
virtual KVDBSystem * GetSystem(const Char_t *system) const
Definition: KVExpDB.h:164
Reconstruct events after filtering a simulation.
static void EnableIDExtensionBeyondAudit(const TString &idlab)
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:85
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
static KVMultiDetArray * MakeMultiDetector(const Char_t *dataset_name, Int_t run=-1, TString classname="KVMultiDetArray", KVExpDB *db=nullptr)
void SetFilterType(Int_t t)
virtual void InitializeIDTelescopes()
void PrintStatusOfIDTelescopes()
void Copy(TObject &nvl) const override
void Concatenate(const KVNameValueList &nvl)
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
Extension of ROOT TString class which allows backwards compatibility with ROOT v3....
Definition: KVString.h:73
void Begin(TString delim) const
Definition: KVString.cpp:565
Bool_t End() const
Definition: KVString.cpp:634
KVString Next(Bool_t strip_whitespace=kFALSE) const
Definition: KVString.cpp:695
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
Bool_t IsNull() 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)