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 "TSystem.h"
9 #include "KVBase.h"
10 #include "KVDataAnalyser.h"
11 #include "KVDataAnalysisTask.h"
12 #include "KVDataSetManager.h"
13 #include "KVString.h"
14 #include "TObjString.h"
15 #include "TObjArray.h"
16 #include "Riostream.h"
17 #include "KVBatchSystemManager.h"
18 #include "TPluginManager.h"
19 #include "TSystemDirectory.h"
20 #include "TROOT.h"
21 #include "TClass.h"
22 #include "THashList.h"
23 #include "KVError.h"
24 
25 using namespace std;
27 
29 
30 KVDataAnalyser* gDataAnalyser = 0;
31 
32 
35 
37 {
38  //Default constructor.
39  fParent = nullptr;
40  fBatch = kFALSE;
41  fTask = nullptr;
42  fQuit = kFALSE;
43  fSubmit = kFALSE;
44  nbEventToRead = -1;
45  fUserClassIsOK = kFALSE;
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 
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.reset();
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  }
114  else {
115  if (BatchMode() && fBatchSystem && !fParent) fBatchSystem->Print("log");
116  if (!RunningInLaunchDirectory() && fParent) {
117  //when batch job runs in directory different to launch directory,
118  //we scan the list of files present in the current working directory
119  //just prior to running the analysis task
120  ScanWorkingDirectory(&fWorkDirInit);
121  }
122  if (!PreSubmitCheck()) return;
123 
124  // The following horrific kludge is supposed to solve the following problem:
125  // when running in batch mode (GridEngine) the data analyser created in
126  // KaliVedaAnalysis.cpp has to be of the right type (KVSimDirAnalyser or KVDataSetAnalyser)
127  // in order for it to read all necessary informations from the batch env file
128  // by calling the appropriate ReadBatchEnvFile override.
129  // However, when Run() is called for this object from KaliVedaAnalysis.cpp,
130  // we have to call the KVDataAnalyser::SubmitTask method, not the override in the
131  // derived class.
132  if (fUseBaseClassSubmitTask)
134  else
135  SubmitTask();
136 
137  if (!RunningInLaunchDirectory() && fParent) {
138  //when batch job runs in directory different to launch directory,
139  //we scan the list of files present in the current working directory
140  //just after running the analysis task
141  ScanWorkingDirectory(&fWorkDirEnd);
142  //any files which are present in the second list which were not present
143  //in the first list will be copied back to the launch directory
144  CopyAnalysisResultsToLaunchDirectory();
145  }
146  if (BatchMode() && fBatchSystem && !fParent) {
147  // at end of batch jobs,
148  // remove .[jobname] and [jobname].status files from $HOME directory
149  // remove .[jobname].bak and [jobname].status.bak files from $HOME directory
150  TString ff;
151  AssignAndDelete(ff, gSystem->ConcatFileName(gSystem->Getenv("HOME"), Form(".%s", GetBatchName())));
152  gSystem->Unlink(ff);
153  AssignAndDelete(ff, gSystem->ConcatFileName(gSystem->Getenv("HOME"), Form(".%s.bak", GetBatchName())));
154  gSystem->Unlink(ff);
155  AssignAndDelete(ff, gSystem->ConcatFileName(gSystem->Getenv("HOME"), Form("%s.status", GetBatchName())));
156  gSystem->Unlink(ff);
157  AssignAndDelete(ff, gSystem->ConcatFileName(gSystem->Getenv("HOME"), Form("%s.status.bak", GetBatchName())));
158  gSystem->Unlink(ff);
159  }
160  }
161  }
162  PostRunReset();
163 }
164 
165 
166 
167 
170 
172 {
173  //Run data analyser in menu-driven mode
174 
175  fMenus = kTRUE;
176  Reset();
178 
179  while (!fQuit) {
180  if (NeedToChooseWhatToDo())
181  ChooseWhatToDo();
182  else if (NeedToChooseWhatToAnalyse())
183  ChooseWhatToAnalyse();
184  else if (fSubmit) {
185  Run();
186  Reset();
188  }
189  }
190 }
191 
192 
193 
194 
199 
201 {
202  //Checks the task variables
203  //In batch mode, we first set the task variables by reading the
204  //batch env file associated with the name set for the batch job
205 
206  if (BatchMode()) ReadBatchEnvFile(Form(".%s", GetBatchName()));
207 
208  //if (!CheckWhatToAnalyseAndHow()) return kFALSE;
209 
210  if (fTask->WithUserClass() && fUserClass.name != ClassName()) {
211  //task requires user analysis class
212  if (fUserClass.name.IsNull()) {
213  if (BatchMode()) return kFALSE; // avoid infinite loop in batch mode
214  ChooseUserClass();
215  }
216 
217  if (!CheckIfUserClassIsValid(fUserClassAlternativeBaseClass)) {
218  cout << "============> Warning <=============" << endl;
219  cout << GetUserClassName() << " is not a valid " << fTask->GetUserBaseClass() << endl;
220  cout << "Analysis aborted." << endl;
221  cout << "====================================" << endl;
222  /*if (BatchMode())*/ return kFALSE; // avoid infinite loop in batch mode
223  //ChooseUserClass();
224  }
225  }
226 
227  if (nbEventToRead < 0) {
228  ChooseNbEventToRead();
229  }
230 
231  return kTRUE;
232 }
233 
234 
235 
237 
239 {
240  if (NeedToChooseWhatToDo()) {
241  return kFALSE;
242  }
243 
244  if (NeedToChooseWhatToAnalyse()) {
245  return kFALSE;
246  }
247  return kTRUE;
248 }
249 
250 
251 
252 
253 
254 
259 
261 {
262  //Set analysis task and data type
263  //For ways of obtaining pointers to data analysis tasks for any given dataset,
264  //see method KVDataSet::GetAnalysisTask(const Char_t* keywords) const.
265  fTask = at;
266  if (at)
267  fDataType = at->GetPrereq();
268  else
269  fDataType = "";
270 }
271 
272 
273 
274 
278 
280 {
281 // Add to the includes paths the user's includes paths
282 // the includes paths have to be separated by a white space
283 
284  fIncludes = "";
285  if (!incDirs) {
286  return;
287  }
288  TString tmp = incDirs;
289  TString curIncDir = gSystem->GetIncludePath();
290  TObjArray* oa = tmp.Tokenize(" ");
291  oa->SetOwner(kTRUE);
292  TIter next(oa);
293  TObjString* st = 0;
294  while ((st = (TObjString*)next())) {
295  TString id = st->GetString();
296  if (id.Length()) {
297  fIncludes += id.Data();
298  fIncludes += " ";
299  if (!curIncDir.Contains(id.Data())) {
300  cout << "Include path \"" << id.Data() << "\" added." << endl;
301  id.Prepend("-I");
302  gSystem->AddIncludePath(id.Data());
303  }
304  }
305  }
306  delete oa;
307 }
308 
309 
310 
311 
315 
317 {
318 // Load the user's libraries
319 // the libraries have to be separated by a white space
320 
321  fLibraries = "";
322  if (!libs) {
323  return;
324  }
325  KVString tmp = libs;
326  KVString slib = gSystem->GetLibraries("", "D");
327 
328  tmp.Begin(" ");
329  while (!tmp.End()) {
330 
331  KVString id = tmp.Next();
332 
333  Bool_t loaded = kFALSE;
334  slib.Begin(" ");
335  while (!slib.End() && !loaded) {
336  KVString ss = slib.Next();
337  if (ss == id) {
338  Info("SetUserLibraries", "%s already load", id.Data());
339  loaded = kTRUE;
340  }
341  else {
342  }
343  }
344  if (!loaded) {
345  Info("SetUserLibraries", "Library \"%s\"added.", id.Data());
346  gSystem->Load(id.Data());
347  }
348  fLibraries += id.Data();
349  fLibraries += " ";
350  }
351 
352 }
353 
354 
355 
356 
359 
361 {
362  // Ask user to set number of events to read
363 
364  SetNbEventToRead(-1);
365  while (nbEventToRead < 0) {
366  cout << "Give the number of events to read [<RET>=all]:" << endl;
367  KVString ntr;
368  ntr.ReadToDelim(cin);
369  if (ntr.IsDigit() || !ntr.Length()) {
370  if (ntr.Length()) {
371  nbEventToRead = (Long64_t) ntr.Atoi();
372  }
373  else {
374  nbEventToRead = 0;
375  }
376  }
377  else {
378  cout << "\"" << ntr.
379  Data() << "\" is not a number. Please retry." << endl;
380  }
381  }
382 }
383 
384 
385 
386 
390 
392 {
393  //Creates an instance of a class derived from KVDataAnalyser defined as a plugin
394 
395  //check and load plugin library
396  TPluginHandler* ph;
397  if (!(ph = KVBase::LoadPlugin("KVDataAnalyser", plugin)))
398  return nullptr;
399 
400  //execute constructor
401  KVDataAnalyser* da = (KVDataAnalyser*) ph->ExecPlugin(0);
402 
403  return da;
404 }
405 
406 
407 
408 
411 
413 {
414  //Choose the user's analysis class
415  fUserClass.name = "";
416  while (!fUserClass.name.Length()) {
417  cout << "Give the name of the analysis class: ";
418  fUserClass.name.ReadLine(cin);
419  fUserClassIsOK = kFALSE;
420  }
421 }
422 
423 
424 
425 
429 
431 {
432  // Check if files containing user's class can be located.
433  // The names of the implementation and header files are stored in fUserClassImp and fUserClassDec.
434 
435  return KVBase::FindClassSourceFiles(fUserClass.name,
436  fUserClass.imp_file, fUserClass.dec_file, fUserClass.dir_name);
437 }
438 
439 
440 
441 
458 
460 {
461  //Return kTRUE if the name of the class given by the user (fUserClass) is valid
462  //for the analysis task. This is so if one of the following is true:
463  // - the class library has already been loaded. In this case the class will exist
464  // in the dictionary (gROOT->GetClass()); we check if it derived from the
465  // base class defined for the analysis task
466  // - a plugin exists defining this class as an extension of the base class defined
467  // for the analysis task (gROOT->GetPluginManager()->FindHandler(...): the URI for
468  // the plugin must be the same as the name of the class)
469  // - source files for the class are present in the working directory. In this case
470  // we can add a plugin handler for the class.
471  //In the latter two cases, the class is valid if compilation succeeds.
472  //
473  //If the user's class may in fact be derived from an alternative base class, rather
474  //than the base class defined for this analysis task (see KVDataAnalysisTask::SetUserBaseClass)
475  //you can supply the name of this class (or a comma-separated list of base classes).
476 
477  std::unique_ptr<TObject> o{GetInstanceOfUserClass(alternative_base_class)};
478  return (Bool_t)o;
479 }
480 
481 
482 
483 
495 
497 {
498  // Returns string to be appended to name of user class for compilation with ACliC in
499  // GetInstanceOfUserClass(). This depends on the boolean resources:
500  //
501  //~~~
502  // KVDataAnalyser.UserClass.Debug: ( "yes" => "g" )
503  // KVDataAnalyser.UserClass.Optimise: ( "yes" => "O" )
504  // KVDataAnalyser.UserClass.ForceRecompile: ( "no" => "+"; "yes" => "++" )
505  //~~~
506  //
507  // Note that if both Debug and Optimise are set to "yes/true", we use Debug mode (can't have BOTH debug & optimisation).
508 
509  static TString aclic;
510  if (gEnv->GetValue("KVDataAnalyser.UserClass.ForceRecompile", kFALSE)) aclic = "++";
511  else aclic = "+";
512  if (gEnv->GetValue("KVDataAnalyser.UserClass.Debug", kFALSE)) aclic += "g";
513  else if (gEnv->GetValue("KVDataAnalyser.UserClass.Optimise", kFALSE)) aclic += "O";
514  return aclic.Data();
515 }
516 
517 
518 
520 
522 {
523  fBatchSystem = nullptr;
524 }
525 
526 
527 
528 
546 
548 {
549  //Return an instance of the class given by the user (fUserClass), if it is valid.
550  //If the user class is given in the form of source code, it will be (re)compiled
551  //if it has not already been loaded and/or the source has changed since the last
552  //build, using ACliC. If the resource
553  //
554  //~~~
555  // KVDataAnalyser.UserClass.Debug: yes
556  //~~~
557  //
558  //is set, the user's class will be compiled with extra debugging information
559  //
560  //Once compiled, we check that the user's class is indeed derived from the base
561  //class defined for this analysis task (see KVDataAnalysisTask::SetUserBaseClass).
562  //If the user's class may in fact be derived from an alternative base class, you
563  //can supply the name of this class (or comma-separated list of base classes).
564 
565  // make sure any required plugin library defining base class for user's analysis class is loaded
566  if (!fTask->CheckUserBaseClassIsLoaded()) return 0x0;
567 
568  //do we have a plugin ?
569  TPluginHandler* ph = gROOT->GetPluginManager()->FindHandler(fTask->GetUserBaseClass(), fUserClass.name);
570  if (!ph) {//no plugin defined
571 
572  //if it is a precompiled class (i.e. already part of KaliVeda),
573  //it will be in the dictionary already
574  TClass* cl = gROOT->GetClass(fUserClass.name);
575 
576  //do we have source files ?
577  if (DoUserClassFilesExist()) {
578  //compile & load user's source files using ACLIC. ACliC options read by GetACliCMode() from .kvrootrc
579  TString cmd;
580  cmd.Form(".L %s%s", fUserClass.full_path_imp().Data(), GetACliCMode());
581  gROOT->ProcessLine(cmd.Data());
582  //class will be in dictionary if compilation successful
583  cl = gROOT->GetClass(fUserClass.name);
584  }
585  else if (!cl) {
586  //class not in dictionary and no source files. help!
587  Info("GetInstanceOfUserClass", "Class %s is unknown and no source files available",
588  fUserClass.name.Data());
589  return 0;
590  }
591  if (!cl) {
592  //compilation of user class has failed
593  Info("GetInstanceOfUserClass", "Compilation of class %s failed. Correct the mistakes and try again",
594  fUserClass.name.Data());
595  return 0;
596  }
597  if (!cl->GetBaseClass(fTask->GetUserBaseClass())) {
598  // class does not inherit from base class defined by analysis task
599  if (alternative_base_class == "") { // no alternative base classes provided
600  Info("GetInstanceOfUserClass", "Class %s does not inherit from correct base class (%s), or compilation of class %s failed. Correct the mistakes and try again",
601  fUserClass.name.Data(), fTask->GetUserBaseClass(), fUserClass.name.Data());
602  return nullptr;
603  }
604  else {
605  // check alternative base class(es) - it may still be good!
606  bool got_good_base = false;
607  TString good_base = "";
608  alternative_base_class.Begin(",");
609  while (!alternative_base_class.End()) {
610  good_base = alternative_base_class.Next(kTRUE);
611  if (cl->GetBaseClass(good_base)) {
612  got_good_base = true;
613  break;
614  }
615  }
616  if (got_good_base) {
617  Info("GetInstanceOfUserClass", "Class %s inherits from alternative base class %s: OK!",
618  fUserClass.name.Data(), good_base.Data());
619  }
620  else {
621  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",
622  fUserClass.name.Data(), fTask->GetUserBaseClass(), alternative_base_class.Data(), fUserClass.name.Data());
623  return nullptr;
624  }
625  }
626  }
627  //EVERYTHING OK!! now instanciate an object of the new class
628  return (TObject*)cl->New();
629  }
630  else {
631  Info("GetInstanceOfUserClass", "Found plugin handler for class %s",
632  fUserClass.name.Data());
633  //load class from plugin
634  ph = KVBase::LoadPlugin(fTask->GetUserBaseClass(), fUserClass.name.Data());
635  if (!ph) {
636  Info("GetInstanceOfUserClass", "KVBase::LoadPlugin failed for %s", fUserClass.name.Data());
637  return 0;
638  }
639  TObject* obj = (TObject*)ph->ExecPlugin(0);
640  if (obj) {
641  //Info("GetInstanceOfUserClass", "constructor OK for %s", fUserClass.Data());
642  if (obj->InheritsFrom(fTask->GetUserBaseClass())) return obj;
643  Info("GetInstanceOfUserClass", "%s does not inherit from %s", fUserClass.name.Data(), fTask->GetUserBaseClass());
644  return 0;
645  }
646  else {
647  Info("GetInstanceOfUserClass", "constructor not OK for %s", fUserClass.name.Data());
648  return 0;
649  }
650  }
651  return 0;
652 }
653 
654 
655 
656 
661 
663 {
664  //Set name of user analysis class.
665  //If check=kTRUE (default), we check the validity of the class
666  //if check=kFALSE we do not check and assume that the class is valid
667 
668  fUserClass = kvs;
669  if (check) {
670  fUserClassIsOK = CheckIfUserClassIsValid();
671  }
672  else {
673  fUserClassIsOK = kTRUE;
674  }
675 }
676 
677 
678 
679 
685 
687 {
688  //Save (in the TEnv fBatchEnv) all necessary information on analysis task which can be used to execute it later
689  //(i.e. when batch processing system executes the job).
690  //If save=kTRUE (default), write the information in a file whose name is given by ".jobname"
691  //where 'jobname' is the name of the job as given to the batch system.
692 
693  OpenBatchInfoFile(Form(".%s", jobname.Data()));
694  if (fBatchSystem) {
695  fBatchEnv->SetValue("BatchSystem", fBatchSystem->GetName());
696  fBatchSystem->WriteBatchEnvFile(GetBatchInfoFile());
697  }
698  fBatchEnv->SetValue("AnalysisTask", fTask->GetType());
699 
700  if (fTask->WithUserClass()) {
701  fBatchEnv->SetValue("UserClass", GetUserClass().name);
702  if (!GetUserClass().with_files()) {
703  if (!DoUserClassFilesExist()) {
704  Warning("WriteBatchEnvFile", "Source files for user class %s do not exist. Job will not work.",
705  GetUserClass().name.Data());
706  }
707  }
708  if (!GetUserClass().dir_name.IsNull()) {
709  // make sure we write an absolute pathname for the directory
710  gSystem->ExpandPathName(GetUserClass().dir_name);
711  fBatchEnv->SetValue("UserClassDir", GetUserClass().dir_name);
712  }
713  fBatchEnv->SetValue("UserClassOptions", fUserClassOptions);
714  fBatchEnv->SetValue("UserClassImp", GetUserClass().imp_file);
715  fBatchEnv->SetValue("UserClassDec", GetUserClass().dec_file);
716  }
717  else {
718  // a task without a user class may still need to pass options to the predefined analysis class
719  if (fUserClassOptions != "") fBatchEnv->SetValue("UserClassOptions", fUserClassOptions);
720  }
721  fBatchEnv->SetValue("NbToRead", (Double_t)nbEventToRead);
722  fBatchEnv->SetValue("LaunchDirectory", gSystem->WorkingDirectory());
723  if (fIncludes.Length()) {
724  fBatchEnv->SetValue("UserIncludes", fIncludes.Data());
725  }
726  if (fLibraries.Length()) {
727  fBatchEnv->SetValue("UserLibraries", fLibraries.Data());
728  }
729 
730  if (save) fBatchEnv->SaveLevel(kEnvUser);
731 }
732 
733 
734 
735 
740 
742 {
743  //Read the batch env file "filename" and initialise the analysis task using the
744  //informations in the file
745  //Returns kTRUE if all goes well
746 
747  Bool_t ok = kFALSE;
748 
749  OpenBatchInfoFile(filename);
750 
751  if (!GetAnalysisTask()) {
752  // we only look for the analysis task here if it has not already been set -
753  // see KVDataSetAnalyser::ReadBatchEnvFile, where if the dataset modifies the
754  // title of the analysis task, only the required dataset can be used to set the task
755  KVString val = fBatchEnv->GetValue("AnalysisTask", "");
756  SetAnalysisTask(nullptr);
757  if (val != "") {
758  if (!gDataSetManager) {
759  gDataSetManager = new KVDataSetManager;
760  gDataSetManager->Init();
761  }
762  SetAnalysisTask(gDataSetManager->GetAnalysisTaskAny(val.Data()));
763  }
764  else {
765  Error("ReadBatchEnvFile", "Name of analysis task not given");
766  return ok;
767  }
768  if (!GetAnalysisTask()) {
769  Error("ReadBatchEnvFile", "Analysis task \"%s\"not found for dataset %s",
770  val.Data(), gDataSet->GetName());
771  return ok;
772  }
773  }
774 
775  nbEventToRead = (Long64_t)fBatchEnv->GetValue("NbToRead", -1);
776  SetUserIncludes(fBatchEnv->GetValue("UserIncludes", ""));
777  SetUserLibraries(fBatchEnv->GetValue("UserLibraries", ""));
778 
779  //batch system
780  if (strcmp(fBatchEnv->GetValue("BatchSystem", ""), "")) {
781  fBatchSystem = gBatchSystemManager->GetBatchSystem(fBatchEnv->GetValue("BatchSystem", ""));
782  fBatchSystem->ReadBatchEnvFile(GetBatchInfoFile());
783  fBatchSystem->cd(); // make gBatchSystem point to it
784  fBatchSystem->SetAnalyser(this);
785  }
786 
787  //User files
788  if (fTask->WithUserClass()) {
789  fUserClass.name = fBatchEnv->GetValue("UserClass", "");
790  if (fUserClass.name.IsNull()) {
791  Error("ReadBatchEnvFile", "Name of user class not given");
792  fBatchEnv->Print();
793  return ok;
794  }
795  fUserClassOptions = fBatchEnv->GetValue("UserClassOptions", "");
796  fUserClass.dir_name = fBatchEnv->GetValue("UserClassDir", "");
797  fUserClass.imp_file = fBatchEnv->GetValue("UserClassImp", "");
798  if (fUserClass.imp_file.IsNull()) {
799  Error("ReadBatchEnvFile", "Name of user class implementation file not given");
800  return ok;
801  }
802  fUserClass.dec_file = fBatchEnv->GetValue("UserClassDec", "");
803  if (fUserClass.dec_file.IsNull()) {
804  Error("ReadBatchEnvFile", "Name of user class header file not given");
805  return ok;
806  }
807  fUserClassAlternativeBaseClass = fBatchEnv->GetValue("UserClassAlternativeBaseClass", "");
808 
809  //If current working directory is not the same as the launch directory,
810  //we have to copy the user's files here
811  if (!RunningInLaunchDirectory()) {
812  TString launchDir = fBatchEnv->GetValue("LaunchDirectory", gSystem->WorkingDirectory());
813  TString path_src, path_trg;
814  //copy user's implementation file
815  AssignAndDelete(path_trg, gSystem->ConcatFileName(gSystem->WorkingDirectory(), fUserClass.imp_file.Data()));
816  Info("ReadBatchEnvFile", "Copying %s to %s", fUserClass.full_path_imp().Data(), path_trg.Data());
817  gSystem->CopyFile(fUserClass.full_path_imp(), path_trg);
818  //copy user's header file
819  AssignAndDelete(path_trg, gSystem->ConcatFileName(gSystem->WorkingDirectory(), fUserClass.dec_file.Data()));
820  Info("ReadBatchEnvFile", "Copying %s to %s", fUserClass.full_path_dec().Data(), path_trg.Data());
821  gSystem->CopyFile(fUserClass.full_path_dec(), path_trg);
822  // change directory stored in UserClass
823  fUserClass.dir_name = ".";
824  }
825  }
826  else {
827  // a task without a user class may still need to pass options to the predefined analysis class
828  fUserClassOptions = fBatchEnv->GetValue("UserClassOptions", "");
829  }
830 
831  ok = kTRUE;
832 
833  return ok;
834 }
835 
836 
837 
838 
842 
844 {
845  //Returns kTRUE if current working directory is same as launch directory for batch job
846  //When not in batch mode, always returns kTRUE.
847  if (!BatchMode() || !fBatchEnv) return kTRUE;
848  TString launchDir = fBatchEnv->GetValue("LaunchDirectory", gSystem->WorkingDirectory());
849  return (launchDir == gSystem->WorkingDirectory());
850 }
851 
852 
853 
854 
856 
858 {
859  the_analyser->SetParent(this);
860  the_analyser->SetAnalysisTask(fTask);
861  the_analyser->SetNbEventToRead(GetNbEventToRead());
862  the_analyser->SetUserIncludes(fIncludes.Data());
863  the_analyser->SetUserLibraries(fLibraries.Data());
864 }
865 
866 
867 
874 
876 {
877  //In interactive mode, the data analysis task is performed by
878  //instanciating and initialising the KVDataAnalyser child class specified by the task,
879  //and then calling its Run() method.
880  //
881  //In batch mode, the job is submitted to the chosen batch system.
882 
883  KVString task_data_analyser = fTask->GetDataAnalyser();
884  Info("SubmitTask", "fTask->GetDataAnalyser()=%s", task_data_analyser.Data());
885  unique_ptr<KVDataAnalyser> the_analyser;
886  if (task_data_analyser == "UserClass") {
887  //the user-provided class is to be used as analyser
888  the_analyser.reset((KVDataAnalyser*)GetInstanceOfUserClass());
889  }
890  else {
891  the_analyser.reset(GetAnalyser(fTask->GetDataAnalyser()));
892  }
893  if (!the_analyser.get())
894  Fatal("SubmitTask", "the_analyser is 0x0, go to crash");
895 
896  set_up_analyser_for_task(the_analyser.get());
897 
898  if (fTask->WithUserClass()) {
899  the_analyser->SetUserClass(GetUserClass(), kFALSE);
900  the_analyser->SetUserClassOptions(fUserClassOptions);
901  }
902  else if (strcmp(fTask->GetUserBaseClass(), ""))
903  the_analyser->SetUserClass({fTask->GetUserBaseClass()}, kFALSE);
904  if (!BatchMode()) {
905  //when not in batch mode i.e. when submitting a task, we ask the user to supply
906  //any further information required by the task, and then ask whether to run in
907  //interactive or batch mode
908  the_analyser->CheckTaskVariables();
909  if (!fChoseRunMode) ChooseRunningMode();
910  }
911  the_analyser->SetBatchMode(BatchMode());
912  the_analyser->SetBatchName(GetBatchName());
913  the_analyser->SetBatchSystem(fBatchSystem);
914  the_analyser->SetProofMode(GetProofMode());
915  //set global pointer to analyser object which performs the analysis
916  //this allows e.g. user class to obtain information on the analysis task
917  gDataAnalyser = the_analyser.get();
918  the_analyser->Run();
919 }
920 
921 
922 
923 
930 
932 {
933  //Replace any 'special' symbols in "format" with their current values
934  //
935  // $Date : current date and time
936  // $User : name of user
937  // $UserClass : name of user's analysis class
938 
939  KVString tmp = format;
940  TDatime now;
941  KVString stDate = now.AsSQLString();
942  stDate.ReplaceAll(" ", "-");
943  tmp.ReplaceAll("$Date", stDate.Data());
944  if (fUserClass.name.Length()) tmp.ReplaceAll("$UserClass", fUserClass.name);
945  else if (fTask) tmp.ReplaceAll("$UserClass", fTask->GetDataAnalyser());
946  tmp.ReplaceAll("$User", gSystem->GetUserInfo()->fUser.Data());
947  return tmp;
948 }
949 
950 
951 
953 
955 {
956  static TString keywords = "Will be expanded: $Date, $User, $UserClass";
957  return keywords;
958 }
959 
960 
961 
965 
967 {
968  // Returns full path to job submission directory for batch jobs.
969  // Returns current working directory for non-batch jobs.
970 
971  if (!BatchMode() || !fBatchEnv) return gSystem->WorkingDirectory();
972  return fBatchEnv->GetValue("LaunchDirectory", gSystem->WorkingDirectory());
973 }
974 
975 
976 
983 
985 {
986  // Use this method to get the full path to a file in the directory where the job was launched.
987  //
988  // When not using a batch system, this will just be the current working directory.
989  //
990  // If the job is actually running elsewhere, use this method to access a file in the launch directory.
991 
992  TString fullpath;
993  AssignAndDelete(fullpath, gSystem->ConcatFileName(GetLaunchDirectory(), f.Data()));
994  return fullpath;
995 }
996 
997 
998 
1001 
1003 {
1004  // Returns full path to file used to store status of running batch jobs
1005 
1006  if (!BatchMode() || !fBatchEnv) return "";
1007 
1008  static TString filename = "";
1009  TString statfile;
1010  statfile.Form("%s.status", gBatchSystem->GetJobName());
1011 
1012  TString launchDir = GetLaunchDirectory();
1013  AssignAndDelete(filename, gSystem->ConcatFileName(launchDir.Data(), statfile.Data()));
1014  return filename;
1015 }
1016 
1017 
1018 
1021 
1023 {
1024  // Update infos in batch status file
1025 
1026  if (!BatchMode() || !fBatchEnv) return;
1027 
1028  TEnv stats(GetBatchStatusFileName());
1029  stats.SetValue("TotalEvents", totev);
1030  stats.SetValue("EventsRead", evread);
1031  disk.Remove(TString::kTrailing, '\t');
1032  disk.Remove(TString::kTrailing, ' ');
1033  disk.Remove(TString::kTrailing, '\t');
1034  stats.SetValue("DiskUsed", disk.Data());
1035  stats.SaveLevel(kEnvLocal);
1036 }
1037 
1038 
1039 
1042 
1044 {
1045  // Delete batch status file (and backup - '.bak') for batch job
1046 
1047  if (!BatchMode() || !fBatchEnv) return;
1048  TString stats = GetBatchStatusFileName();
1049  gSystem->Unlink(stats);
1050  stats += ".bak";
1051  gSystem->Unlink(stats);
1052 }
1053 
1054 
1055 
1059 
1061 {
1062  // Returns kTRUE if the number of events coincides with the interval
1063  // set for status updates for the current data analysis task
1064  return (!(nevents % fTask->GetStatusUpdateInterval()) && nevents);
1065 }
1066 
1067 
1068 
1071 
1073 {
1074  // Print infos on events treated, disk usage, memory usage
1075 
1076  cout << " +++ " << nevents << " events processed +++ " << endl;
1077  ProcInfo_t pid;
1078  if (gSystem->GetProcInfo(&pid) == 0) {
1079  cout << " ------------- Process infos -------------" << endl;
1080  printf(" CpuSys = %f s. CpuUser = %f s. ResMem = %f MB VirtMem = %f MB\n",
1081  pid.fCpuSys, pid.fCpuUser, pid.fMemResident / 1024.,
1082  pid.fMemVirtual / 1024.);
1083  }
1084 }
1085 
1086 
1087 
1088 
1093 
1095 {
1096  //Ask user to choose between immediate or batch execution
1097  //If the choice is batch, we ask to choose a batch system and whether or not
1098  //to use the "multijobs" mode
1099 
1100  fChoseRunMode = kTRUE;
1101  KVString tmp;
1102  do {
1103  cout << endl << "Run in Interactive or Batch mode (I or B) ? : ";
1104  tmp.ReadLine(cin);
1105  }
1106  while (tmp != "i" && tmp != "I" && tmp != "b" && tmp != "B");
1107  tmp.ToUpper();
1108  //interactive mode - no more to do
1109  if (tmp == "I") {
1110  fBatchSystem = 0;
1111  return;
1112  }
1113  cout << endl << "Choose the batch system to use : " << endl;
1114  gBatchSystemManager->Print();
1115  do {
1116  cout << "(enter a number) : " << endl;
1117  tmp.ReadLine(cin);
1118  }
1119  while (!tmp.IsDigit());
1120  fBatchSystem = gBatchSystemManager->GetBatchSystem(tmp.Atoi());
1121  fBatchSystem->Clear();
1122 }
1123 
1124 
1125 
1126 
1130 
1132 {
1133  //Fill TList with list of files in current working directory.
1134  //If ls!=0 it is deleted beforehand
1135  if (*ls) delete (*ls);
1136  TSystemDirectory dir("LocDir", gSystem->WorkingDirectory());
1137  (*ls) = dir.GetListOfFiles();
1138 }
1139 
1140 
1141 
1142 
1147 
1149 {
1150  //Compare the two lists of files in the current working directory, before and after analysis;
1151  //and copy any files which were created during the analysis to the launch directory.
1152  //Files with the same names in the launch directory will be overwritten if they exist.
1153 
1154  if (!fWorkDirInit || !fWorkDirEnd) return;
1155  TString launchDir = fBatchEnv->GetValue("LaunchDirectory", gSystem->WorkingDirectory());
1156  TIter next_new_file(fWorkDirEnd);
1157  TObject* file;
1158  while ((file = next_new_file())) {
1159  if (!fWorkDirInit->FindObject(file->GetName())) {
1160  TString fname;
1161  fname.Form("%s", file->GetName());
1162  //ajout d une condition pour eviter le transfert des file*.so generes par les KVParticleCondition
1163  //et aussi les .d generes par les KVParticleCondition
1164  if (!(fname.BeginsWith("KVParticleCondition_") || fname.EndsWith(".so") || fname.EndsWith(".d") || fname.EndsWith(".pcm") || fname.EndsWith(".bak"))) {
1165  TString path_src, path_trg;
1166  AssignAndDelete(path_trg, gSystem->ConcatFileName(launchDir.Data(), file->GetName()));
1168  file->GetName()));
1169  Info("CopyAnalysisResultsToLaunchDirectory", "Copying analysis results file :\n%s ---> %s",
1170  path_src.Data(), path_trg.Data());
1171  //copy & overwrite any existing file in launch directory
1172  if (gSystem->CopyFile(path_src.Data(), path_trg.Data(), kTRUE) == 0) {
1173  Info("CopyAnalysisResultsToLaunchDirectory", "File copied correctly");
1174  }
1175  else {
1176  Info("CopyAnalysisResultsToLaunchDirectory", " **** ERROR copying file !!! ");
1177  }
1178  }
1179  }
1180  }
1181 }
1182 
1183 
1184 
1185 
1190 
1192 {
1193  // Store lots of useful information about the current version of KaliVeda,
1194  // ROOT, etc. etc. in a TEnv object which will be added to the TTree's
1195  // list of user infos (TTree::GetUserInfo).
1196 
1197  tt->GetUserInfo()->Add(new TEnv());
1198  TEnv* kvenv = (TEnv*)tt->GetUserInfo()->FindObject("TEnv");
1199 
1200 //----
1201  THashList* hh = gEnv->GetTable();
1202  KVString tamp;
1203  for (Int_t kk = 0; kk < hh->GetEntries(); kk += 1) {
1204  tamp.Form("%s", hh->At(kk)->GetName());
1205  if (tamp.BeginsWith("Plugin.")) {}
1206  else kvenv->SetValue(hh->At(kk)->GetName(), ((TEnvRec*)hh->At(kk))->GetValue(), kEnvUser);
1207  }
1208 
1209  kvenv->SetValue("KVBase::GetKVVersion()", KVBase::GetKVVersion(), kEnvUser);
1210  kvenv->SetValue("KVBase::GetKVBuildDate()", KVBase::GetKVBuildDate(), kEnvUser);
1211  kvenv->SetValue("KVBase::GetKVBuildUser()", KVBase::GetKVBuildUser(), kEnvUser);
1212  kvenv->SetValue("KVBase::GetKVSourceDir()", KVBase::GetKVSourceDir(), kEnvUser);
1213 
1214 #ifdef WITH_GIT_INFOS
1215  kvenv->SetValue("KVBase::gitBranch()", KVBase::gitBranch(), kEnvUser);
1216  kvenv->SetValue("KVBase::gitCommit()", KVBase::gitCommit(), kEnvUser);
1217 #endif
1218 
1219  kvenv->SetValue("gROOT->GetVersion()", gROOT->GetVersion(), kEnvUser);
1220 
1221  kvenv->SetValue("gSystem->GetBuildArch()", gSystem->GetBuildArch(), kEnvUser);
1222  kvenv->SetValue("gSystem->GetBuildCompiler()", gSystem->GetBuildCompiler(), kEnvUser);
1223  kvenv->SetValue("gSystem->GetBuildCompilerVersion()", gSystem->GetBuildCompilerVersion(), kEnvUser);
1224  kvenv->SetValue("gSystem->GetBuildNode()", gSystem->GetBuildNode(), kEnvUser);
1225  kvenv->SetValue("gSystem->GetBuildDir()", gSystem->GetBuildDir(), kEnvUser);
1226 
1227  kvenv->SetValue("gSystem->GetUserInfo()->fUser", gSystem->GetUserInfo()->fUser, kEnvUser);
1228  kvenv->SetValue("gSystem->HostName()", gSystem->HostName(), kEnvUser);
1229 
1230  if (fBatchEnv) {
1231  THashList* hh = fBatchEnv->GetTable();
1232  for (Int_t kk = 0; kk < hh->GetEntries(); kk += 1) {
1233  tamp.Form("%s", hh->At(kk)->GetName());
1234  if (!strcmp(kvenv->GetValue(hh->At(kk)->GetName(), "rien"), "rien"))
1235  kvenv->SetValue(hh->At(kk)->GetName(), ((TEnvRec*)hh->At(kk))->GetValue(), kEnvUser);
1236  }
1237  }
1238 
1239 
1240 }
1241 
1242 
1243 
1249 
1251 {
1252  //Set up and run data analysis task.
1253  //This allows to choose a dataset and a data analysis task and then execute the task or submit a batch job.
1254  //The behaviour of the data analyser object (base class KVDataAnalyser) can be modified by choosing
1255  //a plugin class corresponding to one of the plugins defined in $KVROOT/KVFiles/.kvrootrc.
1256 
1257  KVDataAnalyser* datan = 0;
1258  TString tmp(uri);
1259  if (tmp != "") {
1260  //got plugin ?
1261  TPluginHandler* ph = KVBase::LoadPlugin("KVDataAnalyser", uri);
1262  if (!ph)
1263  ::Warning("KVDataAnalyser::RunAnalyser", "No plugin %s found for KVDataAnalyser",
1264  uri);
1265  else
1266  datan = (KVDataAnalyser*) ph->ExecPlugin(0);
1267  }
1268  if (datan == 0)
1269  datan = new KVDataAnalyser;
1270  datan->RunMenus();
1271  delete datan;
1272 }
1273 
1274 
1275 
1280 
1282 {
1283  // Static method KVDataAnalyser::IsRunningBatchAnalysis()
1284  // Returns kTRUE if an analysis task is being performed in batch mode
1285  // Returns kFALSE if no analysis task is in interactive mode, or no analysis task running
1286 
1287  if (gDataAnalyser) return (gDataAnalyser->BatchMode() && gDataAnalyser->fBatchSystem);
1288  return kFALSE;
1289 }
1290 
1291 
1292 
1298 
1300 {
1301  // Create a KVNameValueList called "JobDescriptionList" and add it to
1302  // the TList. The parameters in the list describe the properties of the
1303  // current job. The TList pointer could be, for example, the address of
1304  // the TSelector::fInput list used by PROOF.
1305 
1306  KVNameValueList* jdl = new KVNameValueList("JobDescriptionList", "Job parameters");
1307 
1308  jdl->SetValue("AnalysisTask", fTask->GetType());
1309  jdl->SetValue("PROOFMode", GetProofMode());
1310 
1311  l->Add(jdl);
1312 }
1313 
1314 
1315 
1317 
1318 KVString KVDataAnalyser::UserClass::get_full_path(const KVString& file_name, const KVString& other_dir) const
1319 {
1320  KVString path = file_name;
1321  KVString dir = other_dir.IsNull() ? dir_name : other_dir;
1322  if (!dir.IsNull()) AssignAndDelete(path, gSystem->ConcatFileName(dir.Data(), file_name.Data()));
1323  gSystem->ExpandPathName(path);
1324  return path;
1325 }
1326 
1327 
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
char name[80]
#define gROOT
char * Form(const char *fmt,...)
void AssignAndDelete(TString &target, char *tobedeleted)
R__EXTERN TSystem * gSystem
static const Char_t * GetKVBuildDate()
Returns KaliVeda build date.
Definition: KVBase.cpp:901
static const Char_t * gitCommit()
Returns last git commit of sources.
Definition: KVBase.cpp:971
static const Char_t * GetKVBuildUser()
Returns username of person who performed build.
Definition: KVBase.cpp:889
static const Char_t * gitBranch()
Returns git branch of sources.
Definition: KVBase.cpp:960
static Bool_t FindClassSourceFiles(const KVString &class_name, KVString &imp_file, KVString &dec_file, const KVString &dir_name=".")
Definition: KVBase.cpp:1096
static const Char_t * GetKVSourceDir()
Returns top-level directory of source tree used for build.
Definition: KVBase.cpp:936
static void PrintSplashScreen()
Prints welcome message and infos on version etc.
Definition: KVBase.cpp:1585
static TPluginHandler * LoadPlugin(const Char_t *base, const Char_t *uri="0")
Definition: KVBase.cpp:796
static const Char_t * GetKVVersion()
Returns KaliVeda version string.
Definition: KVBase.cpp:877
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.
void Clear(Option_t *opt="") override
virtual const Char_t * GetJobName() const
virtual void ReadBatchEnvFile(TEnv *)
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)
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()
void SetUserClass(const UserClass &kvs, Bool_t check=kTRUE)
const Char_t * GetBatchStatusFileName() const
Returns full path to file used to store status of running batch jobs.
KVDataAnalyser()
Default constructor.
static Bool_t fCleanAbort
flag to force abort of processing
static KVDataAnalyser * GetAnalyser(const Char_t *plugin)
static Bool_t IsRunningBatchAnalysis()
virtual ~KVDataAnalyser()
Default destructor.
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)
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.
Bool_t Init(KVDataSetRepository *=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
Bool_t IsNull() 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 char * ExpandPathName(const char *path)
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)
tuple file_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)
KVString get_full_path(const KVString &, const KVString &="") const
Long_t fMemVirtual
Float_t fCpuSys
Long_t fMemResident
Float_t fCpuUser
TString fUser
TLine l
auto * tt
ClassImp(TPyArg)