KaliVeda
Toolkit for HIC analysis
KVDataAnalyser.cpp
1 /*
2 $Id: KVDataAnalyser.cpp,v 1.40 2009/01/14 16:15:46 franklan Exp $
3 $Revision: 1.40 $
4 $Date: 2009/01/14 16:15:46 $
5 $Author: franklan $
6 */
7 
8 #include "KVBase.h"
9 #include "KVDataAnalyser.h"
10 #include "KVDataAnalysisTask.h"
11 #include "KVDataSetManager.h"
12 #include "KVString.h"
13 #include "TObjString.h"
14 #include "TObjArray.h"
15 #include "Riostream.h"
16 #include "KVBatchSystemManager.h"
17 #include "TPluginManager.h"
18 #include "TSystemDirectory.h"
19 #include "TROOT.h"
20 #include "TClass.h"
21 #include "THashList.h"
22 #include "KVError.h"
23 
24 using namespace std;
26 
28 
29 KVDataAnalyser* gDataAnalyser = 0;
30 
31 
34 
36 {
37  //Default constructor.
38  fParent = nullptr;
39  fBatch = kFALSE;
40  fTask = nullptr;
41  fQuit = kFALSE;
42  fSubmit = kFALSE;
43  nbEventToRead = -1;
44  fUserClassIsOK = kFALSE;
45  fUserClass = "";
46  if (!gBatchSystemManager) new KVBatchSystemManager;
47  fBatchSystem = 0;
48  fChoseRunMode = kFALSE;
49  fWorkDirInit = fWorkDirEnd = 0;
50  fMenus = kFALSE;
51 #ifdef WITH_CPP11
52  fProofMode = EProofMode::None;
53 #else
54  fProofMode = None;
55 #endif
56  fUseBaseClassSubmitTask = kFALSE;
57 }
58 
59 
60 
63 
64 KVDataAnalyser::~KVDataAnalyser()
65 {
66  //Default destructor.
67  SafeDelete(fWorkDirInit);
68  SafeDelete(fWorkDirEnd);
69  if (gDataAnalyser == this)gDataAnalyser = nullptr;
70 }
71 
72 
73 
75 
77 {
78  fDataType = "";
79  fTask = nullptr;
80  fQuit = kFALSE;
81  fSubmit = kFALSE;
82  fUserClassIsOK = kFALSE;
83  fUserClass = "";
84  fUserClassOptions = "";
85  nbEventToRead = -1;
86  fBatchSystem = nullptr;
87  fChoseRunMode = kFALSE;
88 #ifdef WITH_CPP11
89  fProofMode = EProofMode::None;
90 #else
91  fProofMode = None;
92 #endif
93 }
94 
95 
96 
97 
100 
102 {
103  //Check all task variables, then run analyser
104 
105  fSubmit = kFALSE;
106  //print welcome message for main (parent) analyser
107  if (!fParent && !fMenus) KVBase::PrintSplashScreen();
108 
109  if (CheckTaskVariables()) {
110  if (fBatchSystem && !BatchMode()) {
111  //if batch mode is requested, the job is submitted to the chosen batch system
112  fBatchSystem->SubmitTask(this);
113  } else {
114  if (BatchMode() && fBatchSystem && !fParent) fBatchSystem->Print("log");
115  if (!RunningInLaunchDirectory() && fParent) {
116  //when batch job runs in directory different to launch directory,
117  //we scan the list of files present in the current working directory
118  //just prior to running the analysis task
119  ScanWorkingDirectory(&fWorkDirInit);
120  }
121  if (!PreSubmitCheck()) return;
122 
123  // The following horrific kludge is supposed to solve the following problem:
124  // when running in batch mode (GridEngine) the data analyser created in
125  // KaliVedaAnalysis.cpp has to be of the right type (KVSimDirAnalyser or KVDataSetAnalyser)
126  // in order for it to read all necessary informations from the batch env file
127  // by calling the appropriate ReadBatchEnvFile override.
128  // However, when Run() is called for this object from KaliVedaAnalysis.cpp,
129  // we have to call the KVDataAnalyser::SubmitTask method, not the override in the
130  // derived class.
131  if (fUseBaseClassSubmitTask)
133  else
134  SubmitTask();
135 
136  if (!RunningInLaunchDirectory() && fParent) {
137  //when batch job runs in directory different to launch directory,
138  //we scan the list of files present in the current working directory
139  //just after running the analysis task
140  ScanWorkingDirectory(&fWorkDirEnd);
141  //any files which are present in the second list which were not present
142  //in the first list will be copied back to the launch directory
143  CopyAnalysisResultsToLaunchDirectory();
144  }
145  if (BatchMode() && fBatchSystem && !fParent) {
146  // at end of batch jobs,
147  // remove .[jobname] and [jobname].status files from $HOME directory
148  // remove .[jobname].bak and [jobname].status.bak files from $HOME directory
149  TString ff;
150  AssignAndDelete(ff, gSystem->ConcatFileName(gSystem->Getenv("HOME"), Form(".%s", GetBatchName())));
151  gSystem->Unlink(ff);
152  AssignAndDelete(ff, gSystem->ConcatFileName(gSystem->Getenv("HOME"), Form(".%s.bak", GetBatchName())));
153  gSystem->Unlink(ff);
154  AssignAndDelete(ff, gSystem->ConcatFileName(gSystem->Getenv("HOME"), Form("%s.status", GetBatchName())));
155  gSystem->Unlink(ff);
156  AssignAndDelete(ff, gSystem->ConcatFileName(gSystem->Getenv("HOME"), Form("%s.status.bak", GetBatchName())));
157  gSystem->Unlink(ff);
158  }
159  }
160  }
161  PostRunReset();
162 }
163 
164 
165 
166 
169 
171 {
172  //Run data analyser in menu-driven mode
173 
174  fMenus = kTRUE;
175  Reset();
177 
178  while (!fQuit) {
179  if (NeedToChooseWhatToDo())
180  ChooseWhatToDo();
181  else if (NeedToChooseWhatToAnalyse())
182  ChooseWhatToAnalyse();
183  else if (fSubmit) {
184  Run();
185  Reset();
187  }
188  }
189 }
190 
191 
192 
193 
198 
200 {
201  //Checks the task variables
202  //In batch mode, we first set the task variables by reading the
203  //batch env file associated with the name set for the batch job
204 
205  if (BatchMode()) ReadBatchEnvFile(Form(".%s", GetBatchName()));
206 
207  //if (!CheckWhatToAnalyseAndHow()) return kFALSE;
208 
209  if (fTask->WithUserClass() && fUserClass != ClassName()) {
210  //task requires user analysis class
211  if (fUserClass == "") {
212  if (BatchMode()) return kFALSE; // avoid infinite loop in batch mode
213  ChooseUserClass();
214  }
215 
216  if (!CheckIfUserClassIsValid(fUserClassAlternativeBaseClass)) {
217  cout << "============> Warning <=============" << endl;
218  cout << GetUserClass() << " is not a valid " << fTask->GetUserBaseClass() << endl;
219  cout << "Analysis aborted." << endl;
220  cout << "====================================" << endl;
221  /*if (BatchMode())*/ return kFALSE; // avoid infinite loop in batch mode
222  //ChooseUserClass();
223  }
224  }
225 
226  if (nbEventToRead < 0) {
227  ChooseNbEventToRead();
228  }
229 
230  return kTRUE;
231 }
232 
233 
234 
236 
238 {
239  if (NeedToChooseWhatToDo()) {
240  return kFALSE;
241  }
242 
243  if (NeedToChooseWhatToAnalyse()) {
244  return kFALSE;
245  }
246  return kTRUE;
247 }
248 
249 
250 
251 
252 
253 
258 
260 {
261  //Set analysis task and data type
262  //For ways of obtaining pointers to data analysis tasks for any given dataset,
263  //see method KVDataSet::GetAnalysisTask(const Char_t* keywords) const.
264  fTask = at;
265  if (at)
266  fDataType = at->GetPrereq();
267  else
268  fDataType = "";
269 }
270 
271 
272 
273 
277 
279 {
280 // Add to the includes paths the user's includes paths
281 // the includes paths have to be separated by a white space
282 
283  fIncludes = "";
284  if (!incDirs) {
285  return;
286  }
287  TString tmp = incDirs;
288  TString curIncDir = gSystem->GetIncludePath();
289  TObjArray* oa = tmp.Tokenize(" ");
290  oa->SetOwner(kTRUE);
291  TIter next(oa);
292  TObjString* st = 0;
293  while ((st = (TObjString*)next())) {
294  TString id = st->GetString();
295  if (id.Length()) {
296  fIncludes += id.Data();
297  fIncludes += " ";
298  if (!curIncDir.Contains(id.Data())) {
299  cout << "Include path \"" << id.Data() << "\" added." << endl;
300  id.Prepend("-I");
301  gSystem->AddIncludePath(id.Data());
302  }
303  }
304  }
305  delete oa;
306 }
307 
308 
309 
310 
314 
316 {
317 // Load the user's libraries
318 // the libraries have to be separated by a white space
319 
320  fLibraries = "";
321  if (!libs) {
322  return;
323  }
324  KVString tmp = libs;
325  KVString slib = gSystem->GetLibraries("", "D");
326 
327  tmp.Begin(" ");
328  while (!tmp.End()) {
329 
330  KVString id = tmp.Next();
331 
332  Bool_t loaded = kFALSE;
333  slib.Begin(" ");
334  while (!slib.End() && !loaded) {
335  KVString ss = slib.Next();
336  if (ss == id) {
337  Info("SetUserLibraries", "%s already load", id.Data());
338  loaded = kTRUE;
339  } else {
340  }
341  }
342  if (!loaded) {
343  Info("SetUserLibraries", "Library \"%s\"added.", id.Data());
344  gSystem->Load(id.Data());
345  }
346  fLibraries += id.Data();
347  fLibraries += " ";
348  }
349 
350 }
351 
352 
353 
354 
357 
359 {
360  // Ask user to set number of events to read
361 
362  SetNbEventToRead(-1);
363  while (nbEventToRead < 0) {
364  cout << "Give the number of events to read [<RET>=all]:" << endl;
365  KVString ntr;
366  ntr.ReadToDelim(cin);
367  if (ntr.IsDigit() || !ntr.Length()) {
368  if (ntr.Length()) {
369  nbEventToRead = (Long64_t) ntr.Atoi();
370  } else {
371  nbEventToRead = 0;
372  }
373  } else {
374  cout << "\"" << ntr.
375  Data() << "\" is not a number. Please retry." << endl;
376  }
377  }
378 }
379 
380 
381 
382 
386 
388 {
389  //Creates an instance of a class derived from KVDataAnalyser defined as a plugin
390 
391  //check and load plugin library
392  TPluginHandler* ph;
393  if (!(ph = KVBase::LoadPlugin("KVDataAnalyser", plugin)))
394  return 0;
395 
396  //execute constructor
397  KVDataAnalyser* da = (KVDataAnalyser*) ph->ExecPlugin(0);
398 
399  return da;
400 }
401 
402 
403 
404 
407 
409 {
410  //Choose the user's analysis class
411  fUserClass = "";
412  while (!fUserClass.Length()) {
413  cout << "Give the name of the analysis class derived from " << fTask->GetUserBaseClass() << ":" << endl;
414  fUserClass.ReadLine(cin);
415  fUserClassIsOK = kFALSE;
416  }
417 }
418 
419 
420 
421 
425 
427 {
428  //Check if files containing user's class are present in the working directory.
429  //The names of the implementation and header files are stored in fUserClassImp and fUserClassDec.
430 
431  return KVBase::FindClassSourceFiles(fUserClass.Data(), fUserClassImp, fUserClassDec);
432 }
433 
434 
435 
436 
453 
455 {
456  //Return kTRUE if the name of the class given by the user (fUserClass) is valid
457  //for the analysis task. This is so if one of the following is true:
458  // - the class library has already been loaded. In this case the class will exist
459  // in the dictionary (gROOT->GetClass()); we check if it derived from the
460  // base class defined for the analysis task
461  // - a plugin exists defining this class as an extension of the base class defined
462  // for the analysis task (gROOT->GetPluginManager()->FindHandler(...): the URI for
463  // the plugin must be the same as the name of the class)
464  // - source files for the class are present in the working directory. In this case
465  // we can add a plugin handler for the class.
466  //In the latter two cases, the class is valid if compilation succeeds.
467  //
468  //If the user's class may in fact be derived from an alternative base class, rather
469  //than the base class defined for this analysis task (see KVDataAnalysisTask::SetUserBaseClass)
470  //you can supply the name of this class (or a comma-separated list of base classes).
471 
472  TObject* o = GetInstanceOfUserClass(alternative_base_class);
473  if (o) {
474  delete o;
475  return kTRUE;
476  }
477  return kFALSE;
478 }
479 
480 
481 
482 
493 
495 {
496  // Returns string to be appended to name of user class for compilation with ACliC in
497  // GetInstanceOfUserClass. This depends on the boolean resources:
498  //
499  // KVDataAnalyser.UserClass.Debug: ( "yes" => "g" )
500  // KVDataAnalyser.UserClass.Optimise: ( "yes" => "O" )
501  // KVDataAnalyser.UserClass.ForceRecompile: ( "no" => "+"; "yes" => "++" )
502  //
503  // Note that if both Debug and Optimise are set to "yes/true", we use Debug mode.
504  // (can't have BOTH debug & optimisation).
505 
506  static TString aclic;
507  if (gEnv->GetValue("KVDataAnalyser.UserClass.ForceRecompile", kFALSE)) aclic = "++";
508  else aclic = "+";
509  if (gEnv->GetValue("KVDataAnalyser.UserClass.Debug", kFALSE)) aclic += "g";
510  else if (gEnv->GetValue("KVDataAnalyser.UserClass.Optimise", kFALSE)) aclic += "O";
511  return aclic.Data();
512 }
513 
514 
515 
517 
519 {
520  fBatchSystem = nullptr;
521 }
522 
523 
524 
525 
541 
543 {
544  //Return an instance of the class given by the user (fUserClass), if it is valid.
545  //If the user class is given in the form of source code, it will be (re)compiled
546  //if it has not already been loaded and/or the source has changed since the last
547  //build, using ACliC. If the resource
548  //
549  // KVDataAnalyser.UserClass.Debug: yes
550  //
551  //is set, the user's class will be compiled with extra debugging information
552  //
553  //Once compiled, we check that the user's class is indeed derived from the base
554  //class defined for this analysis task (see KVDataAnalysisTask::SetUserBaseClass).
555  //If the user's class may in fact be derived from an alternative base class, you
556  //can supply the name of this class (or comma-separated list of base classes).
557 
558  // make sure any required plugin library defining base class for user's analysis class is loaded
559  if (!fTask->CheckUserBaseClassIsLoaded()) return 0x0;
560 
561  //do we have a plugin ?
562  TPluginHandler* ph = gROOT->GetPluginManager()->FindHandler(fTask->GetUserBaseClass(), fUserClass.Data());
563  if (!ph) {//no plugin defined
564 
565  //if it is a precompiled class (i.e. already part of KaliVeda),
566  //it will be in the dictionary already
567  TClass* cl = gROOT->GetClass(fUserClass.Data());
568 
569  //do we have source files ?
570  if (DoUserClassFilesExist()) {
571  //compile & load user's source files using ACLIC. ACliC options read by GetACliCMode() from .kvrootrc
572  TString cmd;
573  cmd.Form(".L %s%s", fUserClassImp.Data(), GetACliCMode());
574  gROOT->ProcessLine(cmd.Data());
575  //class will be in dictionary if compilation successful
576  cl = gROOT->GetClass(fUserClass.Data());
577  } else if (!cl) {
578  //class not in dictionary and no source files. help!
579  Info("GetInstanceOfUserClass", "Class %s is unknown and no source files available",
580  fUserClass.Data());
581  return 0;
582  }
583  if (!cl) {
584  //compilation of user class has failed
585  Info("GetInstanceOfUserClass", "Compilation of class %s failed. Correct the mistakes and try again",
586  fUserClass.Data());
587  return 0;
588  }
589  if (!cl->GetBaseClass(fTask->GetUserBaseClass())) {
590  // class does not inherit from base class defined by analysis task
591  if (alternative_base_class == "") { // no alternative base classes provided
592  Info("GetInstanceOfUserClass", "Class %s does not inherit from correct base class (%s), or compilation of class %s failed. Correct the mistakes and try again",
593  fUserClass.Data(), fTask->GetUserBaseClass(), fUserClass.Data());
594  return nullptr;
595  } else {
596  // check alternative base class(es) - it may still be good!
597  bool got_good_base = false;
598  TString good_base = "";
599  alternative_base_class.Begin(",");
600  while (!alternative_base_class.End()) {
601  good_base = alternative_base_class.Next(kTRUE);
602  if (cl->GetBaseClass(good_base)) {
603  got_good_base = true;
604  break;
605  }
606  }
607  if (got_good_base) {
608  Info("GetInstanceOfUserClass", "Class %s inherits from alternative base class %s: OK!",
609  fUserClass.Data(), good_base.Data());
610  } else {
611  Info("GetInstanceOfUserClass", "Class %s does not inherit from task-defined base class (%s) or any provided alternative base classes (%s), or compilation of class %s failed. Correct the mistakes and try again",
612  fUserClass.Data(), fTask->GetUserBaseClass(), alternative_base_class.Data(), fUserClass.Data());
613  return nullptr;
614  }
615  }
616  }
617  //EVERYTHING OK!! now instanciate an object of the new class
618  return (TObject*)cl->New();
619  } else {
620  Info("GetInstanceOfUserClass", "Found plugin handler for class %s",
621  fUserClass.Data());
622  //load class from plugin
623  ph = KVBase::LoadPlugin(fTask->GetUserBaseClass(), fUserClass.Data());
624  if (!ph) {
625  Info("GetInstanceOfUserClass", "KVBase::LoadPlugin failed for %s", fUserClass.Data());
626  return 0;
627  }
628  TObject* obj = (TObject*)ph->ExecPlugin(0);
629  if (obj) {
630  //Info("GetInstanceOfUserClass", "constructor OK for %s", fUserClass.Data());
631  if (obj->InheritsFrom(fTask->GetUserBaseClass())) return obj;
632  Info("GetInstanceOfUserClass", "%s does not inherit from %s", fUserClass.Data(), fTask->GetUserBaseClass());
633  return 0;
634  } else {
635  Info("GetInstanceOfUserClass", "constructor not OK for %s", fUserClass.Data());
636  return 0;
637  }
638  }
639  return 0;
640 }
641 
642 
643 
644 
649 
651 {
652  //Set name of user analysis class.
653  //If check=kTRUE (default), we check the validity of the class
654  //if check=kFALSE we do not check and assume that the class is valid
655 
656  fUserClass = kvs;
657  if (check) {
658  fUserClassIsOK = CheckIfUserClassIsValid();
659  } else {
660  fUserClassIsOK = kTRUE;
661  }
662 }
663 
664 
665 
666 
672 
674 {
675  //Save (in the TEnv fBatchEnv) all necessary information on analysis task which can be used to execute it later
676  //(i.e. when batch processing system executes the job).
677  //If save=kTRUE (default), write the information in a file whose name is given by ".jobname"
678  //where 'jobname' is the name of the job as given to the batch system.
679 
680  OpenBatchInfoFile(Form(".%s", jobname.Data()));
681  if (fBatchSystem) {
682  fBatchEnv->SetValue("BatchSystem", fBatchSystem->GetName());
683  fBatchSystem->WriteBatchEnvFile(GetBatchInfoFile());
684  }
685  fBatchEnv->SetValue("AnalysisTask", fTask->GetType());
686 
687  if (fTask->WithUserClass()) {
688  fBatchEnv->SetValue("UserClass", GetUserClass());
689  if (fUserClassImp == "" || fUserClassDec == "") {
690  if (!DoUserClassFilesExist()) {
691  Warning("WriteBatchEnvFile", "Source files for user class %s do not exist. Job will not work.",
692  GetUserClass());
693  }
694  }
695  fBatchEnv->SetValue("UserClassOptions", fUserClassOptions);
696  fBatchEnv->SetValue("UserClassImp", fUserClassImp);
697  fBatchEnv->SetValue("UserClassDec", fUserClassDec);
698  } else {
699  // a task without a user class may still need to pass options to the predefined analysis class
700  if (fUserClassOptions != "") fBatchEnv->SetValue("UserClassOptions", fUserClassOptions);
701  }
702  fBatchEnv->SetValue("NbToRead", (Double_t)nbEventToRead);
703  fBatchEnv->SetValue("LaunchDirectory", gSystem->WorkingDirectory());
704  if (fIncludes.Length()) {
705  fBatchEnv->SetValue("UserIncludes", fIncludes.Data());
706  }
707  if (fLibraries.Length()) {
708  fBatchEnv->SetValue("UserLibraries", fLibraries.Data());
709  }
710 
711  if (save) fBatchEnv->SaveLevel(kEnvUser);
712 }
713 
714 
715 
716 
721 
723 {
724  //Read the batch env file "filename" and initialise the analysis task using the
725  //informations in the file
726  //Returns kTRUE if all goes well
727 
728  Bool_t ok = kFALSE;
729 
730  OpenBatchInfoFile(filename);
731 
732  if (!GetAnalysisTask()) {
733  // we only look for the analysis task here if it has not already been set -
734  // see KVDataSetAnalyser::ReadBatchEnvFile, where if the dataset modifies the
735  // title of the analysis task, only the required dataset can be used to set the task
736  KVString val = fBatchEnv->GetValue("AnalysisTask", "");
737  SetAnalysisTask(nullptr);
738  if (val != "") {
739  if (!gDataSetManager) {
740  gDataSetManager = new KVDataSetManager;
741  gDataSetManager->Init();
742  }
743  SetAnalysisTask(gDataSetManager->GetAnalysisTaskAny(val.Data()));
744  } else {
745  Error("ReadBatchEnvFile", "Name of analysis task not given");
746  return ok;
747  }
748  if (!GetAnalysisTask()) {
749  Error("ReadBatchEnvFile", "Analysis task \"%s\"not found for dataset %s",
750  val.Data(), gDataSet->GetName());
751  return ok;
752  }
753  }
754 
755  nbEventToRead = (Long64_t)fBatchEnv->GetValue("NbToRead", -1);
756  SetUserIncludes(fBatchEnv->GetValue("UserIncludes", ""));
757  SetUserLibraries(fBatchEnv->GetValue("UserLibraries", ""));
758 
759  //batch system
760  if (strcmp(fBatchEnv->GetValue("BatchSystem", ""), "")) {
761  fBatchSystem = gBatchSystemManager->GetBatchSystem(fBatchEnv->GetValue("BatchSystem", ""));
762  fBatchSystem->ReadBatchEnvFile(GetBatchInfoFile());
763  fBatchSystem->cd(); // make gBatchSystem point to it
764  fBatchSystem->SetAnalyser(this);
765  }
766 
767  //User files
768  if (fTask->WithUserClass()) {
769  fUserClass = fBatchEnv->GetValue("UserClass", "");
770  if (fUserClass == "") {
771  Error("ReadBatchEnvFile", "Name of user class not given");
772  fBatchEnv->Print();
773  return ok;
774  }
775  fUserClassOptions = fBatchEnv->GetValue("UserClassOptions", "");
776  fUserClassImp = fBatchEnv->GetValue("UserClassImp", "");
777  if (fUserClassImp == "") {
778  Error("ReadBatchEnvFile", "Name of user class implementation file not given");
779  return ok;
780  }
781  fUserClassDec = fBatchEnv->GetValue("UserClassDec", "");
782  if (fUserClass == "") {
783  Error("ReadBatchEnvFile", "Name of user class header file not given");
784  return ok;
785  }
786  fUserClassAlternativeBaseClass = fBatchEnv->GetValue("UserClassAlternativeBaseClass", "");
787 
788  //If current working directory is not the same as the launch directory,
789  //we have to copy the user's files here
790  if (!RunningInLaunchDirectory()) {
791  TString launchDir = fBatchEnv->GetValue("LaunchDirectory", gSystem->WorkingDirectory());
792  TString path_src, path_trg;
793  //copy user's implementation file
794  AssignAndDelete(path_src, gSystem->ConcatFileName(launchDir.Data(), fUserClassImp.Data()));
795  AssignAndDelete(path_trg, gSystem->ConcatFileName(gSystem->WorkingDirectory(), fUserClassImp.Data()));
796  gSystem->CopyFile(path_src.Data(), path_trg.Data());
797  //copy user's header file
798  AssignAndDelete(path_src, gSystem->ConcatFileName(launchDir.Data(), fUserClassDec.Data()));
799  AssignAndDelete(path_trg, gSystem->ConcatFileName(gSystem->WorkingDirectory(), fUserClassDec.Data()));
800  gSystem->CopyFile(path_src.Data(), path_trg.Data());
801  }
802  } else {
803  // a task without a user class may still need to pass options to the predefined analysis class
804  fUserClassOptions = fBatchEnv->GetValue("UserClassOptions", "");
805  }
806 
807  ok = kTRUE;
808 
809  return ok;
810 }
811 
812 
813 
814 
818 
820 {
821  //Returns kTRUE if current working directory is same as launch directory for batch job
822  //When not in batch mode, always returns kTRUE.
823  if (!BatchMode() || !fBatchEnv) return kTRUE;
824  TString launchDir = fBatchEnv->GetValue("LaunchDirectory", gSystem->WorkingDirectory());
825  return (launchDir == gSystem->WorkingDirectory());
826 }
827 
828 
829 
830 
832 
834 {
835  the_analyser->SetParent(this);
836  the_analyser->SetAnalysisTask(fTask);
837  the_analyser->SetNbEventToRead(GetNbEventToRead());
838  the_analyser->SetUserIncludes(fIncludes.Data());
839  the_analyser->SetUserLibraries(fLibraries.Data());
840 }
841 
842 
843 
849 
851 {
852  //In interactive mode, the data analysis task is performed by
853  //instanciating and initialising the KVDataAnalyser child class specified by the task,
854  //and then calling its Run() method.
855  //In batch mode, the job is submitted to the chosen batch system.
856 
857  KVString task_data_analyser = fTask->GetDataAnalyser();
858  Info("SubmitTask", "fTask->GetDataAnalyser()=%s", task_data_analyser.Data());
859  unique_ptr<KVDataAnalyser> the_analyser;
860  if (task_data_analyser == "UserClass") {
861  //the user-provided class is to be used as analyser
862  the_analyser.reset((KVDataAnalyser*)GetInstanceOfUserClass());
863  } else {
864  the_analyser.reset(GetAnalyser(fTask->GetDataAnalyser()));
865  }
866  if (!the_analyser.get())
867  Fatal("SubmitTask", "the_analyser is 0x0, go to crash");
868 
869  set_up_analyser_for_task(the_analyser.get());
870 
871  if (fTask->WithUserClass()) {
872  the_analyser->SetUserClass(GetUserClass(), kFALSE);
873  the_analyser->SetUserClassOptions(fUserClassOptions);
874  } else if (strcmp(fTask->GetUserBaseClass(), "")) the_analyser->SetUserClass(fTask->GetUserBaseClass(), kFALSE);
875  if (!BatchMode()) {
876  //when not in batch mode i.e. when submitting a task, we ask the user to supply
877  //any further information required by the task, and then ask whether to run in
878  //interactive or batch mode
879  the_analyser->CheckTaskVariables();
880  if (!fChoseRunMode) ChooseRunningMode();
881  }
882  the_analyser->SetBatchMode(BatchMode());
883  the_analyser->SetBatchName(GetBatchName());
884  the_analyser->SetBatchSystem(fBatchSystem);
885  the_analyser->SetProofMode(GetProofMode());
886  //set global pointer to analyser object which performs the analysis
887  //this allows e.g. user class to obtain information on the analysis task
888  gDataAnalyser = the_analyser.get();
889  the_analyser->Run();
890 }
891 
892 
893 
894 
901 
903 {
904  //Replace any 'special' symbols in "format" with their current values
905  //
906  // $Date : current date and time
907  // $User : name of user
908  // $UserClass : name of user's analysis class
909 
910  KVString tmp = format;
911  TDatime now;
912  KVString stDate = now.AsSQLString();
913  stDate.ReplaceAll(" ", "-");
914  tmp.ReplaceAll("$Date", stDate.Data());
915  if (fUserClass.Length()) tmp.ReplaceAll("$UserClass", fUserClass.Data());
916  else if (fTask) tmp.ReplaceAll("$UserClass", fTask->GetDataAnalyser());
917  tmp.ReplaceAll("$User", gSystem->GetUserInfo()->fUser.Data());
918  return tmp;
919 }
920 
921 
922 
924 
926 {
927  static TString keywords = "Will be expanded: $Date, $User, $UserClass";
928  return keywords;
929 }
930 
931 
932 
933 
934 
935 
939 
941 {
942  // Returns full path to job submission directory for batch jobs.
943  // Returns current working directory for non-batch jobs.
944 
945  if (!BatchMode() || !fBatchEnv) return gSystem->WorkingDirectory();
946  return fBatchEnv->GetValue("LaunchDirectory", gSystem->WorkingDirectory());
947 }
948 
949 
950 
957 
959 {
960  // Use this method to get the full path to a file in the directory where the job was launched.
961  //
962  // When not using a batch system, this will just be the current working directory.
963  //
964  // If the job is actually running elsewhere, use this method to access a file in the launch directory.
965 
966  TString fullpath;
967  AssignAndDelete(fullpath, gSystem->ConcatFileName(GetLaunchDirectory(), f.Data()));
968  return fullpath;
969 }
970 
971 
972 
975 
977 {
978  // Returns full path to file used to store status of running batch jobs
979 
980  if (!BatchMode() || !fBatchEnv) return "";
981 
982  static TString filename = "";
983  TString statfile;
984  statfile.Form("%s.status", gBatchSystem->GetJobName());
985 
986  TString launchDir = GetLaunchDirectory();
987  AssignAndDelete(filename, gSystem->ConcatFileName(launchDir.Data(), statfile.Data()));
988  return filename;
989 }
990 
991 
992 
995 
997 {
998  // Update infos in batch status file
999 
1000  if (!BatchMode() || !fBatchEnv) return;
1001 
1002  TEnv stats(GetBatchStatusFileName());
1003  stats.SetValue("TotalEvents", totev);
1004  stats.SetValue("EventsRead", evread);
1005  disk.Remove(TString::kTrailing, '\t');
1006  disk.Remove(TString::kTrailing, ' ');
1007  disk.Remove(TString::kTrailing, '\t');
1008  stats.SetValue("DiskUsed", disk.Data());
1009  stats.SaveLevel(kEnvLocal);
1010 }
1011 
1012 
1013 
1016 
1018 {
1019  // Delete batch status file (and backup - '.bak') for batch job
1020 
1021  if (!BatchMode() || !fBatchEnv) return;
1022  TString stats = GetBatchStatusFileName();
1023  gSystem->Unlink(stats);
1024  stats += ".bak";
1025  gSystem->Unlink(stats);
1026 }
1027 
1028 
1029 
1033 
1035 {
1036  // Returns kTRUE if the number of events coincides with the interval
1037  // set for status updates for the current data analysis task
1038  return (!(nevents % fTask->GetStatusUpdateInterval()) && nevents);
1039 }
1040 
1041 
1042 
1045 
1047 {
1048  // Print infos on events treated, disk usage, memory usage
1049 
1050  cout << " +++ " << nevents << " events processed +++ " << endl;
1051  ProcInfo_t pid;
1052  if (gSystem->GetProcInfo(&pid) == 0) {
1053  cout << " ------------- Process infos -------------" << endl;
1054  printf(" CpuSys = %f s. CpuUser = %f s. ResMem = %f MB VirtMem = %f MB\n",
1055  pid.fCpuSys, pid.fCpuUser, pid.fMemResident / 1024.,
1056  pid.fMemVirtual / 1024.);
1057  }
1058 }
1059 
1060 
1061 
1062 
1067 
1069 {
1070  //Ask user to choose between immediate or batch execution
1071  //If the choice is batch, we ask to choose a batch system and whether or not
1072  //to use the "multijobs" mode
1073 
1074  fChoseRunMode = kTRUE;
1075  KVString tmp;
1076  do {
1077  cout << endl << "Run in Interactive or Batch mode (I or B) ? : ";
1078  tmp.ReadLine(cin);
1079  } while (tmp != "i" && tmp != "I" && tmp != "b" && tmp != "B");
1080  tmp.ToUpper();
1081  //interactive mode - no more to do
1082  if (tmp == "I") {
1083  fBatchSystem = 0;
1084  return;
1085  }
1086  cout << endl << "Choose the batch system to use : " << endl;
1087  gBatchSystemManager->Print();
1088  do {
1089  cout << "(enter a number) : " << endl;
1090  tmp.ReadLine(cin);
1091  } while (!tmp.IsDigit());
1092  fBatchSystem = gBatchSystemManager->GetBatchSystem(tmp.Atoi());
1093  fBatchSystem->Clear();
1094 }
1095 
1096 
1097 
1098 
1102 
1104 {
1105  //Fill TList with list of files in current working directory.
1106  //If ls!=0 it is deleted beforehand
1107  if (*ls) delete(*ls);
1108  TSystemDirectory dir("LocDir", gSystem->WorkingDirectory());
1109  (*ls) = dir.GetListOfFiles();
1110 }
1111 
1112 
1113 
1114 
1119 
1121 {
1122  //Compare the two lists of files in the current working directory, before and after analysis;
1123  //and copy any files which were created during the analysis to the launch directory.
1124  //Files with the same names in the launch directory will be overwritten if they exist.
1125 
1126  if (!fWorkDirInit || !fWorkDirEnd) return;
1127  TString launchDir = fBatchEnv->GetValue("LaunchDirectory", gSystem->WorkingDirectory());
1128  TIter next_new_file(fWorkDirEnd);
1129  TObject* file;
1130  while ((file = next_new_file())) {
1131  if (!fWorkDirInit->FindObject(file->GetName())) {
1132  TString fname;
1133  fname.Form("%s", file->GetName());
1134  //ajout d une condition pour eviter le transfert des file*.so generes par les KVParticleCondition
1135  //et aussi les .d generes par les KVParticleCondition
1136  if (!(fname.BeginsWith("KVParticleCondition_") || fname.EndsWith(".so") || fname.EndsWith(".d") || fname.EndsWith(".pcm") || fname.EndsWith(".bak"))) {
1137  TString path_src, path_trg;
1138  AssignAndDelete(path_trg, gSystem->ConcatFileName(launchDir.Data(), file->GetName()));
1140  file->GetName()));
1141  Info("CopyAnalysisResultsToLaunchDirectory", "Copying analysis results file :\n%s ---> %s",
1142  path_src.Data(), path_trg.Data());
1143  //copy & overwrite any existing file in launch directory
1144  if (gSystem->CopyFile(path_src.Data(), path_trg.Data(), kTRUE) == 0) {
1145  Info("CopyAnalysisResultsToLaunchDirectory", "File copied correctly");
1146  } else {
1147  Info("CopyAnalysisResultsToLaunchDirectory", " **** ERROR copying file !!! ");
1148  }
1149  }
1150  }
1151  }
1152 }
1153 
1154 
1155 
1156 
1161 
1163 {
1164  // Store lots of useful information about the current version of KaliVeda,
1165  // ROOT, etc. etc. in a TEnv object which will be added to the TTree's
1166  // list of user infos (TTree::GetUserInfo).
1167 
1168  tt->GetUserInfo()->Add(new TEnv());
1169  TEnv* kvenv = (TEnv*)tt->GetUserInfo()->FindObject("TEnv");
1170 
1171 //----
1172  THashList* hh = gEnv->GetTable();
1173  KVString tamp;
1174  for (Int_t kk = 0; kk < hh->GetEntries(); kk += 1) {
1175  tamp.Form("%s", hh->At(kk)->GetName());
1176  if (tamp.BeginsWith("Plugin.")) {}
1177  else kvenv->SetValue(hh->At(kk)->GetName(), ((TEnvRec*)hh->At(kk))->GetValue(), kEnvUser);
1178  }
1179 
1180  kvenv->SetValue("KVBase::GetKVVersion()", KVBase::GetKVVersion(), kEnvUser);
1181  kvenv->SetValue("KVBase::GetKVBuildDate()", KVBase::GetKVBuildDate(), kEnvUser);
1182  kvenv->SetValue("KVBase::GetKVBuildUser()", KVBase::GetKVBuildUser(), kEnvUser);
1183  kvenv->SetValue("KVBase::GetKVSourceDir()", KVBase::GetKVSourceDir(), kEnvUser);
1184 
1185 #ifdef WITH_BZR_INFOS
1186  kvenv->SetValue("KVBase::bzrRevisionId()", KVBase::bzrRevisionId(), kEnvUser);
1187  kvenv->SetValue("KVBase::bzrRevisionDate()", KVBase::bzrRevisionDate(), kEnvUser);
1188  kvenv->SetValue("KVBase::bzrBranchNick()", KVBase::bzrBranchNick(), kEnvUser);
1189  kvenv->SetValue("KVBase::bzrRevisionNumber()", KVBase::bzrRevisionNumber());
1190  kvenv->SetValue("KVBase::bzrIsBranchClean()", KVBase::bzrIsBranchClean());
1191 #endif
1192 #ifdef WITH_GIT_INFOS
1193  kvenv->SetValue("KVBase::gitBranch()", KVBase::gitBranch(), kEnvUser);
1194  kvenv->SetValue("KVBase::gitCommit()", KVBase::gitCommit(), kEnvUser);
1195 #endif
1196 
1197  kvenv->SetValue("gROOT->GetVersion()", gROOT->GetVersion(), kEnvUser);
1198 
1199  kvenv->SetValue("gSystem->GetBuildArch()", gSystem->GetBuildArch(), kEnvUser);
1200  kvenv->SetValue("gSystem->GetBuildCompiler()", gSystem->GetBuildCompiler(), kEnvUser);
1201  kvenv->SetValue("gSystem->GetBuildCompilerVersion()", gSystem->GetBuildCompilerVersion(), kEnvUser);
1202  kvenv->SetValue("gSystem->GetBuildNode()", gSystem->GetBuildNode(), kEnvUser);
1203  kvenv->SetValue("gSystem->GetBuildDir()", gSystem->GetBuildDir(), kEnvUser);
1204 
1205  kvenv->SetValue("gSystem->GetUserInfo()->fUser", gSystem->GetUserInfo()->fUser, kEnvUser);
1206  kvenv->SetValue("gSystem->HostName()", gSystem->HostName(), kEnvUser);
1207 
1208  if (fBatchEnv) {
1209  THashList* hh = fBatchEnv->GetTable();
1210  for (Int_t kk = 0; kk < hh->GetEntries(); kk += 1) {
1211  tamp.Form("%s", hh->At(kk)->GetName());
1212  if (!strcmp(kvenv->GetValue(hh->At(kk)->GetName(), "rien"), "rien"))
1213  kvenv->SetValue(hh->At(kk)->GetName(), ((TEnvRec*)hh->At(kk))->GetValue(), kEnvUser);
1214  }
1215  }
1216 
1217 
1218 }
1219 
1220 
1221 
1227 
1229 {
1230  //Set up and run data analysis task.
1231  //This allows to choose a dataset and a data analysis task and then execute the task or submit a batch job.
1232  //The behaviour of the data analyser object (base class KVDataAnalyser) can be modified by choosing
1233  //a plugin class corresponding to one of the plugins defined in $KVROOT/KVFiles/.kvrootrc.
1234 
1235  KVDataAnalyser* datan = 0;
1236  TString tmp(uri);
1237  if (tmp != "") {
1238  //got plugin ?
1239  TPluginHandler* ph = KVBase::LoadPlugin("KVDataAnalyser", uri);
1240  if (!ph)
1241  ::Warning("KVDataAnalyser::RunAnalyser", "No plugin %s found for KVDataAnalyser",
1242  uri);
1243  else
1244  datan = (KVDataAnalyser*) ph->ExecPlugin(0);
1245  }
1246  if (datan == 0)
1247  datan = new KVDataAnalyser;
1248  datan->RunMenus();
1249  delete datan;
1250 }
1251 
1252 
1253 
1258 
1260 {
1261  // Static method KVDataAnalyser::IsRunningBatchAnalysis()
1262  // Returns kTRUE if an analysis task is being performed in batch mode
1263  // Returns kFALSE if no analysis task is in interactive mode, or no analysis task running
1264 
1265  if (gDataAnalyser) return (gDataAnalyser->BatchMode() && gDataAnalyser->fBatchSystem);
1266  return kFALSE;
1267 }
1268 
1269 
1270 
1276 
1278 {
1279  // Create a KVNameValueList called "JobDescriptionList" and add it to
1280  // the TList. The parameters in the list describe the properties of the
1281  // current job. The TList pointer could be, for example, the address of
1282  // the TSelector::fInput list used by PROOF.
1283 
1284  KVNameValueList* jdl = new KVNameValueList("JobDescriptionList", "Job parameters");
1285 
1286  jdl->SetValue("AnalysisTask", fTask->GetType());
1287  jdl->SetValue("PROOFMode", GetProofMode());
1288 
1289  l->Add(jdl);
1290 }
1291 
1292 
1293 
1296 
1298 {
1299  // TO IMPLEMENT ?
1300 }
1301 
1302 
1303 
1306 
1308 {
1309  // TO IMPLEMENT ?
1310 }
1311 
1312 
int Int_t
#define SafeDelete(p)
#define f(i)
bool Bool_t
char Char_t
constexpr Bool_t kFALSE
double Double_t
constexpr Bool_t kTRUE
R__EXTERN TEnv * gEnv
kEnvUser
kEnvLocal
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 Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
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 Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t format
#define gROOT
char * Form(const char *fmt,...)
void AssignAndDelete(TString &target, char *tobedeleted)
R__EXTERN TSystem * gSystem
static Bool_t FindClassSourceFiles(const Char_t *class_name, KVString &imp_file, KVString &dec_file, const Char_t *dir_name=".")
Definition: KVBase.cpp:1102
static const Char_t * GetKVBuildDate()
Returns KaliVeda build date.
Definition: KVBase.cpp:900
static const Char_t * gitCommit()
Returns last git commit of sources.
Definition: KVBase.cpp:976
static const Char_t * GetKVBuildUser()
Returns username of person who performed build.
Definition: KVBase.cpp:887
static const Char_t * gitBranch()
Returns git branch of sources.
Definition: KVBase.cpp:964
static const Char_t * GetKVSourceDir()
Returns top-level directory of source tree used for build.
Definition: KVBase.cpp:938
static void PrintSplashScreen()
Prints welcome message and infos on version etc.
Definition: KVBase.cpp:1593
static TPluginHandler * LoadPlugin(const Char_t *base, const Char_t *uri="0")
Definition: KVBase.cpp:793
static const Char_t * GetKVVersion()
Returns KaliVeda version string.
Definition: KVBase.cpp:874
Handles list of all available batch systems for processing non-interactive data analysis tasks.
void Print(Option_t *opt="") const
KVBatchSystem * GetBatchSystem(const Char_t *name)
Get batch system by name.
virtual const Char_t * GetJobName() const
virtual void ReadBatchEnvFile(TEnv *)
virtual void Clear(Option_t *opt="")
Manager class which sets up and runs data analysis tasks.
const Char_t * GetACliCMode()
void DoStatusUpdate(Long64_t nevents) const
Print infos on events treated, disk usage, memory usage.
virtual TString ExpandAutoBatchName(const Char_t *format) const
void SetParent(KVDataAnalyser *da)
virtual void PostRunReset()
virtual void Run()
Check all task variables, then run analyser.
virtual void Reset()
virtual void AddJobDescriptionList(TList *)
virtual void WriteBatchEnvFile(const TString &, Bool_t sav=kTRUE)
void ChooseNbEventToRead()
Ask user to set number of events to read.
Bool_t RunningInLaunchDirectory()
void SetUserLibraries(const Char_t *libs=0)
void SetUserClass(const Char_t *kvs, Bool_t check=kTRUE)
virtual Bool_t CheckIfUserClassIsValid(const KVString &alternative_base_class="")
TString GetPathToFileInLaunchDirectory(const TString &) const
void WriteBatchInfo(TTree *)
virtual void RunMenus()
Run data analyser in menu-driven mode.
virtual Bool_t CheckTaskVariables()
Bool_t DoUserClassFilesExist()
const Char_t * GetLaunchDirectory() const
void SetAnalysisTask(KVDataAnalysisTask *at)
virtual const Char_t * GetRecognisedAutoBatchNameKeywords() const
virtual void set_up_analyser_for_task(KVDataAnalyser *the_analyser)
virtual Bool_t CheckStatusUpdateInterval(Long64_t nevents) const
virtual Bool_t CheckWhatToAnalyseAndHow()
virtual void SubmitTask()
const Char_t * GetBatchStatusFileName() const
Returns full path to file used to store status of running batch jobs.
virtual void ChooseWhatToAnalyse()
TO IMPLEMENT ?
KVDataAnalyser()
Default constructor.
static Bool_t fCleanAbort
flag to force abort of processing
static KVDataAnalyser * GetAnalyser(const Char_t *plugin)
static Bool_t IsRunningBatchAnalysis()
static void RunAnalyser(const Char_t *plugin="")
void ScanWorkingDirectory(TList **)
void ChooseUserClass()
Choose the user's analysis class.
void CopyAnalysisResultsToLaunchDirectory()
virtual Bool_t ReadBatchEnvFile(const TString &)
void DeleteBatchStatusFile() const
Delete batch status file (and backup - '.bak') for batch job.
void SetUserIncludes(const Char_t *incDirs=0)
virtual void ChooseWhatToDo()
TO IMPLEMENT ?
Bool_t BatchMode() const
void UpdateBatchStatusFile(Int_t totev, Int_t evread, TString disk) const
Update infos in batch status file.
KVBatchSystem * fBatchSystem
batch system to use for submission of job
TObject * GetInstanceOfUserClass(const KVString &alternative_base_class="")
void SetNbEventToRead(Long64_t nb=0)
Define and manage data analysis tasks.
virtual const Char_t * GetPrereq() const
Manage all datasets contained in a given data repository.
virtual Bool_t Init(KVDataRepository *=0)
KVDataAnalysisTask * GetAnalysisTaskAny(const Char_t *keywords) const
Handles lists of named parameters with different types, a list of KVNamedParameter objects.
void SetValue(const Char_t *name, value_type value)
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
virtual Int_t GetEntries() const
virtual void SetOwner(Bool_t enable=kTRUE)
const char * AsSQLString() const
THashList * GetTable() const
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)
virtual void SaveLevel(EEnvLevel level)
TObject * At(Int_t idx) const override
const char * GetName() const override
const TString & GetString() const
virtual const char * GetName() const
virtual Bool_t InheritsFrom(const char *classname) const
Longptr_t ExecPlugin(int nargs)
Ssiz_t Length() const
Int_t Atoi() const
std::istream & ReadToDelim(std::istream &str, char delim='\n')
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
const char * Data() const
Bool_t IsDigit() const
void ToUpper()
TObjArray * Tokenize(const TString &delim) const
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
void Form(const char *fmt,...)
TString & Remove(EStripType s, char c)
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
TString & ReplaceAll(const char *s1, const char *s2)
std::istream & ReadLine(std::istream &str, Bool_t skipWhite=kTRUE)
virtual TList * GetListOfFiles() const
virtual const char * GetBuildNode() const
virtual const char * GetBuildCompilerVersion() const
virtual const char * GetBuildDir() const
virtual void AddIncludePath(const char *includePath)
virtual int CopyFile(const char *from, const char *to, Bool_t overwrite=kFALSE)
virtual const char * Getenv(const char *env)
virtual const char * GetIncludePath()
virtual char * ConcatFileName(const char *dir, const char *name)
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
virtual UserGroup_t * GetUserInfo(const char *user=nullptr)
virtual int GetProcInfo(ProcInfo_t *info) const
virtual const char * HostName()
virtual const char * WorkingDirectory()
virtual const char * GetBuildCompiler() const
virtual const char * GetLibraries(const char *regexp="", const char *option="", Bool_t isRegexp=kTRUE)
virtual const char * GetBuildArch() const
virtual int Unlink(const char *name)
long long Long64_t
RooCmdArg ClassName(const char *name)
void Error(const char *location, const char *fmt,...)
void Info(const char *location, const char *fmt,...)
void Fatal(const char *location, const char *fmt,...)
void Warning(const char *location, const char *fmt,...)
RooCmdArg BatchMode(std::string const &batchMode)
Long_t fMemVirtual
Float_t fCpuSys
Long_t fMemResident
Float_t fCpuUser
TString fUser
TLine l
auto * tt
ClassImp(TPyArg)