KaliVeda
Toolkit for HIC analysis
Loading...
Searching...
No Matches
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
24using namespace std;
26
28
29KVDataAnalyser* gDataAnalyser = 0;
30
31
34
36{
37 //Default constructor.
38 fParent = nullptr;
39 fBatch = kFALSE;
40 fTask = nullptr;
41 fQuit = kFALSE;
43 nbEventToRead = -1;
45 fUserClass = "";
46 if (!gBatchSystemManager) new KVBatchSystemManager;
47 fBatchSystem = 0;
50 fMenus = kFALSE;
51#ifdef WITH_CPP11
53#else
55#endif
57}
58
59
60
63
65{
66 //Default destructor.
69 if (gDataAnalyser == this)gDataAnalyser = nullptr;
70}
71
72
73
75
77{
78 fDataType = "";
79 fTask = nullptr;
80 fQuit = kFALSE;
83 fUserClass = "";
85 nbEventToRead = -1;
86 fBatchSystem = nullptr;
88#ifdef WITH_CPP11
90#else
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
108
109 if (CheckTaskVariables()) {
110 if (fBatchSystem && !BatchMode()) {
111 //if batch mode is requested, the job is submitted to the chosen batch system
113 } else {
114 if (BatchMode() && fBatchSystem && !fParent) fBatchSystem->Print("log");
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
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.
133 else
134 SubmitTask();
135
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
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
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;
151 gSystem->Unlink(ff);
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) {
181 else if (NeedToChooseWhatToAnalyse())
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
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
214 }
215
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) {
228 }
229
230 return kTRUE;
231}
232
233
234
236
238{
239 if (NeedToChooseWhatToDo()) {
240 return kFALSE;
241 }
242
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
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
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);
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
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",
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
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) {
659 } else {
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());
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
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", ""));
763 fBatchSystem->cd(); // make gBatchSystem point to it
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
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()));
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()));
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();
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;
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
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;
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
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());
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
virtual const Char_t * GetType() const
Definition KVBase.h:177
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 void SubmitTask(KVDataAnalyser *da)
virtual void WriteBatchEnvFile(TEnv *)
void cd()
Make this the default batch system.
virtual const Char_t * GetJobName() const
virtual void Print(Option_t *="") const
virtual void SetAnalyser(KVDataAnalyser *da)
virtual void ReadBatchEnvFile(TEnv *)
virtual void Clear(Option_t *opt="")
Manager class which sets up and runs data analysis tasks.
const Char_t * GetACliCMode()
KVString fUserClass
user's analysis class
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)
Bool_t fUseBaseClassSubmitTask
const Char_t * GetBatchName()
Long64_t nbEventToRead
virtual void PostRunReset()
virtual void Run()
Check all task variables, then run analyser.
Bool_t fSubmit
set to kTRUE when user wants to submit task
virtual void Reset()
std::unique_ptr< TEnv > fBatchEnv
batch environment file
virtual void AddJobDescriptionList(TList *)
KVDataAnalyser * fParent
holds address of parent analyser which created this one
virtual void WriteBatchEnvFile(const TString &, Bool_t sav=kTRUE)
void ChooseNbEventToRead()
Ask user to set number of events to read.
Bool_t RunningInLaunchDirectory()
KVString fLibraries
user's libraries
void SetUserLibraries(const Char_t *libs=0)
KVString fUserClassOptions
options to be passed to user analysis class
void SetUserClass(const Char_t *kvs, Bool_t check=kTRUE)
virtual Bool_t CheckIfUserClassIsValid(const KVString &alternative_base_class="")
virtual Bool_t NeedToChooseWhatToAnalyse() const
const Char_t * GetUserClass()
Bool_t fBatch
set to kTRUE when used in a non-interactive environment
TString GetPathToFileInLaunchDirectory(const TString &) const
KVDataAnalysisTask * GetAnalysisTask() 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
EProofMode fProofMode
void SetAnalysisTask(KVDataAnalysisTask *at)
Bool_t fUserClassIsOK
set once user class has been validated
virtual const Char_t * GetRecognisedAutoBatchNameKeywords() const
virtual void set_up_analyser_for_task(KVDataAnalyser *the_analyser)
virtual Bool_t NeedToChooseWhatToDo() const
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 ?
KVString fUserClassImp
user's analysis class implementation file
TList * fWorkDirInit
list of files in working directory before task runs
KVDataAnalyser()
Default constructor.
static Bool_t fCleanAbort
flag to force abort of processing
KVString fUserClassDec
user's analysis class header file
virtual Bool_t PreSubmitCheck()
static KVDataAnalyser * GetAnalyser(const Char_t *plugin)
KVString fIncludes
user's include directories
Bool_t fQuit
set to kTRUE when user wants to quit
EProofMode GetProofMode() const
static Bool_t IsRunningBatchAnalysis()
Bool_t fMenus
set to kTRUE in menu-driven mode
virtual ~KVDataAnalyser()
Default destructor.
KVString fUserClassAlternativeBaseClass
alternative base class for user's analysis class
static void RunAnalyser(const Char_t *plugin="")
void ScanWorkingDirectory(TList **)
void ChooseUserClass()
Choose the user's analysis class.
TList * fWorkDirEnd
list of files in working directory after task runs
Long64_t GetNbEventToRead(void) const
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 OpenBatchInfoFile(const TString &filename)
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
Bool_t fChoseRunMode
set to kTRUE once running mode has been set/chosen
TObject * GetInstanceOfUserClass(const KVString &alternative_base_class="")
TEnv * GetBatchInfoFile() const
KVString fDataType
datatype chosen by user
KVDataAnalysisTask * fTask
task chosen by user
void SetNbEventToRead(Long64_t nb=0)
Define and manage data analysis tasks.
virtual Bool_t CheckUserBaseClassIsLoaded()
virtual const Char_t * GetDataAnalyser() const
virtual const Char_t * GetUserBaseClass() const
virtual Bool_t WithUserClass() const
virtual Long64_t GetStatusUpdateInterval() const
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 * FindObject(const char *name) const override
TObject * At(Int_t idx) const override
const char * GetName() const override
const TString & GetString() const
virtual const char * GetName() const
virtual const char * ClassName() const
virtual void Warning(const char *method, const char *msgfmt,...) const
virtual Bool_t InheritsFrom(const char *classname) const
virtual void Error(const char *method, const char *msgfmt,...) const
virtual void Fatal(const char *method, const char *msgfmt,...) const
virtual void ls(Option_t *option="") const
virtual void Info(const char *method, const char *msgfmt,...) 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
Long_t fMemVirtual
Float_t fCpuSys
Long_t fMemResident
Float_t fCpuUser
TString fUser
TLine l
auto * tt
ClassImp(TPyArg)