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  if (!gBatchSystemManager) new KVBatchSystemManager;
46  fBatchSystem = 0;
47  fChoseRunMode = kFALSE;
48  fWorkDirInit = fWorkDirEnd = 0;
49  fMenus = kFALSE;
50 #ifdef WITH_CPP11
51  fProofMode = EProofMode::None;
52 #else
53  fProofMode = None;
54 #endif
55  fUseBaseClassSubmitTask = kFALSE;
56 }
57 
58 
59 
62 
63 KVDataAnalyser::~KVDataAnalyser()
64 {
65  //Default destructor.
66  SafeDelete(fWorkDirInit);
67  SafeDelete(fWorkDirEnd);
68  if (gDataAnalyser == this)gDataAnalyser = nullptr;
69 }
70 
71 
72 
74 
76 {
77  fDataType = "";
78  fTask = nullptr;
79  fQuit = kFALSE;
80  fSubmit = kFALSE;
81  fUserClassIsOK = kFALSE;
82  fUserClass.reset();
83  fUserClassOptions = "";
84  nbEventToRead = -1;
85  fBatchSystem = nullptr;
86  fChoseRunMode = kFALSE;
87 #ifdef WITH_CPP11
88  fProofMode = EProofMode::None;
89 #else
90  fProofMode = None;
91 #endif
92 }
93 
94 
95 
96 
99 
101 {
102  //Check all task variables, then run analyser
103 
104  fSubmit = kFALSE;
105  //print welcome message for main (parent) analyser
106  if (!fParent && !fMenus) KVBase::PrintSplashScreen();
107 
108  if (CheckTaskVariables()) {
109  if (fBatchSystem && !BatchMode()) {
110  //if batch mode is requested, the job is submitted to the chosen batch system
111  fBatchSystem->SubmitTask(this);
112  }
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.name != ClassName()) {
210  //task requires user analysis class
211  if (fUserClass.name.IsNull()) {
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 << GetUserClassName() << " 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  }
340  else {
341  }
342  }
343  if (!loaded) {
344  Info("SetUserLibraries", "Library \"%s\"added.", id.Data());
345  gSystem->Load(id.Data());
346  }
347  fLibraries += id.Data();
348  fLibraries += " ";
349  }
350 
351 }
352 
353 
354 
355 
358 
360 {
361  // Ask user to set number of events to read
362 
363  SetNbEventToRead(-1);
364  while (nbEventToRead < 0) {
365  cout << "Give the number of events to read [<RET>=all]:" << endl;
366  KVString ntr;
367  ntr.ReadToDelim(cin);
368  if (ntr.IsDigit() || !ntr.Length()) {
369  if (ntr.Length()) {
370  nbEventToRead = (Long64_t) ntr.Atoi();
371  }
372  else {
373  nbEventToRead = 0;
374  }
375  }
376  else {
377  cout << "\"" << ntr.
378  Data() << "\" is not a number. Please retry." << endl;
379  }
380  }
381 }
382 
383 
384 
385 
389 
391 {
392  //Creates an instance of a class derived from KVDataAnalyser defined as a plugin
393 
394  //check and load plugin library
395  TPluginHandler* ph;
396  if (!(ph = KVBase::LoadPlugin("KVDataAnalyser", plugin)))
397  return nullptr;
398 
399  //execute constructor
400  KVDataAnalyser* da = (KVDataAnalyser*) ph->ExecPlugin(0);
401 
402  return da;
403 }
404 
405 
406 
407 
410 
412 {
413  //Choose the user's analysis class
414  fUserClass.name = "";
415  while (!fUserClass.name.Length()) {
416  cout << "Give the name of the analysis class: ";
417  fUserClass.name.ReadLine(cin);
418  fUserClassIsOK = kFALSE;
419  }
420 }
421 
422 
423 
424 
428 
430 {
431  // Check if files containing user's class can be located.
432  // The names of the implementation and header files are stored in fUserClassImp and fUserClassDec.
433 
434  return KVBase::FindClassSourceFiles(fUserClass.name,
435  fUserClass.imp_file, fUserClass.dec_file, fUserClass.dir_name);
436 }
437 
438 
439 
440 
457 
459 {
460  //Return kTRUE if the name of the class given by the user (fUserClass) is valid
461  //for the analysis task. This is so if one of the following is true:
462  // - the class library has already been loaded. In this case the class will exist
463  // in the dictionary (gROOT->GetClass()); we check if it derived from the
464  // base class defined for the analysis task
465  // - a plugin exists defining this class as an extension of the base class defined
466  // for the analysis task (gROOT->GetPluginManager()->FindHandler(...): the URI for
467  // the plugin must be the same as the name of the class)
468  // - source files for the class are present in the working directory. In this case
469  // we can add a plugin handler for the class.
470  //In the latter two cases, the class is valid if compilation succeeds.
471  //
472  //If the user's class may in fact be derived from an alternative base class, rather
473  //than the base class defined for this analysis task (see KVDataAnalysisTask::SetUserBaseClass)
474  //you can supply the name of this class (or a comma-separated list of base classes).
475 
476  std::unique_ptr<TObject> o{GetInstanceOfUserClass(alternative_base_class)};
477  return (Bool_t)o;
478 }
479 
480 
481 
482 
494 
496 {
497  // Returns string to be appended to name of user class for compilation with ACliC in
498  // GetInstanceOfUserClass(). This depends on the boolean resources:
499  //
500  //~~~
501  // KVDataAnalyser.UserClass.Debug: ( "yes" => "g" )
502  // KVDataAnalyser.UserClass.Optimise: ( "yes" => "O" )
503  // KVDataAnalyser.UserClass.ForceRecompile: ( "no" => "+"; "yes" => "++" )
504  //~~~
505  //
506  // Note that if both Debug and Optimise are set to "yes/true", we use Debug mode (can't have BOTH debug & optimisation).
507 
508  static TString aclic;
509  if (gEnv->GetValue("KVDataAnalyser.UserClass.ForceRecompile", kFALSE)) aclic = "++";
510  else aclic = "+";
511  if (gEnv->GetValue("KVDataAnalyser.UserClass.Debug", kFALSE)) aclic += "g";
512  else if (gEnv->GetValue("KVDataAnalyser.UserClass.Optimise", kFALSE)) aclic += "O";
513  return aclic.Data();
514 }
515 
516 
517 
519 
521 {
522  fBatchSystem = nullptr;
523 }
524 
525 
526 
527 
545 
547 {
548  //Return an instance of the class given by the user (fUserClass), if it is valid.
549  //If the user class is given in the form of source code, it will be (re)compiled
550  //if it has not already been loaded and/or the source has changed since the last
551  //build, using ACliC. If the resource
552  //
553  //~~~
554  // KVDataAnalyser.UserClass.Debug: yes
555  //~~~
556  //
557  //is set, the user's class will be compiled with extra debugging information
558  //
559  //Once compiled, we check that the user's class is indeed derived from the base
560  //class defined for this analysis task (see KVDataAnalysisTask::SetUserBaseClass).
561  //If the user's class may in fact be derived from an alternative base class, you
562  //can supply the name of this class (or comma-separated list of base classes).
563 
564  // make sure any required plugin library defining base class for user's analysis class is loaded
565  if (!fTask->CheckUserBaseClassIsLoaded()) return 0x0;
566 
567  //do we have a plugin ?
568  TPluginHandler* ph = gROOT->GetPluginManager()->FindHandler(fTask->GetUserBaseClass(), fUserClass.name);
569  if (!ph) {//no plugin defined
570 
571  //if it is a precompiled class (i.e. already part of KaliVeda),
572  //it will be in the dictionary already
573  TClass* cl = gROOT->GetClass(fUserClass.name);
574 
575  //do we have source files ?
576  if (DoUserClassFilesExist()) {
577  //compile & load user's source files using ACLIC. ACliC options read by GetACliCMode() from .kvrootrc
578  TString cmd;
579  cmd.Form(".L %s%s", fUserClass.full_path_imp().Data(), GetACliCMode());
580  gROOT->ProcessLine(cmd.Data());
581  //class will be in dictionary if compilation successful
582  cl = gROOT->GetClass(fUserClass.name);
583  }
584  else if (!cl) {
585  //class not in dictionary and no source files. help!
586  Info("GetInstanceOfUserClass", "Class %s is unknown and no source files available",
587  fUserClass.name.Data());
588  return 0;
589  }
590  if (!cl) {
591  //compilation of user class has failed
592  Info("GetInstanceOfUserClass", "Compilation of class %s failed. Correct the mistakes and try again",
593  fUserClass.name.Data());
594  return 0;
595  }
596  if (!cl->GetBaseClass(fTask->GetUserBaseClass())) {
597  // class does not inherit from base class defined by analysis task
598  if (alternative_base_class == "") { // no alternative base classes provided
599  Info("GetInstanceOfUserClass", "Class %s does not inherit from correct base class (%s), or compilation of class %s failed. Correct the mistakes and try again",
600  fUserClass.name.Data(), fTask->GetUserBaseClass(), fUserClass.name.Data());
601  return nullptr;
602  }
603  else {
604  // check alternative base class(es) - it may still be good!
605  bool got_good_base = false;
606  TString good_base = "";
607  alternative_base_class.Begin(",");
608  while (!alternative_base_class.End()) {
609  good_base = alternative_base_class.Next(kTRUE);
610  if (cl->GetBaseClass(good_base)) {
611  got_good_base = true;
612  break;
613  }
614  }
615  if (got_good_base) {
616  Info("GetInstanceOfUserClass", "Class %s inherits from alternative base class %s: OK!",
617  fUserClass.name.Data(), good_base.Data());
618  }
619  else {
620  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",
621  fUserClass.name.Data(), fTask->GetUserBaseClass(), alternative_base_class.Data(), fUserClass.name.Data());
622  return nullptr;
623  }
624  }
625  }
626  //EVERYTHING OK!! now instanciate an object of the new class
627  return (TObject*)cl->New();
628  }
629  else {
630  Info("GetInstanceOfUserClass", "Found plugin handler for class %s",
631  fUserClass.name.Data());
632  //load class from plugin
633  ph = KVBase::LoadPlugin(fTask->GetUserBaseClass(), fUserClass.name.Data());
634  if (!ph) {
635  Info("GetInstanceOfUserClass", "KVBase::LoadPlugin failed for %s", fUserClass.name.Data());
636  return 0;
637  }
638  TObject* obj = (TObject*)ph->ExecPlugin(0);
639  if (obj) {
640  //Info("GetInstanceOfUserClass", "constructor OK for %s", fUserClass.Data());
641  if (obj->InheritsFrom(fTask->GetUserBaseClass())) return obj;
642  Info("GetInstanceOfUserClass", "%s does not inherit from %s", fUserClass.name.Data(), fTask->GetUserBaseClass());
643  return 0;
644  }
645  else {
646  Info("GetInstanceOfUserClass", "constructor not OK for %s", fUserClass.name.Data());
647  return 0;
648  }
649  }
650  return 0;
651 }
652 
653 
654 
655 
660 
662 {
663  //Set name of user analysis class.
664  //If check=kTRUE (default), we check the validity of the class
665  //if check=kFALSE we do not check and assume that the class is valid
666 
667  fUserClass = kvs;
668  if (check) {
669  fUserClassIsOK = CheckIfUserClassIsValid();
670  }
671  else {
672  fUserClassIsOK = kTRUE;
673  }
674 }
675 
676 
677 
678 
684 
686 {
687  //Save (in the TEnv fBatchEnv) all necessary information on analysis task which can be used to execute it later
688  //(i.e. when batch processing system executes the job).
689  //If save=kTRUE (default), write the information in a file whose name is given by ".jobname"
690  //where 'jobname' is the name of the job as given to the batch system.
691 
692  OpenBatchInfoFile(Form(".%s", jobname.Data()));
693  if (fBatchSystem) {
694  fBatchEnv->SetValue("BatchSystem", fBatchSystem->GetName());
695  fBatchSystem->WriteBatchEnvFile(GetBatchInfoFile());
696  }
697  fBatchEnv->SetValue("AnalysisTask", fTask->GetType());
698 
699  if (fTask->WithUserClass()) {
700  fBatchEnv->SetValue("UserClass", GetUserClass().name);
701  if (!GetUserClass().with_files()) {
702  if (!DoUserClassFilesExist()) {
703  Warning("WriteBatchEnvFile", "Source files for user class %s do not exist. Job will not work.",
704  GetUserClass().name.Data());
705  }
706  }
707  if (!GetUserClass().dir_name.IsNull()) {
708  // make sure we write an absolute pathname for the directory
709  gSystem->ExpandPathName(GetUserClass().dir_name);
710  fBatchEnv->SetValue("UserClassDir", GetUserClass().dir_name);
711  }
712  fBatchEnv->SetValue("UserClassOptions", fUserClassOptions);
713  fBatchEnv->SetValue("UserClassImp", GetUserClass().imp_file);
714  fBatchEnv->SetValue("UserClassDec", GetUserClass().dec_file);
715  }
716  else {
717  // a task without a user class may still need to pass options to the predefined analysis class
718  if (fUserClassOptions != "") fBatchEnv->SetValue("UserClassOptions", fUserClassOptions);
719  }
720  fBatchEnv->SetValue("NbToRead", (Double_t)nbEventToRead);
721  fBatchEnv->SetValue("LaunchDirectory", gSystem->WorkingDirectory());
722  if (fIncludes.Length()) {
723  fBatchEnv->SetValue("UserIncludes", fIncludes.Data());
724  }
725  if (fLibraries.Length()) {
726  fBatchEnv->SetValue("UserLibraries", fLibraries.Data());
727  }
728 
729  if (save) fBatchEnv->SaveLevel(kEnvUser);
730 }
731 
732 
733 
734 
739 
741 {
742  //Read the batch env file "filename" and initialise the analysis task using the
743  //informations in the file
744  //Returns kTRUE if all goes well
745 
746  Bool_t ok = kFALSE;
747 
748  OpenBatchInfoFile(filename);
749 
750  if (!GetAnalysisTask()) {
751  // we only look for the analysis task here if it has not already been set -
752  // see KVDataSetAnalyser::ReadBatchEnvFile, where if the dataset modifies the
753  // title of the analysis task, only the required dataset can be used to set the task
754  KVString val = fBatchEnv->GetValue("AnalysisTask", "");
755  SetAnalysisTask(nullptr);
756  if (val != "") {
757  if (!gDataSetManager) {
758  gDataSetManager = new KVDataSetManager;
759  gDataSetManager->Init();
760  }
761  SetAnalysisTask(gDataSetManager->GetAnalysisTaskAny(val.Data()));
762  }
763  else {
764  Error("ReadBatchEnvFile", "Name of analysis task not given");
765  return ok;
766  }
767  if (!GetAnalysisTask()) {
768  Error("ReadBatchEnvFile", "Analysis task \"%s\"not found for dataset %s",
769  val.Data(), gDataSet->GetName());
770  return ok;
771  }
772  }
773 
774  nbEventToRead = (Long64_t)fBatchEnv->GetValue("NbToRead", -1);
775  SetUserIncludes(fBatchEnv->GetValue("UserIncludes", ""));
776  SetUserLibraries(fBatchEnv->GetValue("UserLibraries", ""));
777 
778  //batch system
779  if (strcmp(fBatchEnv->GetValue("BatchSystem", ""), "")) {
780  fBatchSystem = gBatchSystemManager->GetBatchSystem(fBatchEnv->GetValue("BatchSystem", ""));
781  fBatchSystem->ReadBatchEnvFile(GetBatchInfoFile());
782  fBatchSystem->cd(); // make gBatchSystem point to it
783  fBatchSystem->SetAnalyser(this);
784  }
785 
786  //User files
787  if (fTask->WithUserClass()) {
788  fUserClass.name = fBatchEnv->GetValue("UserClass", "");
789  if (fUserClass.name.IsNull()) {
790  Error("ReadBatchEnvFile", "Name of user class not given");
791  fBatchEnv->Print();
792  return ok;
793  }
794  fUserClassOptions = fBatchEnv->GetValue("UserClassOptions", "");
795  fUserClass.dir_name = fBatchEnv->GetValue("UserClassDir", "");
796  fUserClass.imp_file = fBatchEnv->GetValue("UserClassImp", "");
797  if (fUserClass.imp_file.IsNull()) {
798  Error("ReadBatchEnvFile", "Name of user class implementation file not given");
799  return ok;
800  }
801  fUserClass.dec_file = fBatchEnv->GetValue("UserClassDec", "");
802  if (fUserClass.dec_file.IsNull()) {
803  Error("ReadBatchEnvFile", "Name of user class header file not given");
804  return ok;
805  }
806  fUserClassAlternativeBaseClass = fBatchEnv->GetValue("UserClassAlternativeBaseClass", "");
807 
808  //If current working directory is not the same as the launch directory,
809  //we have to copy the user's files here
810  if (!RunningInLaunchDirectory()) {
811  TString launchDir = fBatchEnv->GetValue("LaunchDirectory", gSystem->WorkingDirectory());
812  TString path_src, path_trg;
813  //copy user's implementation file
814  AssignAndDelete(path_trg, gSystem->ConcatFileName(gSystem->WorkingDirectory(), fUserClass.imp_file.Data()));
815  Info("ReadBatchEnvFile", "Copying %s to %s", fUserClass.full_path_imp().Data(), path_trg.Data());
816  gSystem->CopyFile(fUserClass.full_path_imp(), path_trg);
817  //copy user's header file
818  AssignAndDelete(path_trg, gSystem->ConcatFileName(gSystem->WorkingDirectory(), fUserClass.dec_file.Data()));
819  Info("ReadBatchEnvFile", "Copying %s to %s", fUserClass.full_path_dec().Data(), path_trg.Data());
820  gSystem->CopyFile(fUserClass.full_path_dec(), path_trg);
821  // change directory stored in UserClass
822  fUserClass.dir_name = ".";
823  }
824  }
825  else {
826  // a task without a user class may still need to pass options to the predefined analysis class
827  fUserClassOptions = fBatchEnv->GetValue("UserClassOptions", "");
828  }
829 
830  ok = kTRUE;
831 
832  return ok;
833 }
834 
835 
836 
837 
841 
843 {
844  //Returns kTRUE if current working directory is same as launch directory for batch job
845  //When not in batch mode, always returns kTRUE.
846  if (!BatchMode() || !fBatchEnv) return kTRUE;
847  TString launchDir = fBatchEnv->GetValue("LaunchDirectory", gSystem->WorkingDirectory());
848  return (launchDir == gSystem->WorkingDirectory());
849 }
850 
851 
852 
853 
855 
857 {
858  the_analyser->SetParent(this);
859  the_analyser->SetAnalysisTask(fTask);
860  the_analyser->SetNbEventToRead(GetNbEventToRead());
861  the_analyser->SetUserIncludes(fIncludes.Data());
862  the_analyser->SetUserLibraries(fLibraries.Data());
863 }
864 
865 
866 
873 
875 {
876  //In interactive mode, the data analysis task is performed by
877  //instanciating and initialising the KVDataAnalyser child class specified by the task,
878  //and then calling its Run() method.
879  //
880  //In batch mode, the job is submitted to the chosen batch system.
881 
882  KVString task_data_analyser = fTask->GetDataAnalyser();
883  Info("SubmitTask", "fTask->GetDataAnalyser()=%s", task_data_analyser.Data());
884  unique_ptr<KVDataAnalyser> the_analyser;
885  if (task_data_analyser == "UserClass") {
886  //the user-provided class is to be used as analyser
887  the_analyser.reset((KVDataAnalyser*)GetInstanceOfUserClass());
888  }
889  else {
890  the_analyser.reset(GetAnalyser(fTask->GetDataAnalyser()));
891  }
892  if (!the_analyser.get())
893  Fatal("SubmitTask", "the_analyser is 0x0, go to crash");
894 
895  set_up_analyser_for_task(the_analyser.get());
896 
897  if (fTask->WithUserClass()) {
898  the_analyser->SetUserClass(GetUserClass(), kFALSE);
899  the_analyser->SetUserClassOptions(fUserClassOptions);
900  }
901  else if (strcmp(fTask->GetUserBaseClass(), ""))
902  the_analyser->SetUserClass({fTask->GetUserBaseClass()}, kFALSE);
903  if (!BatchMode()) {
904  //when not in batch mode i.e. when submitting a task, we ask the user to supply
905  //any further information required by the task, and then ask whether to run in
906  //interactive or batch mode
907  the_analyser->CheckTaskVariables();
908  if (!fChoseRunMode) ChooseRunningMode();
909  }
910  the_analyser->SetBatchMode(BatchMode());
911  the_analyser->SetBatchName(GetBatchName());
912  the_analyser->SetBatchSystem(fBatchSystem);
913  the_analyser->SetProofMode(GetProofMode());
914  //set global pointer to analyser object which performs the analysis
915  //this allows e.g. user class to obtain information on the analysis task
916  gDataAnalyser = the_analyser.get();
917  the_analyser->Run();
918 }
919 
920 
921 
922 
929 
931 {
932  //Replace any 'special' symbols in "format" with their current values
933  //
934  // $Date : current date and time
935  // $User : name of user
936  // $UserClass : name of user's analysis class
937 
938  KVString tmp = format;
939  TDatime now;
940  KVString stDate = now.AsSQLString();
941  stDate.ReplaceAll(" ", "-");
942  tmp.ReplaceAll("$Date", stDate.Data());
943  if (fUserClass.name.Length()) tmp.ReplaceAll("$UserClass", fUserClass.name);
944  else if (fTask) tmp.ReplaceAll("$UserClass", fTask->GetDataAnalyser());
945  tmp.ReplaceAll("$User", gSystem->GetUserInfo()->fUser.Data());
946  return tmp;
947 }
948 
949 
950 
952 
954 {
955  static TString keywords = "Will be expanded: $Date, $User, $UserClass";
956  return keywords;
957 }
958 
959 
960 
964 
966 {
967  // Returns full path to job submission directory for batch jobs.
968  // Returns current working directory for non-batch jobs.
969 
970  if (!BatchMode() || !fBatchEnv) return gSystem->WorkingDirectory();
971  return fBatchEnv->GetValue("LaunchDirectory", gSystem->WorkingDirectory());
972 }
973 
974 
975 
982 
984 {
985  // Use this method to get the full path to a file in the directory where the job was launched.
986  //
987  // When not using a batch system, this will just be the current working directory.
988  //
989  // If the job is actually running elsewhere, use this method to access a file in the launch directory.
990 
991  TString fullpath;
992  AssignAndDelete(fullpath, gSystem->ConcatFileName(GetLaunchDirectory(), f.Data()));
993  return fullpath;
994 }
995 
996 
997 
1000 
1002 {
1003  // Returns full path to file used to store status of running batch jobs
1004 
1005  if (!BatchMode() || !fBatchEnv) return "";
1006 
1007  static TString filename = "";
1008  TString statfile;
1009  statfile.Form("%s.status", gBatchSystem->GetJobName());
1010 
1011  TString launchDir = GetLaunchDirectory();
1012  AssignAndDelete(filename, gSystem->ConcatFileName(launchDir.Data(), statfile.Data()));
1013  return filename;
1014 }
1015 
1016 
1017 
1020 
1022 {
1023  // Update infos in batch status file
1024 
1025  if (!BatchMode() || !fBatchEnv) return;
1026 
1027  TEnv stats(GetBatchStatusFileName());
1028  stats.SetValue("TotalEvents", totev);
1029  stats.SetValue("EventsRead", evread);
1030  disk.Remove(TString::kTrailing, '\t');
1031  disk.Remove(TString::kTrailing, ' ');
1032  disk.Remove(TString::kTrailing, '\t');
1033  stats.SetValue("DiskUsed", disk.Data());
1034  stats.SaveLevel(kEnvLocal);
1035 }
1036 
1037 
1038 
1041 
1043 {
1044  // Delete batch status file (and backup - '.bak') for batch job
1045 
1046  if (!BatchMode() || !fBatchEnv) return;
1047  TString stats = GetBatchStatusFileName();
1048  gSystem->Unlink(stats);
1049  stats += ".bak";
1050  gSystem->Unlink(stats);
1051 }
1052 
1053 
1054 
1058 
1060 {
1061  // Returns kTRUE if the number of events coincides with the interval
1062  // set for status updates for the current data analysis task
1063  return (!(nevents % fTask->GetStatusUpdateInterval()) && nevents);
1064 }
1065 
1066 
1067 
1070 
1072 {
1073  // Print infos on events treated, disk usage, memory usage
1074 
1075  cout << " +++ " << nevents << " events processed +++ " << endl;
1076  ProcInfo_t pid;
1077  if (gSystem->GetProcInfo(&pid) == 0) {
1078  cout << " ------------- Process infos -------------" << endl;
1079  printf(" CpuSys = %f s. CpuUser = %f s. ResMem = %f MB VirtMem = %f MB\n",
1080  pid.fCpuSys, pid.fCpuUser, pid.fMemResident / 1024.,
1081  pid.fMemVirtual / 1024.);
1082  }
1083 }
1084 
1085 
1086 
1087 
1092 
1094 {
1095  //Ask user to choose between immediate or batch execution
1096  //If the choice is batch, we ask to choose a batch system and whether or not
1097  //to use the "multijobs" mode
1098 
1099  fChoseRunMode = kTRUE;
1100  KVString tmp;
1101  do {
1102  cout << endl << "Run in Interactive or Batch mode (I or B) ? : ";
1103  tmp.ReadLine(cin);
1104  }
1105  while (tmp != "i" && tmp != "I" && tmp != "b" && tmp != "B");
1106  tmp.ToUpper();
1107  //interactive mode - no more to do
1108  if (tmp == "I") {
1109  fBatchSystem = 0;
1110  return;
1111  }
1112  cout << endl << "Choose the batch system to use : " << endl;
1113  gBatchSystemManager->Print();
1114  do {
1115  cout << "(enter a number) : " << endl;
1116  tmp.ReadLine(cin);
1117  }
1118  while (!tmp.IsDigit());
1119  fBatchSystem = gBatchSystemManager->GetBatchSystem(tmp.Atoi());
1120  fBatchSystem->Clear();
1121 }
1122 
1123 
1124 
1125 
1129 
1131 {
1132  //Fill TList with list of files in current working directory.
1133  //If ls!=0 it is deleted beforehand
1134  if (*ls) delete (*ls);
1135  TSystemDirectory dir("LocDir", gSystem->WorkingDirectory());
1136  (*ls) = dir.GetListOfFiles();
1137 }
1138 
1139 
1140 
1141 
1146 
1148 {
1149  //Compare the two lists of files in the current working directory, before and after analysis;
1150  //and copy any files which were created during the analysis to the launch directory.
1151  //Files with the same names in the launch directory will be overwritten if they exist.
1152 
1153  if (!fWorkDirInit || !fWorkDirEnd) return;
1154  TString launchDir = fBatchEnv->GetValue("LaunchDirectory", gSystem->WorkingDirectory());
1155  TIter next_new_file(fWorkDirEnd);
1156  TObject* file;
1157  while ((file = next_new_file())) {
1158  if (!fWorkDirInit->FindObject(file->GetName())) {
1159  TString fname;
1160  fname.Form("%s", file->GetName());
1161  //ajout d une condition pour eviter le transfert des file*.so generes par les KVParticleCondition
1162  //et aussi les .d generes par les KVParticleCondition
1163  if (!(fname.BeginsWith("KVParticleCondition_") || fname.EndsWith(".so") || fname.EndsWith(".d") || fname.EndsWith(".pcm") || fname.EndsWith(".bak"))) {
1164  TString path_src, path_trg;
1165  AssignAndDelete(path_trg, gSystem->ConcatFileName(launchDir.Data(), file->GetName()));
1167  file->GetName()));
1168  Info("CopyAnalysisResultsToLaunchDirectory", "Copying analysis results file :\n%s ---> %s",
1169  path_src.Data(), path_trg.Data());
1170  //copy & overwrite any existing file in launch directory
1171  if (gSystem->CopyFile(path_src.Data(), path_trg.Data(), kTRUE) == 0) {
1172  Info("CopyAnalysisResultsToLaunchDirectory", "File copied correctly");
1173  }
1174  else {
1175  Info("CopyAnalysisResultsToLaunchDirectory", " **** ERROR copying file !!! ");
1176  }
1177  }
1178  }
1179  }
1180 }
1181 
1182 
1183 
1184 
1189 
1191 {
1192  // Store lots of useful information about the current version of KaliVeda,
1193  // ROOT, etc. etc. in a TEnv object which will be added to the TTree's
1194  // list of user infos (TTree::GetUserInfo).
1195 
1196  tt->GetUserInfo()->Add(new TEnv());
1197  TEnv* kvenv = (TEnv*)tt->GetUserInfo()->FindObject("TEnv");
1198 
1199 //----
1200  THashList* hh = gEnv->GetTable();
1201  KVString tamp;
1202  for (Int_t kk = 0; kk < hh->GetEntries(); kk += 1) {
1203  tamp.Form("%s", hh->At(kk)->GetName());
1204  if (tamp.BeginsWith("Plugin.")) {}
1205  else kvenv->SetValue(hh->At(kk)->GetName(), ((TEnvRec*)hh->At(kk))->GetValue(), kEnvUser);
1206  }
1207 
1208  kvenv->SetValue("KVBase::GetKVVersion()", KVBase::GetKVVersion(), kEnvUser);
1209  kvenv->SetValue("KVBase::GetKVBuildDate()", KVBase::GetKVBuildDate(), kEnvUser);
1210  kvenv->SetValue("KVBase::GetKVBuildUser()", KVBase::GetKVBuildUser(), kEnvUser);
1211  kvenv->SetValue("KVBase::GetKVSourceDir()", KVBase::GetKVSourceDir(), kEnvUser);
1212 
1213 #ifdef WITH_GIT_INFOS
1214  kvenv->SetValue("KVBase::gitBranch()", KVBase::gitBranch(), kEnvUser);
1215  kvenv->SetValue("KVBase::gitCommit()", KVBase::gitCommit(), kEnvUser);
1216 #endif
1217 
1218  kvenv->SetValue("gROOT->GetVersion()", gROOT->GetVersion(), kEnvUser);
1219 
1220  kvenv->SetValue("gSystem->GetBuildArch()", gSystem->GetBuildArch(), kEnvUser);
1221  kvenv->SetValue("gSystem->GetBuildCompiler()", gSystem->GetBuildCompiler(), kEnvUser);
1222  kvenv->SetValue("gSystem->GetBuildCompilerVersion()", gSystem->GetBuildCompilerVersion(), kEnvUser);
1223  kvenv->SetValue("gSystem->GetBuildNode()", gSystem->GetBuildNode(), kEnvUser);
1224  kvenv->SetValue("gSystem->GetBuildDir()", gSystem->GetBuildDir(), kEnvUser);
1225 
1226  kvenv->SetValue("gSystem->GetUserInfo()->fUser", gSystem->GetUserInfo()->fUser, kEnvUser);
1227  kvenv->SetValue("gSystem->HostName()", gSystem->HostName(), kEnvUser);
1228 
1229  if (fBatchEnv) {
1230  THashList* hh = fBatchEnv->GetTable();
1231  for (Int_t kk = 0; kk < hh->GetEntries(); kk += 1) {
1232  tamp.Form("%s", hh->At(kk)->GetName());
1233  if (!strcmp(kvenv->GetValue(hh->At(kk)->GetName(), "rien"), "rien"))
1234  kvenv->SetValue(hh->At(kk)->GetName(), ((TEnvRec*)hh->At(kk))->GetValue(), kEnvUser);
1235  }
1236  }
1237 
1238 
1239 }
1240 
1241 
1242 
1248 
1250 {
1251  //Set up and run data analysis task.
1252  //This allows to choose a dataset and a data analysis task and then execute the task or submit a batch job.
1253  //The behaviour of the data analyser object (base class KVDataAnalyser) can be modified by choosing
1254  //a plugin class corresponding to one of the plugins defined in $KVROOT/KVFiles/.kvrootrc.
1255 
1256  KVDataAnalyser* datan = 0;
1257  TString tmp(uri);
1258  if (tmp != "") {
1259  //got plugin ?
1260  TPluginHandler* ph = KVBase::LoadPlugin("KVDataAnalyser", uri);
1261  if (!ph)
1262  ::Warning("KVDataAnalyser::RunAnalyser", "No plugin %s found for KVDataAnalyser",
1263  uri);
1264  else
1265  datan = (KVDataAnalyser*) ph->ExecPlugin(0);
1266  }
1267  if (datan == 0)
1268  datan = new KVDataAnalyser;
1269  datan->RunMenus();
1270  delete datan;
1271 }
1272 
1273 
1274 
1279 
1281 {
1282  // Static method KVDataAnalyser::IsRunningBatchAnalysis()
1283  // Returns kTRUE if an analysis task is being performed in batch mode
1284  // Returns kFALSE if no analysis task is in interactive mode, or no analysis task running
1285 
1286  if (gDataAnalyser) return (gDataAnalyser->BatchMode() && gDataAnalyser->fBatchSystem);
1287  return kFALSE;
1288 }
1289 
1290 
1291 
1297 
1299 {
1300  // Create a KVNameValueList called "JobDescriptionList" and add it to
1301  // the TList. The parameters in the list describe the properties of the
1302  // current job. The TList pointer could be, for example, the address of
1303  // the TSelector::fInput list used by PROOF.
1304 
1305  KVNameValueList* jdl = new KVNameValueList("JobDescriptionList", "Job parameters");
1306 
1307  jdl->SetValue("AnalysisTask", fTask->GetType());
1308  jdl->SetValue("PROOFMode", GetProofMode());
1309 
1310  l->Add(jdl);
1311 }
1312 
1313 
1314 
1316 
1317 KVString KVDataAnalyser::UserClass::get_full_path(const KVString& file_name, const KVString& other_dir) const
1318 {
1319  KVString path = file_name;
1320  KVString dir = other_dir.IsNull() ? dir_name : other_dir;
1321  if (!dir.IsNull()) AssignAndDelete(path, gSystem->ConcatFileName(dir.Data(), file_name.Data()));
1322  gSystem->ExpandPathName(path);
1323  return path;
1324 }
1325 
1326 
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:877
static const Char_t * gitCommit()
Returns last git commit of sources.
Definition: KVBase.cpp:947
static const Char_t * GetKVBuildUser()
Returns username of person who performed build.
Definition: KVBase.cpp:865
static const Char_t * gitBranch()
Returns git branch of sources.
Definition: KVBase.cpp:936
static Bool_t FindClassSourceFiles(const KVString &class_name, KVString &imp_file, KVString &dec_file, const KVString &dir_name=".")
Definition: KVBase.cpp:1072
static const Char_t * GetKVSourceDir()
Returns top-level directory of source tree used for build.
Definition: KVBase.cpp:912
static void PrintSplashScreen()
Prints welcome message and infos on version etc.
Definition: KVBase.cpp:1561
static TPluginHandler * LoadPlugin(const Char_t *base, const Char_t *uri="0")
Definition: KVBase.cpp:772
static const Char_t * GetKVVersion()
Returns KaliVeda version string.
Definition: KVBase.cpp:853
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()
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.
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
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)