KaliVeda
Toolkit for HIC analysis
KVDataSet.cpp
1 /*
2 $Id: KVDataSet.cpp,v 1.41 2009/03/11 14:22:41 franklan Exp $
3 $Revision: 1.41 $
4 $Date: 2009/03/11 14:22:41 $
5 $Author: franklan $
6 */
7 
8 #include "TMethodCall.h"
9 #include "KVDataSet.h"
10 #include "KVDataRepository.h"
11 #include "KVDataRepositoryManager.h"
12 #include "KVDataSetManager.h"
13 #include "TSystem.h"
14 #include "TObjArray.h"
15 #include "TObjString.h"
16 #include "KVDBSystem.h"
17 #include "KVDBRun.h"
18 #include "TEnv.h"
19 #include "KVAvailableRunsFile.h"
20 #include "KVNumberList.h"
21 #include "TPluginManager.h"
22 #include "TClass.h"
23 #include "KVRunFile.h"
24 
25 using namespace std;
26 
28 
29 KVDataSet* gDataSet;
30 
31 
34 
36 {
37  //Default constructor
38  fRepository = nullptr;
39  fDataBase = nullptr;
40  fAllTasks.SetOwner(kTRUE);
41  fTasks.SetOwner(kFALSE);
42 }
43 
44 
45 
49 
51 {
52  //Returns available runs file object for given data 'type' (="raw", "recon", "ident", "root")
53  //Object will be created and added to internal list if it does not exist
54 
55  if (!fRepository) return nullptr;
56  KVAvailableRunsFile* avrf =
57  (KVAvailableRunsFile*) fAvailableRuns.FindObjectByName(type);
58  if (!avrf) {
59  avrf = fRepository->NewAvailableRunsFile(type, this);
60  fAvailableRuns.Add(avrf);
61  }
62  return avrf;
63 }
64 
65 
66 
71 
73 {
74  //Returns name of file containing database for dataset.
75  //If this is not set explicitly with SetDBFileName(), the default value defined by DataSet.DatabaseFile
76  //in $KVROOT/KVFiles/.kvrootrc will be returned.
77 
78  if (fDBFileName != "")
79  return fDBFileName.Data();
80  return gEnv->GetValue("DataSet.DatabaseFile", "");
81 }
82 
83 
84 
88 
90 {
91  //Returns name of database object in database file.
92  //If this is not set explicitly with SetDBName(), we use the name of the dataset by default
93 
94  if (fDBName != "")
95  return fDBName.Data();
96  return GetName();
97 }
98 
99 
100 
101 
104 
105 void KVDataSet::OpenDBFile(const Char_t* full_path_to_dbfile) const
106 {
107  //Open the database from a file on disk.
108 
109  TDirectory* work_dir = gDirectory; //keep pointer to current directory
110  fDBase.reset(new TFile(full_path_to_dbfile, "READ"));
111 
112  if (fDBase->IsOpen()) {
113  fDataBase = dynamic_cast<KVExpDB*>(fDBase->Get(GetDBName()));
114  if (!fDataBase) {
115  Error("OpenDBFile", "%s not found in file %s", GetDBName(),
116  GetDBFileName());
117  }
118  else {
119  fDataBase->ReadObjects(fDBase.get()); // read any associated objects
120  }
121  work_dir->cd(); //back to initial working directory
122  }
123 }
124 
125 
126 
127 
130 
132 {
133  // Returns full path to file where database is written on disk
134 
135  TString dbfile = GetDBFileName();
136  static TString dbfile_fullpath;
137  TString tmp;
138 
139  // If this dataset is just an alias for another dataset i.e. if DataSet.Directory
140  // is set with just the name of another dataset (not a full path to dataset files)
141  // then the database file should be written/found under the name of the alias.
142  TString dataset_alias = GetDataSetEnv("DataSet.Directory", GetName());
143  TString db_alias = GetName();
144  if (!gSystem->IsAbsoluteFileName(dataset_alias)) db_alias = dataset_alias;
145 
146  AssignAndDelete(tmp, gSystem->ConcatFileName(GetDATABASEFilePath(), db_alias.Data()));
147  AssignAndDelete(dbfile_fullpath, gSystem->ConcatFileName(tmp.Data(), dbfile.Data()));
148  return dbfile_fullpath.Data();
149 }
150 
151 
152 
158 
160 {
161  //PROTECTED METHOD
162  //Called by KVDataSet::SetAnalysisTasks
163  //Check environment variables (i.e. .kvrootrc) to see if the task parameters
164  //have been "tweaked" for the dataset.
165 
166  KVString envar = GetDataSetEnv(Form("%s.DataAnalysisTask.Title", t->GetName()));
167  if (envar != "") t->SetTitle(envar);
168  envar = GetDataSetEnv(Form("%s.DataAnalysisTask.Analyser", t->GetName()));
169  if (envar != "") t->SetDataAnalyser(envar);
170  envar = GetDataSetEnv(Form("%s.DataAnalysisTask.UserClass.Base", t->GetName()));
171  if (envar != "") t->SetUserBaseClass(envar);
172  envar = GetDataSetEnv(Form("%s.DataAnalysisTask.Prereq", t->GetName()));
173  if (envar != "") t->SetPrereq(envar);
174  envar = GetDataSetEnv(Form("%s.DataAnalysisTask.UserClass.ExtraACliCIncludes", t->GetName()));
175  if (envar != "") t->SetExtraAClicIncludes(envar);
176  Int_t nev = (Int_t)GetDataSetEnv(Form("%s.DataAnalysisTask.StatusUpdateInterval", t->GetName()), 0.0);
177  if (nev > 0) t->SetStatusUpdateInterval(nev);
178 }
179 
180 
181 
182 
193 
195 {
196  // Write the database to disk (ROOT file).
197  // It will be written in the directory
198  // $KVROOT/db/[dataset name]
199  // If the directory does not exist, it will be created. Permissions are set to 775 (rwxrwxr-x).
200  //
201  // # Default name of database file containing informations on runs, systems, calibration parameters etc.
202  // DataSet.DatabaseFile: DataBase.root
203  // # Default name of database object in file
204  // DataSet.DatabaseName: DataBase
205 
206  TString dbfile_fullpath = GetFullPathToDB();
207  TString tmp = gSystem->DirName(dbfile_fullpath.Data()); //full path to directory $KVROOT/db/[dataset name]
208 
209  if (gSystem->AccessPathName(tmp.Data())) { // directory $KVROOT/db/[dataset name] does not exist
210 
211  if (gSystem->mkdir(tmp.Data()) == -1) { // problem creating $KVROOT/db/[dataset name]
212 
213  TString tmp2 = gSystem->DirName(tmp.Data());// full path to directory $KVROOT/db
214 
215  if (gSystem->AccessPathName(tmp2.Data())) { // directory $KVROOT/db does not exist
216 
217  if (gSystem->mkdir(tmp2.Data()) == -1) { // problem creating $KVROOT/db
218  Error("SaveDataBase", "Cannot create directory %s required to save database",
219  tmp2.Data());
220  return;
221  }
222  gSystem->Chmod(tmp2.Data(), 0775);
223  }
224  else {
225  Error("SaveDataBase", "Cannot create directory %s required to save database, even though %s exists: check disk space ?",
226  tmp.Data(), tmp2.Data());
227  return;
228  }
229  //try again
230  if (gSystem->mkdir(tmp.Data()) == -1) {
231  Error("SaveDataBase", "Cannot create directory %s required to save database",
232  tmp.Data());
233  return;
234  }
235  else {
236  gSystem->Chmod(tmp.Data(), 0775);
237  }
238  }
239  else {
240  gSystem->Chmod(tmp.Data(), 0775);
241  }
242  }
243 
244  WriteDBFile(dbfile_fullpath.Data());
245 }
246 
247 
248 
249 
254 
255 void KVDataSet::WriteDBFile(const Char_t* full_path_to_dbfile) const
256 {
257  //PRIVATE METHOD
258  //Write the database to disk.
259  //Set permissions to rw for user & group
260 
261  TDirectory* work_dir = gDirectory; //keep pointer to current directory
262  if (!fDataBase) {
263  Error("WriteDBFile", "Database has not been built");
264  return;
265  }
266  fDBase.reset(new TFile(full_path_to_dbfile, "recreate"));
267  fDBase->cd(); //set as current directory (maybe not necessary)
268  fDataBase->Write(GetDBName()); //write database to file with given name
269  fDataBase->WriteObjects(fDBase.get()); //write any associated objects
270  fDBase->Write(); // write file header etc.
271  fDBase->Close(); // close file
272  gSystem->Chmod(full_path_to_dbfile, 0664); // set permissions to rw-rw-r--
273  work_dir->cd(); //back to initial working directory
274 }
275 
276 
277 
288 
290 {
291  //Returns pointer to database associated with this dataset.
292  //Opens, updates or creates database file if necessary
293  //(the database is automatically rebuilt if the source files are
294  //more recent than the last database file).
295  //
296  //If opt="update":
297  // close and delete database if already open
298  // regenerate database from source files
299  //Use this option to force the regeneration of the database.
300 
301  TString _opt(opt);
302  _opt.ToUpper();
303  if (_opt == "UPDATE") {
304  OpenDataBase(_opt.Data());
305  }
306  else {
307  OpenDataBase();
308  }
309  return fDataBase;
310 }
311 
312 
313 
334 
336 {
337  //Open the database for this dataset.
338  //If the database does not exist or is older than the source files
339  //the database is automatically rebuilt
340  //(see DataBaseNeedUpdate()).
341  //Use opt="UPDATE" to force rebuilding of the database.
342  //
343  //First, we look in to see if the database file exists
344  //(if no database file name given, use default name for database file defined in
345  //.rootrc config files).
346  //If so, we open the database contained in the file, after first loading the required plugin
347  //library if needed.
348  //
349  //The name of the dataset must correspond to the name of one of the Plugin.KVDataBase
350  //plugins defined in the .rootrc configuration files
351  //
352  //WARNING: if the database needs to be (re)built, we set gDataSet to
353  //point to this dataset in case it was not already done,
354  //as in order to (re)build the database it may be necessary for
355  //gDataSet to point to the current dataset.
356 
357  Bool_t is_glob_db = kFALSE;
358  //if option="update" or database out of date or does not exist, (re)build the database
359  if ((!strcmp(opt, "UPDATE")) || DataBaseNeedsUpdate()) {
360  //check if it is the currently active database (gDataBase),
361  //in which case we must 'cd()' to it after rebuilding
362  Info("OpenDataBase", "Updating database file");
363  fDataBaseUpdateInProgress = true;
364  is_glob_db = (fDataBase == gExpDB);
365  if (fDataBase) {
366  delete fDataBase;
367  fDataBase = 0;
368  }
369  // make sure gDataSet is set & points to us
370  gDataSet = const_cast<KVDataSet*>(this);
371  fDataBase = KVExpDB::MakeDataBase(GetDBName(), GetDataSetDir());
372  if (!fDataBase) {
373  // no database defined for dataset
374  Info("OpenDataBase", "No database defined for dataset");
375  return;
376  }
377  SaveDataBase();
378  if (fDataBase && is_glob_db) fDataBase->cd();
379  fDataBaseUpdateInProgress = false;
380  }
381  else if (!fDataBase) {
382  // if database is not in memory at this point, we need to
383  // open the database file and read in the database
384 
385  //load plugin for database
386  if (!LoadPlugin("KVExpDB", GetDBName())) {
387  Error("GetDataBase", "Cannot load required plugin library");
388  return;
389  }
390  //look for database file in dataset subdirectory
391  TString dbfile_fullpath = GetFullPathToDB();
392  //open database file
393  OpenDBFile(dbfile_fullpath.Data());
394  }
395 }
396 
397 
398 
399 
402 
404 {
405  //Print dataset information
406  cout << "Dataset name=" << GetName() << " (" << GetTitle() << ")";
407  if (IsAvailable()) {
408  cout << " [ AVAILABLE: ";
409  cout << fDatatypes.Data();
410  cout << "]";
411  }
412  else
413  cout << " [UNAVAILABLE]";
414  cout << endl;
415 }
416 
417 
418 
423 
424 void KVDataSet::Print(Option_t* opt) const
425 {
426  //Print dataset information
427  //If option string contains "tasks", print numbered list of tasks that can be performed
428  //If option string contains "data", print list of available data types
429 
430  TString Sopt(opt);
431  Sopt.ToUpper();
432  if (Sopt.Contains("TASK")) {
433  if (!GetNtasks()) {
434  cout << " *** No available analysis tasks ***"
435  << endl;
436  return;
437  }
438  else {
439  for (int i = 1; i <= GetNtasks(); i++) {
440  KVDataAnalysisTask* dat = GetAnalysisTask(i);
441  cout << "\t" << i << ". " << dat->GetTitle() << endl;
442  }
443  }
444  cout << endl;
445  }
446  else if (Sopt.Contains("DATA")) {
447  cout << "Available data types: " << fDatatypes.Data() << endl;
448  }
449  else {
450  ls(opt);
451  }
452 }
453 
454 
455 
474 
476 {
477  //Check if this data set is physically present and available for analysis.
478  //In other words we check if the value of GetDatapathSubdir() is a subdirectory
479  //of the given data repository
480  //If so, we proceed to check for the existence of any of the datatypes defined in
481  //
482  //KVDataSet.DataTypes:
483  //
484  //by checking for the associated sudirectories defined in the corresponding variables:
485  //
486  //KVDataSet.DataType.Subdir.[type]:
487  //
488  //If none of them exists, the dataset will be reset to 'unavailable'
489  //Otherwise the corresponding flags are set.
490  //
491  //Note that if SetUserGroups has been called with a list of groups allowed to read this data,
492  //the current user's name (gSystem->GetUserInfo()->fUser) will be used to check if the
493  //dataset is available. The user name must appear in the group defined by SetUserGroups.
494 
495  if (!fRepository) // for a stand-alone KVDataSetManager not linked to a KVDataRepository,
496  SetAvailable(); // all known datasets are 'available'
497  else
498  SetAvailable(fRepository->CheckSubdirExists(GetDataPathSubdir()));
499  if (!IsAvailable())
500  return;
501  //check subdirectories
502  KVString data_types = GetDataSetEnv("KVDataSet.DataTypes", "");
503  if (data_types == "") {
504  Warning("CheckAvailable", "No datatypes defined for this dataset: %s\nCheck value of KVDataSet.DataTypes or %s.KVDataSet.DataTypes",
505  GetName(), GetName());
506  SetAvailable(kFALSE);
507  }
508  fDatatypes = "";
509  // loop over data types
510  data_types.Begin(" ");
511  while (!data_types.End()) {
512  KVString type = data_types.Next(kTRUE);
513  if (!fRepository ||
514  (fRepository && fRepository->CheckSubdirExists(GetDataPathSubdir(), GetDataTypeSubdir(type.Data())))
515  ) {
516  AddAvailableDataType(type.Data());
517  }
518  }
519  //check at least one datatype exists
520  SetAvailable(fDatatypes != "");
521  //check user name against allowed groups
522  if (!CheckUserCanAccess()) {
523  SetAvailable(kFALSE);
524  return;
525  }
526 }
527 
528 
529 
531 
533 {
534  if (fDatatypes != "") fDatatypes += " ";
535  KVString _type = type;
536  _type.Remove(TString::kBoth, ' '); //strip whitespace
537  fDatatypes += _type;
538 }
539 
540 
541 
548 
550 {
551  // Add to fAllTasks list any data analysis task in list 'task_list'
552  //
553  // Add to fTasks list any data analysis task in list 'task_list' whose pre-requisite datatype is present for this dataset.
554  //
555  // Any dataset-specific "tweaking" of the task (including the prerequisite datatype) is done here.
556 
557  TString availables = gEnv->GetValue(Form("%s.DataAnalysisTask", GetName()), "");
558  fAllTasks.Clear();
559  fTasks.Clear();
560  TIter nxt(task_list);
561  KVDataAnalysisTask* dat;
562  while ((dat = (KVDataAnalysisTask*) nxt())) {
563  //make new copy of default analysis task
564  if (availables == "" || availables.Contains(dat->GetName())) {
565  KVDataAnalysisTask* new_task = new KVDataAnalysisTask(*dat);
566  //check if any dataset-specific parameters need to be changed
567  SetDataSetSpecificTaskParameters(new_task);
568  fAllTasks.Add(new_task);
569  // add tasks with available prerequisite data to fTasks
570  if (HasDataType(new_task->GetPrereq())) {
571  fTasks.Add(new_task);
572  }
573  }
574  }
575 }
576 
577 
578 
582 
584 {
585  //Returns the number of tasks associated to dataset which are compatible
586  //with the available data
587 
588  return fTasks.GetSize();
589 }
590 
591 
592 
597 
599 {
600  //Return kth analysis task in list of available tasks.
601  //k=[1, GetNtasks()] and corresponds to the number shown next to the title of the task when
602  //KVDataSet::Print("tasks") is called
603  return (KVDataAnalysisTask*) fTasks.At(k - 1);
604 }
605 
606 
607 
622 
624 {
625  //Create and fill a list of available systems for this dataset and the given datatype
626  //
627  //This uses the database associated to the dataset.
628  //USER MUST DELETE THE LIST AFTER USE.
629  //
630  //For each system in the list we set the number of available runs : this number
631  //can be retrieved with KVDBSystem::GetNumberRuns()
632  //
633  //If systol!=0 then in fact the list contains a list of runs for the given system which are available.
634  //
635  //If no systems are defined for the dataset then we return a list of available runs
636  //for the given datatype
637 
638  //open the available runs file for the data type
639  if (!GetAvailableRunsFile(datatype)) {
640  Error("GetListOfAvailableSystems(const Char_t*)",
641  "No available runs file for type %s", datatype);
642  return 0;
643  }
644  return GetAvailableRunsFile(datatype)->GetListOfAvailableSystems(systol);
645 }
646 
647 
648 
662 
664 {
665  //Create and fill a list of available systems for this dataset and the prerequisite
666  //datatype for the given data analysis task.
667  //This uses the database associated to the dataset.
668  //USER MUST DELETE THE LIST AFTER USE.
669  //
670  //For each system in the list we set the number of available runs : this number
671  //can be retrieved with KVDBSystem::GetNumberRuns()
672  //
673  //If systol!=0 then in fact the list contains a list of runs for the given system which are available.
674  //
675  //If no systems are defined for the dataset then we return a list of available runs
676  //for the given datatype
677 
678  return GetListOfAvailableSystems(datan->GetPrereq(), systol);
679 }
680 
681 
682 
696 
697 void KVDataSet::SetName(const char* name)
698 {
699  // Set name of dataset.
700  // Also sets path to directory containing database informations
701  // for this dataset, i.e. list of runs, systems, calibration files etc.
702  // By default, just the name of the dataset is used, i.e.
703  // [DATADIR]/name
704  // (where DATADIR = path given by KVBase::GetDATADIRFilePath())
705  // However, if the variable
706  // [name].DataSet.Directory: [path]
707  // has been set, the value of [path] will be used.
708  // If [path] is an absolute path name, it will be used as such.
709  // If [path] is an incomplete or relative path, it will be prepended
710  // with [DATADIR]/
712  TString path = GetDataSetEnv("DataSet.Directory", name);
713  if (gSystem->IsAbsoluteFileName(path)) fCalibDir = path;
714  else {
715  // in this case (not an absolute path but just the name of another dataset)
716  // this dataset is an alias for another dataset.
717  fCalibDir = GetDATADIRFilePath(path);
718  // the name of the database object is the name of the "true" dataset
719  SetDBName(path);
720  }
721 }
722 
723 
724 
728 
730 {
731  //Returns full path to directory containing database and calibration/identification parameters etc.
732  //for this dataset.
733  return fCalibDir.Data();
734 }
735 
736 
737 
744 
745 void KVDataSet::cd() const
746 {
747  //Data analysis can only be performed if the data set in question
748  //is "activated" or "selected" using this method.
749  //At the same time, the data repository, dataset manager and database associated with
750  //this dataset also become the "active" ones (pointed to by the respective global
751  //pointers, gDataRepository, gDataBase, etc. etc.)
752 
753  gDataSet = const_cast<KVDataSet*>(this);
754  if (fRepository) fRepository->cd();
755  KVExpDB* db = GetDataBase();
756  if (db) db->cd();
757 }
758 
759 
760 
761 
766 
767 const Char_t* KVDataSet::GetDataSetEnv(const Char_t* type, const Char_t* defval) const
768 {
769  //Will look for gEnv->GetValue "name_of_dataset.type"
770  //then simply "type" if no dataset-specific value is found.
771  //If neither resource is defined, return the "defval" default value (="" by default)
772 
773  return KVBase::GetDataSetEnv(GetName(), type, defval);
774 }
775 
776 
777 
778 
783 
785 {
786  //Will look for gEnv->GetValue "name_of_dataset.type"
787  //then simply "type" if no dataset-specific value is found.
788  //If neither resource is defined, return the "defval" default value
789 
790  return KVBase::GetDataSetEnv(GetName(), type, defval);
791 }
792 
793 
794 
795 
800 
801 Bool_t KVDataSet::GetDataSetEnv(const Char_t* type, Bool_t defval) const
802 {
803  //Will look for gEnv->GetValue "name_of_dataset.type"
804  //then simply "type" if no dataset-specific value is found.
805  //If neither resource is defined, return the "defval" default value
806 
807  return KVBase::GetDataSetEnv(GetName(), type, defval);
808 }
809 
810 
811 
812 
813 
841 
843 {
844  // Open file containing data of given datatype for given run number of this dataset.
845  //
846  // Returns a pointer to the opened file; if the file is not available, we return nullptr.
847  //
848  // The user must cast the returned pointer to the correct class, which will
849  // depend on the data type and the dataset (see `$KVROOT/KVFiles/.kvrootrc`)
850  //
851  // **SPECIAL CASE: MFM data with EBYEDAT frames**
852  //
853  // If the variable
854  //
855  //~~~~~~~~~~~~~~~~~~~~~~~~~
856  // [dataset].MFM.WithEbyedat: yes
857  //~~~~~~~~~~~~~~~~~~~~~~~~~
858  //
859  // is set, then we expect to find the necessary `ACTIONS_*` files in the dataset directory
860  // in subdirectory `ebyedat` (they should have the same names as the data files prefixed by
861  // `ACTIONS_[expname].CHC_PAR.`).
862  //
863  // If in addition the variable
864  //
865  //~~~~~~~~~~~~~~~~~~~~~~~~~
866  // [dataset].MFM.EbyedatActionsExpName: [expname]
867  //~~~~~~~~~~~~~~~~~~~~~~~~~
868  //
869  // is set, then we use the same `ACTIONS` file for all runs, with name `ACTIONS_[expname].CHC_PAR`
870 
871 
872  if (!strcmp(type, "raw") && !strcmp(GetDataSetEnv("MFM.WithEbyedat", ""), "yes")) {
873  TString ebydir = GetDataSetDir();
874  ebydir += "/ebyedat";
875  gEnv->SetValue("KVMFMDataFileReader.ActionsDirectory", ebydir);
876  if (strcmp(GetDataSetEnv("MFM.EbyedatActionsExpName", ""), ""))
877  gEnv->SetValue("KVMFMDataFileReader.ActionsExpName", GetDataSetEnv("MFM.EbyedatActionsExpName", ""));
878  TObject* f = GetRepository()->OpenDataSetRunFile(this, type, run, GetName());
879  // reset in case another dataset opens a raw MFM file without EBYEDAT data
880  gEnv->SetValue("KVMFMDataFileReader.ActionsDirectory", "");
881  gEnv->SetValue("KVMFMDataFileReader.ActionsExpName", "");
882  return f;
883  }
884  return GetRepository()->OpenDataSetRunFile(this, type, run, GetName());
885 }
886 
887 
888 
889 
896 
898  Int_t run) const
899 {
900  //Return full path to file containing data of given datatype for given run number
901  //of this dataset. NB. only works for available run files, if their is no file in the repository for this run,
902  //the returned path will be empty.
903  //This path should be used with e.g. TChain::Add.
904 
905  //get name of file from available runs file
906  TString file("");
907  if (fRepository) file = GetRunfileName(type, run);
908  if (file == "")
909  return file.Data();
910  return fRepository->GetFullPathToOpenFile(this, type, file.Data());
911 }
912 
913 
914 
915 
922 
923 const Char_t* KVDataSet::GetRunfileName(const Char_t* type, Int_t run) const
924 {
925  //Return name of file containing data of given datatype
926  //for given run number of this dataset.
927  //NB. only works for available run files, if there is no file in the repository for this run,
928  //the returned path will be empty.
929 
930  //check data type is available
931  if (!HasDataType(type)) {
932  Error("GetRunfileName",
933  "No data of type \"%s\" available for dataset %s", type,
934  GetName());
935  return 0;
936  }
937  //get name of file from available runs file
938  return GetAvailableRunsFile(type)->GetFileName(run);
939 }
940 
941 
942 
943 
950 
952 {
953  //Return date of file containing data of given datatype
954  //for given run number of this dataset.
955  //NB. only works for available run files, if there is no file in the repository for this run,
956  //an error will be printed and the returned data is set to "Sun Jan 1 00:00:00 1995"
957  //(earliest possible date for TDatime class).
958 
959  static TDatime date;
960  date.Set(1995, 1, 1, 0, 0, 0);
961  //check data type is available
962  if (!HasDataType(type)) {
963  Error("GetRunfileDate",
964  "No data of type \"%s\" available for dataset %s", type,
965  GetName());
966  return date;
967  }
968  //get date of file from available runs file
970  if (!GetAvailableRunsFile(type)->GetRunInfo(run, date, filename)) {
971  Error("GetRunfileDate",
972  "Runfile not found for run %d (data type: %s)", run, type);
973  }
974  return date;
975 }
976 
977 
978 
979 
984 
986 {
987  //We check the availability of the run by looking in the available runs file associated
988  //with the given datatype.
989 
990  //check data type is available
991  if (!HasDataType(type)) {
992  Error("CheckRunfileAvailable",
993  "No data of type \"%s\" available for dataset %s", type,
994  GetName());
995  return 0;
996  }
997  return GetAvailableRunsFile(type)->CheckAvailable(run);
998 }
999 
1000 
1001 
1002 
1012 
1013 const Char_t* KVDataSet::GetBaseFileName(const Char_t* type, Int_t run) const
1014 {
1015  //PRIVATE METHOD: Returns base name of data file containing data for the run of given datatype.
1016  //The filename corresponds to one of the formats defined in $KVROOT/KVFiles/.kvrootrc
1017  //by variables like:
1018  //
1019  //[dataset].DataSet.RunFileName.[type]: run%R.dat
1020  //
1021  //%R will be replaced with the run number
1022  //IF the format contains '%D' it will be replaced with the current date and time
1023 
1024  static TString tmp;
1025  //get format string
1026  TString fmt = GetDataSetEnv(Form("DataSet.RunFileName.%s", type));
1027  TString run_num(Form("%d", run));
1028  KVDatime now;
1029  TString date(now.AsSQLString());
1030  tmp = fmt;
1031  tmp.ReplaceAll("%R", run_num);
1032  if (fmt.Contains("%D")) {
1033  tmp.ReplaceAll("%D", date);
1034  }
1035  return tmp.Data();
1036 }
1037 
1038 
1039 
1040 
1044 
1046 {
1047  //Update list of available runs for given data 'type'
1048 
1049  //check data type is available
1050  if (!HasDataType(type)) {
1051  Error("UpdateAvailableRuns",
1052  "No data of type \"%s\" available for dataset %s", type,
1053  GetName());
1054  }
1055  KVAvailableRunsFile* a = GetAvailableRunsFile(type);
1056  a->Update(!a->FileExists());
1057 }
1058 
1059 
1060 
1061 
1066 
1068 {
1069  // Create a new runfile for the dataset of given datatype.
1070  // (only if this dataset is associated with a data repository)
1071  // Once the file has been filled, use CommitRunfile to submit it to the repository.
1072 
1073  if (!fRepository) return nullptr;
1074  TString tmp = GetBaseFileName(type, run);
1075  //turn any spaces into "_"
1076  tmp.ReplaceAll(" ", "_");
1077  return fRepository->CreateNewFile(this, type, tmp.Data());
1078 }
1079 
1080 
1081 
1082 
1091 
1092 void KVDataSet::DeleteRunfile(const Char_t* type, Int_t run, Bool_t confirm)
1093 {
1094  // Delete the file for the given run of data type "type" from the repository.
1095  // By default, confirm=kTRUE, which means that the user will be asked to confirm
1096  // that the file should be deleted. If confirm=kFALSE, no confirmation will be asked
1097  // for and the file will be deleted straight away.
1098  //
1099  // WARNING: this really does DELETE files in the repository, they cannot be
1100  // retrieved once they have been deleted.
1101 
1102  if (!fRepository) return;
1103 
1104  //get name of file to delete
1105  TString filename = GetAvailableRunsFile(type)->GetFileName(run);
1106  if (filename == "") {
1107  Error("DeleteRunfile", "Run %d of type %s does not exist.", run, type);
1108  return;
1109  }
1110  //delete file
1111  //prevent accidental deletion of certain types of runfiles
1112  KVString doNotDelete = GetDataSetEnv("DataSet.RunFile.DoNotDelete", "all");
1113  if (doNotDelete == "all" || doNotDelete.Contains(type)) {
1114  Error("DeleteRunFile", "%s files cannot be deleted", type);
1115  return;
1116  }
1117  fRepository->DeleteFile(this, type, filename.Data(), confirm);
1118  //was file deleted ? if so, remove entry from available runs file
1119  if (!fRepository->CheckFileStatus(this, type, filename.Data()))
1120  GetAvailableRunsFile(type)->Remove(run);
1121 }
1122 
1123 
1124 
1125 
1135 
1136 void KVDataSet::DeleteRunfiles(const Char_t* type, KVNumberList nl, Bool_t confirm)
1137 {
1138  //Delete files corresponding to a list of runs of data type "type" from the repository.
1139  //By default, confirm=kTRUE, which means that the user will be asked to confirm
1140  //that each file should be deleted. If confirm=kFALSE, no confirmation will be asked
1141  //for and the file will be deleted straight away.
1142  //if "nl" is empty (default value) all runs of the dataset corresponding to the given type
1143  //will be deleted
1144  //WARNING: this really does DELETE files in the repository, they cannot be
1145  //retrieved once they have been deleted.
1146 
1147  if (nl.IsEmpty()) nl = GetRunList(type);
1148  if (nl.IsEmpty()) return;
1149  nl.Begin();
1150  while (!nl.End()) {
1151  DeleteRunfile(type, nl.Next(), confirm);
1152  }
1153 }
1154 
1155 
1156 
1157 
1164 
1166 {
1167  //Prints out and returns list of runs after date / time selection
1168  //Runs generated between ]min;max[ are selected
1169  //if min=NULL runs with date <max are selected
1170  //if max=NULL runs with date >min are selected
1171  //if max and min are NULL returns empty KVNumberList
1172 
1173  if (!min && !max) return 0;
1174 
1175  if (min) printf("date minimum %s\n", min->AsString());
1176  if (max) printf("date maximum %s\n", max->AsString());
1177 
1178  KVNumberList numb;
1179 
1180  unique_ptr<TList> ll(GetListOfAvailableSystems(type));
1181  KVDBSystem* sys = 0;
1182  KVRunFile* run = 0;
1183  unique_ptr<TList> lrun;
1184  for (Int_t nl = 0; nl < ll->GetEntries(); nl += 1) {
1185  sys = (KVDBSystem*)ll->At(nl);
1186  lrun.reset(GetListOfAvailableSystems(type, sys));
1187  KVNumberList oldList = numb;
1188  for (Int_t nr = 0; nr < lrun->GetEntries(); nr += 1) {
1189  run = (KVRunFile*)lrun->At(nr);
1190 
1191  if (min && max) {
1192  if (*min < run->GetRun()->GetDatime() && run->GetRun()->GetDatime() < *max) {
1193  numb.Add(run->GetRunNumber());
1194  }
1195  }
1196  else if (min) {
1197  if (*min < run->GetRun()->GetDatime()) {
1198  numb.Add(run->GetRunNumber());
1199  }
1200  }
1201  else if (max) {
1202  if (run->GetRun()->GetDatime() < *max) {
1203  numb.Add(run->GetRunNumber());
1204  }
1205  }
1206  }
1207  // print runs for system if any
1208  if (numb.GetEntries() > oldList.GetEntries()) printf("%s : %s\n", sys->GetName(), (numb - oldList).AsString());
1209  }
1210  return numb;
1211 
1212 }
1213 
1214 
1215 
1216 
1222 
1223 KVNumberList KVDataSet::GetRunList_StageSelection(const Char_t* type, const Char_t* ref_type, KVDBSystem* system, Bool_t OnlyCol)
1224 {
1225  // Returns list of runs which are present for data type "base_type" but not for "other_type"
1226  // if type is NULL or ="" returns empty KVNumberList
1227  // If pointer to system is given, only runs for the system are considered.
1228  // If OnlyCol=kTRUE (kFALSE default) only systems with KVDBSystem::IsCollision()=kTRUE are considered
1229 
1230  KVNumberList manquant;
1231  TList* ll = GetListOfAvailableSystems(ref_type);
1232  if (!ll || !ll->GetEntries()) {
1233  //numb.Clear();
1234  Info("GetRunList_StageSelection", "No data available of type \"%s\"", ref_type);
1235  if (ll) delete ll;
1236  return manquant;
1237  }
1238  if (system && !ll->FindObject(system)) {
1239  Info("GetRunList_StageSelection", "No data available of type \"%s\" for system %s", ref_type, system->GetName());
1240  delete ll;
1241  return manquant;
1242  }
1243 
1244  Info("GetRunList_StageSelection", "Liste des runs presents dans \"%s\" mais absent dans \"%s\"", ref_type, type);
1245 
1246  KVDBSystem* sys = 0;
1247  KVNumberList nsys_ref;
1248  KVNumberList nsys;
1249 
1250  for (Int_t nl = 0; nl < ll->GetEntries(); nl += 1) {
1251 
1252  sys = (KVDBSystem*)ll->At(nl);
1253  if (system && sys != system) continue;
1254  if (OnlyCol && !sys->IsCollision()) continue;
1255  nsys = GetRunList(type, sys);
1256  nsys_ref = GetRunList(ref_type, sys);
1257  Int_t nref = nsys_ref.GetNValues();
1258 
1259  nsys_ref.Remove(nsys);
1260 
1261  Info("GetRunList_StageSelection", "\nKVDBSystem : %s --> %d runs manquants sur %d : %s",
1262  sys->GetName(),
1263  nsys_ref.GetNValues(),
1264  nref,
1265  nsys_ref.AsString()
1266  );
1267  manquant.Add(nsys_ref);
1268  }
1269  delete ll;
1270  return manquant;
1271 
1272 }
1273 
1274 
1275 
1279 
1281 {
1282  // Returns list of runs of given type that were created with the given version of KaliVeda.
1283  // If system!="" then only runs for the given system are considered
1284 
1285  KVNumberList runs;
1286  if (sys) {
1287  unique_ptr<TList> lrun(GetListOfAvailableSystems(type, sys));
1288  TIter next(lrun.get());
1289  KVRunFile* run;
1290  while ((run = (KVRunFile*)next())) {
1291  if (!strcmp(run->GetVersion(), version)) runs.Add(run->GetRunNumber());
1292  }
1293  return runs;
1294  }
1295  unique_ptr<TList> ll(GetListOfAvailableSystems(type));
1296  if (!ll.get() || !ll->GetEntries()) {
1297  //numb.Clear();
1298  Info("GetRunList_VersionSelection", "No data available of type \"%s\"", type);
1299  return runs;
1300  }
1301  Int_t nsys = ll->GetEntries();
1302  for (Int_t nl = 0; nl < nsys; nl += 1) {
1303  sys = (KVDBSystem*)ll->At(nl);
1304  unique_ptr<TList> lrun(GetListOfAvailableSystems(type, sys));
1305  TIter next(lrun.get());
1306  KVRunFile* run;
1307  while ((run = (KVRunFile*)next())) {
1308  if (!strcmp(run->GetVersion(), version)) runs.Add(run->GetRunNumber());
1309  }
1310  }
1311  return runs;
1312 }
1313 
1314 
1315 
1320 
1322 {
1323  // Commit a runfile previously created with NewRunfile() to the repository.
1324  // Any previous version of the runfile will be deleted.
1325  // The available runs list for this data 'type' is updated.
1326 
1327  if (!fRepository) return;
1328 
1329  //keep name of file for updating available runs list
1330  TString newfile = gSystem->BaseName(file->GetName());
1331 
1332  fRepository->CommitFile(file, type, this);
1333  //update list of available datatypes of dataset,
1334  //in case this addition has created a new subdirectory
1335  CheckAvailable();
1336  //check if previous version of file exists
1337  //get name of file from available runs file
1338  //note that when the file is the first of a new subdirectory, GetAvailableRunsFile->GetFileName
1339  //will cause the available runs file to be created, and it will contain one entry:
1340  //the new file!
1341  TString oldfile = GetAvailableRunsFile(type)->GetFileName(run);
1342  if (oldfile != "" && oldfile != newfile) {
1343  //delete previous version - no confirmation
1344  fRepository->DeleteFile(this, type, oldfile.Data(),
1345  kFALSE);
1346  //was file deleted ? if so, remove entry from available runs file
1347  if (!fRepository->CheckFileStatus(this, type, oldfile.Data()))
1348  GetAvailableRunsFile(type)->Remove(run);
1349  }
1350  if (oldfile != newfile) {
1351  //add entry for new run in available runs file
1352  GetAvailableRunsFile(type)->Add(run, newfile.Data());
1353  }
1354 }
1355 
1356 
1357 
1358 
1364 
1366 {
1367  //if fUserGroups has been set with SetUserGroups(), we check that the current user's name
1368  //(gSystem->GetUserInfo()->fUser) appears in at least one of the groups in the list.
1369  //Returns kFALSE if user's name is not found in any of the groups.
1370  //if fUserGroups="" (default), we return kTRUE for all users.
1371 
1372  if (fUserGroups == "")
1373  return kTRUE; /* no groups set, all users have access */
1374 
1375  //split into array of group names
1376  unique_ptr<TObjArray> toks(fUserGroups.Tokenize(' '));
1377  TObjString* group_name;
1378  TIter next_name(toks.get());
1379  while ((group_name = (TObjString*) next_name())) {
1380  //for each group_name, we check if the user's name appears in the group
1381  if (!fRepository || (fRepository && fRepository->GetDataSetManager()->
1382  CheckUser(group_name->String().Data()))
1383  ) {
1384  return kTRUE;
1385  }
1386  }
1387  return kFALSE;
1388 }
1389 
1390 
1391 
1392 
1395 
1397 {
1398  //Set pointer to data repository in which dataset is stored
1399  fRepository = dr;
1400 }
1401 
1402 
1403 
1404 
1407 
1409 {
1410  //Get pointer to data repository in which dataset is stored
1411  return fRepository;
1412 }
1413 
1414 
1415 
1416 
1421 
1423 {
1424  //Check all runs for a given datatype and make sure that only one version
1425  //exists for each run. If not, we print a report on the runfiles which occur
1426  //multiple times, with the associated date and file name.
1427 
1428  KVNumberList doubles =
1429  GetAvailableRunsFile(data_type)->CheckMultiRunfiles();
1430  if (doubles.IsEmpty()) {
1431  cout << "OK. No runs appear more than once." << endl;
1432  }
1433  else {
1434  cout << "Runs which appear more than once: " << doubles.
1435  AsString() << endl << endl;
1436  //print dates and filenames for each run
1437 
1438  doubles.Begin();
1439  KVList filenames, dates;
1440  while (!doubles.End()) {
1441 
1442  Int_t rr = doubles.Next();
1443 
1444  //get infos for current run
1445  GetAvailableRunsFile(data_type)->GetRunInfos(rr, &dates, &filenames);
1446 
1447  cout << "Run " << rr << " : " << dates.
1448  GetEntries() << " files >>>>>>" << endl;
1449  for (int i = 0; i < dates.GetEntries(); i++) {
1450 
1451  cout << "\t" << ((TObjString*) filenames.At(i))->String().
1452  Data() << "\t" << ((TObjString*) dates.At(i))->String().
1453  Data() << endl;
1454 
1455  }
1456  }
1457  }
1458 }
1459 
1460 
1461 
1462 
1471 
1472 void KVDataSet::CleanMultiRunfiles(const Char_t* data_type, Bool_t confirm)
1473 {
1474  // Check all runs for a given datatype and make sure that only one version
1475  // exists for each run. If not, we print a report on the runfiles which occur
1476  // multiple times, with the associated date and file name, and then we
1477  // destroy all but the most recent version of the file in the repository, and
1478  // update the runlist accordingly.
1479  // By default, we ask for confirmation before deleting each file.
1480  // Call with confirm=kFALSE to delete WITHOUT CONFIRMATION (DANGER!! WARNING!!!)
1481 
1482  if (!fRepository) return;
1483 
1484  KVAvailableRunsFile* ARF = GetAvailableRunsFile(data_type);
1485  KVNumberList doubles = ARF->CheckMultiRunfiles();
1486  if (doubles.IsEmpty()) {
1487  cout << "OK. No runs appear more than once." << endl;
1488  }
1489  else {
1490  cout << "Runs which appear more than once: " << doubles.
1491  AsString() << endl << endl;
1492  //print dates and filenames for each run
1493 
1494  KVList filenames, dates;
1495  doubles.Begin();
1496  while (!doubles.End()) {
1497 
1498  Int_t rr = doubles.Next();
1499 
1500  //get infos for current run
1501  ARF->GetRunInfos(rr, &dates, &filenames);
1502 
1503  TDatime most_recent("1998-12-25 00:00:00");
1504  Int_t i_most_recent = 0;
1505  cout << "Run " << rr << " : " << dates.
1506  GetEntries() << " files >>>>>>" << endl;
1507  for (int i = 0; i < dates.GetEntries(); i++) {
1508 
1509  //check if run is most recent
1510  TDatime rundate(((TObjString*) dates.At(i))->String().Data());
1511  if (rundate > most_recent) {
1512 
1513  most_recent = rundate;
1514  i_most_recent = i;
1515 
1516  }
1517  }
1518  //Now, we loop over the list again, this time we destroy all but the most recent
1519  //version of the runfile
1520  for (int i = 0; i < dates.GetEntries(); i++) {
1521 
1522  if (i == i_most_recent) {
1523  cout << "KEEP : ";
1524  }
1525  else {
1526  cout << "DELETE : ";
1527  }
1528  cout << "\t" << ((TObjString*) filenames.At(i))->String().
1529  Data() << "\t" << ((TObjString*) dates.At(i))->String().
1530  Data() << endl;
1531  if (i != i_most_recent) {
1532  //delete file from repository forever and ever
1533  fRepository->DeleteFile(this, data_type,
1534  ((TObjString*) filenames.At(i))->
1535  String().Data(), confirm);
1536  //remove file entry from available runlist
1537  ARF->Remove(rr,
1538  ((TObjString*) filenames.At(i))->String().
1539  Data());
1540  }
1541  }
1542  }
1543  }
1544 }
1545 
1546 
1547 
1548 
1554 
1556  KVDataRepository* other_repos)
1557 {
1558  //Use this method to check whether the file of type "data_type" for run number "run"
1559  //in the data repository "other_repos" is more recent than the file contained in the data
1560  //repository corresponding to this dataset.
1561  //Returns kFALSE if file in other repository is more recent.
1562 
1563  if (!other_repos)
1564  return kTRUE;
1565  //get dataset with same name as this one from dataset manager of other repository
1566  KVDataSet* ds = other_repos->GetDataSetManager()->GetDataSet(GetName());
1567  if (!ds) {
1568  Error("CheckRunfileUpToDate",
1569  "Dataset \"%s\" not found in repository \"%s\"", GetName(),
1570  other_repos->GetName());
1571  return kFALSE;
1572  }
1573  //compare dates of the two runfiles
1574  if (GetRunfileDate(data_type, run) < ds->GetRunfileDate(data_type, run))
1575  return kFALSE;
1576  return kTRUE;
1577 }
1578 
1579 
1580 
1581 
1588 
1590  const Char_t* other_repos)
1591 {
1592  //Use this method to check whether the file of type "data_type" for run number "run"
1593  //in the data repository "other_repos" is more recent than the file contained in the data
1594  //repository corresponding to this dataset.
1595  //Returns kTRUE if no repository with name "other_repos" exists.
1596  //Returns kFALSE if file in other repository is more recent.
1597 
1598  KVDataRepository* _or =
1599  gDataRepositoryManager->GetRepository(other_repos);
1600  if (_or)
1601  return CheckRunfileUpToDate(data_type, run, _or);
1602  Error("CheckRunfileUpToDate",
1603  "No data repository known with this name : %s", other_repos);
1604  return kTRUE;
1605 }
1606 
1607 
1608 
1609 
1613 
1614 void KVDataSet::CheckUpToDate(const Char_t* data_type,
1615  const Char_t* other_repos)
1616 {
1617  //Check whether all files of type "data_type" for run number "run" in the data repository
1618  //are up to date (i.e. at least as recent) as compared to the files in data repository "other_repos".
1619 
1620  if (!fRepository) return;
1621 
1622  KVDataRepository* _or =
1623  gDataRepositoryManager->GetRepository(other_repos);
1624  if (!_or) {
1625  Error("CheckUpToDate",
1626  "No data repository known with this name : %s", other_repos);
1627  return;
1628  }
1629  KVNumberList runlist = GetAvailableRunsFile(data_type)->GetRunList();
1630  runlist.Begin();
1631  Int_t need_update = 0;
1632  while (!runlist.End()) {
1633  //check run
1634  Int_t rr = runlist.Next();
1635  if (!CheckRunfileUpToDate(data_type, rr, _or)) {
1636  cout << " *** run " << rr << " needs update ***" <<
1637  endl;
1638  cout << "\t\tREPOSITORY: " << fRepository->
1639  GetName() << "\tDATE: " << GetRunfileDate(data_type,
1640  rr).
1641  AsString() << endl;
1642  cout << "\t\tREPOSITORY: " << other_repos << "\tDATE: " << _or->
1643  GetDataSetManager()->GetDataSet(GetName())->
1644  GetRunfileDate(data_type,
1645  rr).AsString() << endl;
1646  need_update++;
1647  }
1648  }
1649  if (!need_update) {
1650  cout << " *** All runfiles are up to date for data type " <<
1651  data_type << endl;
1652  }
1653 }
1654 
1655 
1656 
1657 
1661 
1663  const Char_t* other_repos)
1664 {
1665  //Returns list of all runs of type "data_type" which may be updated
1666  //from the repository named "other_repos". See CheckUpToDate().
1667 
1668  KVNumberList updates;
1669  if (!fRepository) return updates;
1670 
1671  KVDataRepository* _or =
1672  gDataRepositoryManager->GetRepository(other_repos);
1673  if (!_or) {
1674  Error("CheckUpToDate",
1675  "No data repository known with this name : %s", other_repos);
1676  return updates;
1677  }
1678  KVNumberList runlist = GetAvailableRunsFile(data_type)->GetRunList();
1679  runlist.Begin();
1680  while (!runlist.End()) {
1681  //check run
1682  Int_t rr = runlist.Next();
1683  if (!CheckRunfileUpToDate(data_type, rr, _or)) {
1684  //run is out of date
1685  updates.Add(rr);
1686  }
1687  }
1688  return updates;
1689 }
1690 
1691 
1692 
1693 
1698 
1700  const KVDBSystem* system) const
1701 {
1702  //Returns list of all runs available for given "data_type"
1703  //If a pointer to a reaction system is given, only runs for the
1704  //given system will be included in the list.
1705  KVNumberList list;
1706  if (!fRepository || !HasDataType(data_type)) {
1707  Error("GetRunList",
1708  "No data of type %s available. Runlist will be empty.",
1709  data_type);
1710  }
1711  else {
1712  list = GetAvailableRunsFile(data_type)->GetRunList(system);
1713  }
1714  return list;
1715 }
1716 
1717 
1718 
1719 
1750 
1752 {
1753  //This method returns a pointer to the available analysis task whose description (title) contains
1754  //all of the whitespace-separated keywords (which may be regular expressions)
1755  //given in the string "keywords". The comparison is case-insensitive.
1756  //
1757  //WARNING: this method can only be used to access analysis tasks that are
1758  //available for this dataset, i.e. for which the corresponding prerequisite data type
1759  //is available in the repository.
1760  //For unavailable data/tasks, use GetAnalysisTaskAny(const Char_t*).
1761  //
1762  //EXAMPLES
1763  //Let us suppose that the current dataset has the following list of tasks:
1764  //~~~
1765  // root [2] gDataSet->Print("tasks")
1766  // 1. Event reconstruction from raw data (raw->recon)
1767  // 2. Analysis of raw data
1768  // 3. Identification of reconstructed events (recon->ident)
1769  // 4. Analysis of reconstructed events (recon)
1770  // 5. Analysis of partially identified & calibrated reconstructed events (ident)
1771  // 6. Analysis of fully calibrated physical data (root)
1772  //~~~
1773  //Then the following will occur:
1774  //~~~
1775  // root [14] gDataSet->GetAnalysisTask("raw->recon")->Print()
1776  // KVDataAnalysisTask : Event reconstruction from raw data (raw->recon)
1777  //
1778  // root [10] gDataSet->GetAnalysisTask("analysis root")->Print()
1779  // KVDataAnalysisTask : Analysis of fully calibrated physical data (root)
1780  //~~~
1781 
1782  //case-insensitive search for matches in list based on 'title' attribute
1783  return (KVDataAnalysisTask*)fTasks.FindObjectAny("title", keywords, kTRUE, kFALSE);
1784 }
1785 
1786 
1787 
1788 
1801 
1802 void KVDataSet::MakeAnalysisClass(const Char_t* task, const Char_t* classname)
1803 {
1804  //Create a skeleton analysis class to be used for analysis of the data belonging to this dataset.
1805  //
1806  // task = keywords contained in title of analysis task (see GetAnalysisTask(const Char_t*))
1807  // (you do not need to include 'analysis', it is added automatically)
1808  // classname = name of new analysis class
1809  //
1810  //Example:
1811  // MakeAnalysisClass("raw", "MyRawDataAnalysis")
1812  // --> make skeleton raw data analysis class in files MyRawDataAnalysis.cpp & MyRawDataAnalysis.h
1813  // MakeAnalysisClass("fully calibrated", "MyDataAnalysis")
1814  // --> make skeleton data analysis class in files MyDataAnalysis.cpp & MyDataAnalysis.h
1815 
1816  KVString _task = task;
1817  if (!_task.Contains("nalysis")) _task += " analysis";
1818  //We want to be able to write analysis classes even when we don't have any data
1819  //to analyse. Therefore we use GetAnalysisTaskAny.
1820  auto dat = GetAnalysisTaskAny(_task.Data());
1821  if (!dat) {
1822  Error("MakeAnalysisClass",
1823  "called for unknown or unavailable analysis task : %s", _task.Data());
1824  return;
1825  }
1826  if (!dat->WithUserClass()) {
1827  Error("MakeAnalysisClass",
1828  "no user analysis class for analysis task : %s", dat->GetTitle());
1829  return;
1830  }
1831 
1832  //all analysis base classes must define a static Make(const Char_t * classname)
1833  //which generates the skeleton class files.
1834 
1835  TClass* cl = nullptr;
1836  //has the user base class for the task been compiled and loaded ?
1837  if (dat->CheckUserBaseClassIsLoaded()) cl = TClass::GetClass(dat->GetUserBaseClass());
1838  else
1839  return;
1840 
1841  //set up call to static Make method
1842  unique_ptr<TMethodCall> methcall(new TMethodCall(cl, "Make", Form("\"%s\"", classname)));
1843 
1844  if (!methcall->IsValid()) {
1845  Error("MakeAnalysisClass", "static Make(const Char_t*) method for class %s is not valid",
1846  cl->GetName());
1847  return;
1848  }
1849 
1850  //generate skeleton class
1851  methcall->Execute();
1852 }
1853 
1854 
1855 
1856 
1860 
1861 Bool_t KVDataSet::OpenDataSetFile(const Char_t* filename, ifstream& file)
1862 {
1863  // Look for (and open for reading, if found) the named file in the directory which
1864  // contains the files for this dataset (given by GetDataSetDir())
1865 
1866  return OpenDataSetFile(GetName(), filename, file);
1867 }
1868 
1869 
1870 
1874 
1875 Bool_t KVDataSet::OpenDataSetFile(const TString& dataset, const Char_t* filename, ifstream& file)
1876 {
1877  // Static method to look for (and open for reading, if found) the named file in the directory which
1878  // contains the files for the dataset
1879 
1880  TString datasetdir = KVBase::GetDataSetEnv(dataset, "DataSet.Directory", dataset);
1881  if (gSystem->IsAbsoluteFileName(datasetdir)) {
1882  // dataset directory is outside of standard KV installation directories
1883  // use absolute path to search for file
1884  TString abspath;
1885  abspath.Form("%s/%s", datasetdir.Data(), filename);
1886  return SearchAndOpenKVFile(abspath, file);
1887  }
1888  // dataset directory is a subdirectory of GetDATADIRFilePath()
1889  return SearchAndOpenKVFile(filename, file, datasetdir);
1890 }
1891 
1892 
1893 
1897 
1899 {
1900  // Find a file in the dataset directory (given by GetDataSetDir())
1901  // Returns full path to file if found, empty string if not
1902 
1903  return GetFullPathToDataSetFile(GetName(), filename);
1904 }
1905 
1906 
1907 
1911 
1913 {
1914  // Static method to find a file in the dataset directory (given by GetDataSetDir())
1915  // Returns full path to file if found, empty string if not
1916 
1917  TString fullpath;
1918  TString datasetdir = KVBase::GetDataSetEnv(dataset, "DataSet.Directory", dataset);
1919  if (!SearchKVFile(filename, fullpath, datasetdir)) {
1920  ::Warning("KVDataSet::GetFullPathToDataSetFile", "File %s not found in dataset subdirectory %s", filename, datasetdir.Data());
1921  fullpath = "";
1922  }
1923  return fullpath;
1924 }
1925 
1926 
1927 
1931 
1932 Bool_t KVDataSet::FindDataSetFile(const TString& dataset, const Char_t* filename)
1933 {
1934  // Static method to find a file in the dataset directory (given by GetDataSetDir())
1935  // Returns kTRUE if found, kFALSE if not
1936 
1937  TString fullpath;
1938  TString datasetdir = KVBase::GetDataSetEnv(dataset, "DataSet.Directory", dataset);
1939  return SearchKVFile(filename, fullpath, datasetdir);
1940 }
1941 
1942 
1943 
1947 
1949 {
1950  // Find a file in the dataset directory (given by GetDataSetDir())
1951  // Returns kTRUE if found, kFALSE if not
1952 
1953  return FindDataSetFile(GetName(), filename);
1954 }
1955 
1956 
1957 
1958 
1967 
1969 {
1970  //This method returns the analysis task whose description (title) contains
1971  //all of the whitespace-separated keywords (which may be regular expressions)
1972  //given in the string "keywords". The comparison is case-insensitive.
1973  //The analysis task does not need to be "available", i.e. the associated prerequisite
1974  //data type does not have to be present in the repository (see GetAnalysisTask).
1975  //
1976  // If no task is found, returns nullptr
1977 
1978  KVDataAnalysisTask* tsk = (KVDataAnalysisTask*)fAllTasks.FindObjectAny("title", keywords, kTRUE, kFALSE);
1979  if (!tsk) {
1980  Error("GetAnalysisTaskAny", "No task found with the following keywords in its title : %s", keywords);
1981  }
1982  return tsk;
1983 }
1984 
1985 
1986 
1987 
1993 
1995 {
1996  // Returns kTRUE if database needs to be regenerated from source files,
1997  // i.e. if source files are more recent than DataBase.root
1998  // In case no directory exists for dataset (dataset added 'on the fly')
1999  // we create the directory and fill it with dummy files (Makefile, Runlist.csv, Systems.dat)
2000 
2001  TString pwd = gSystem->pwd();
2002 
2003  TString path = "";
2004  if (!SearchKVFile(GetDataSetDir(), path)) {
2005  // dataset directory doesn't exist - create it
2006  Info("DataBaseNeedsUpdate", "%s: Creating new dataset directory %s",
2007  GetName(), GetDataSetDir());
2008  if (gSystem->mkdir(GetDataSetDir())) {
2009  // problem creating directory
2010  Error("DataBaseNeedsUpdate",
2011  "%s: Dataset directory %s does not exist and cannot be created ?",
2012  GetName(), GetDataSetDir());
2013  return kFALSE;
2014  }
2015  // create dummy files
2016  SearchKVFile(GetDataSetDir(), path); // get full path
2017  path += "/";
2018  TString filename = path + "Makefile";
2019  ofstream of1(filename.Data());
2020  of1 << "$(KV_WORK_DIR)/db/" << GetName() << "/DataBase.root : Runlist.csv Systems.dat" << endl;
2021  of1 << "\t@echo Database needs update" << endl;
2022  of1.close();
2023  filename = path + "Runlist.csv";
2024  ofstream of2(filename.Data());
2025  of2 << "# Automatically generated dummy Runlist.csv file" << endl;
2026  of2.close();
2027  filename = path + "Systems.dat";
2028  ofstream of3(filename.Data());
2029  of3 << "# Automatically generated dummy Systems.dat file" << endl;
2030  of3.close();
2031  }
2032  gSystem->cd(GetDataSetDir());
2033  TString cmd = "make -q";
2034  Int_t ret = gSystem->Exec(cmd.Data());
2035  gSystem->cd(pwd.Data());
2036  return (ret != 0);
2037 }
2038 
2039 
2040 
2057 
2059 {
2060  // Returns name of output repository for given task.
2061  // By default it is the name of the repository associated with this dataset,
2062  // but can be changed by the following environment variables:
2063  //
2064  // [repository].DefaultOutputRepository: [other repository]
2065  // - this means that all tasks carried out on data in [repository]
2066  // will have their output files placed in [other repository]
2067  //
2068  // [taskname].DataAnalysisTask.OutputRepository: [other repository]
2069  // - this means that for [taskname], any output files will
2070  // be placed in [other repository]
2071  //
2072  // [dataset].[taskname].DataAnalysisTask.OutputRepository: [other repository]
2073  // - this means that for given [dataset] & [taskname],
2074  // any output files will be placed in [other repository]
2075 
2076  if (gEnv->Defined(Form("%s.DataRepository.DefaultOutputRepository", GetRepository()->GetName())))
2077  return TString(gEnv->GetValue(Form("%s.DataRepository.DefaultOutputRepository", GetRepository()->GetName()), ""));
2078  TString orep = GetDataSetEnv(Form("%s.DataAnalysisTask.OutputRepository", taskname), GetRepository()->GetName());
2079  return orep;
2080 }
2081 
2082 
2083 
2084 
2088 
2089 void KVDataSet::CopyRunfilesFromRepository(const Char_t* type, KVNumberList runs, const Char_t* destdir)
2090 {
2091  // Copies the runfiles of given "type" into the local directory "destdir".
2092  // Run numbers given as a list of type "1-10".
2093 
2094  KVDataRepository* repo = GetRepository();
2095  runs.Begin();
2096  while (!runs.End()) {
2097  int run = runs.Next();
2098  TString filename = GetRunfileName(type, run);
2099  TString destpath;
2100  AssignAndDelete(destpath, gSystem->ConcatFileName(destdir, filename));
2101  repo->CopyFileFromRepository(this, type, filename, destpath);
2102  }
2103 }
2104 
2105 
2106 
2107 
2112 
2113 void KVDataSet::CopyRunfilesToRepository(const Char_t* type, KVNumberList runs, const Char_t* destrepo)
2114 {
2115  // Copies the runfiles of given "type" from the data repository associated
2116  // with this dataset into the local repository "destrepo".
2117  // Run numbers given as a list of type "1-10".
2118 
2119  KVDataRepository* repo = GetRepository();
2120  KVDataRepository* dest_repo = gDataRepositoryManager->GetRepository(destrepo);
2121 
2122  if (!dest_repo) {
2123  Error("CopyRunfilesToRepository", "Unknown destination repository : %s", destrepo);
2124  gDataRepositoryManager->Print();
2125  return;
2126  }
2127 
2128  KVDataSet* dest_ds = dest_repo->GetDataSetManager()->GetDataSet(GetName());
2129  dest_repo->CreateAllNeededSubdirectories(dest_ds, type);
2130  runs.Begin();
2131  while (!runs.End()) {
2132  int run = runs.Next();
2133  TString filename = GetRunfileName(type, run);
2134  TString destpath = dest_repo->GetFullPathToTransferFile(dest_ds, type, filename);
2135  repo->CopyFileFromRepository(this, type, filename, destpath);
2136  }
2137 }
2138 
2139 
int Int_t
#define f(i)
bool Bool_t
char Char_t
constexpr Bool_t kFALSE
double Double_t
constexpr Bool_t kTRUE
const char Option_t
#define gDirectory
R__EXTERN TEnv * gEnv
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 type
char name[80]
char * Form(const char *fmt,...)
void AssignAndDelete(TString &target, char *tobedeleted)
R__EXTERN TSystem * gSystem
Handles lists of available runs for different datasets and types of data.
virtual void Add(Int_t run, const Char_t *filename)
KVNumberList CheckMultiRunfiles()
Returns a list with all runs which occur more than once in the available runs file.
virtual void Remove(Int_t run, const Char_t *filename="")
virtual void GetRunInfos(Int_t run, KVList *dates, KVList *names)
static const Char_t * GetDataSetEnv(const Char_t *dataset, const Char_t *type, const Char_t *defval)
Definition: KVBase.cpp:1619
const TDatime & GetDatime() const
Definition: KVDBRun.h:114
Database class used to store information on different colliding systems studied during an experiment....
Definition: KVDBSystem.h:52
Bool_t IsCollision() const
retourne kTRUE, si le systeme est une collision ie projectile+cible
Definition: KVDBSystem.cpp:105
Define and manage data analysis tasks.
virtual void SetDataAnalyser(const Char_t *d)
virtual void SetPrereq(const Char_t *p)
virtual void SetStatusUpdateInterval(Long64_t n)
void SetExtraAClicIncludes(const KVString &list)
virtual const Char_t * GetPrereq() const
virtual void SetUserBaseClass(const Char_t *d)
KVDataRepository * GetRepository(const Char_t *name) const
void Print(Option_t *opt="") const
Base class for managing repositories of experimental data.
virtual KVDataSetManager * GetDataSetManager() const
Return pointer to data set manager for this repository.
virtual void CopyFileFromRepository(const KVDataSet *dataset, const Char_t *datatype, const Char_t *filename, const Char_t *destination)
void CreateAllNeededSubdirectories(const KVDataSet *DataSet, const Char_t *DataType)
virtual const Char_t * GetFullPathToTransferFile(const KVDataSet *dataset, const Char_t *datatype, const Char_t *runfile)
KVDataSet * GetDataSet(Int_t) const
Return pointer to DataSet using index in list of all datasets, index>=0.
Manage an experimental dataset corresponding to a given experiment or campaign.
Definition: KVDataSet.h:35
TString GetOutputRepository(const Char_t *taskname) const
Definition: KVDataSet.cpp:2058
virtual void OpenDBFile(const Char_t *full_path_to_dbfile) const
Open the database from a file on disk.
Definition: KVDataSet.cpp:105
KVNumberList GetRunList_VersionSelection(const Char_t *type, const Char_t *version, KVDBSystem *sys=0)
Definition: KVDataSet.cpp:1280
void CheckMultiRunfiles(const Char_t *data_type)
Definition: KVDataSet.cpp:1422
KVNumberList GetRunList_StageSelection(const Char_t *other_type, const Char_t *base_type, KVDBSystem *sys=0, Bool_t OnlyCol=kFALSE)
Definition: KVDataSet.cpp:1223
void CheckUpToDate(const Char_t *data_type, const Char_t *other_repos)
Definition: KVDataSet.cpp:1614
const Char_t * GetDBName() const
Definition: KVDataSet.cpp:89
KVDataRepository * GetRepository() const
Get pointer to data repository in which dataset is stored.
Definition: KVDataSet.cpp:1408
void CopyRunfilesToRepository(const Char_t *type, KVNumberList runs, const Char_t *destrepo)
Definition: KVDataSet.cpp:2113
const Char_t * GetDBFileName() const
Definition: KVDataSet.cpp:72
const Char_t * GetDataSetDir() const
Definition: KVDataSet.cpp:729
void DeleteRunfiles(const Char_t *type, KVNumberList lrun="", Bool_t confirm=kTRUE)
Definition: KVDataSet.cpp:1136
KVNumberList GetUpdatableRuns(const Char_t *data_type, const Char_t *other_repos)
Definition: KVDataSet.cpp:1662
virtual void ls(Option_t *opt="") const
Print dataset information.
Definition: KVDataSet.cpp:403
void DeleteRunfile(const Char_t *type, Int_t run, Bool_t confirm=kTRUE)
Definition: KVDataSet.cpp:1092
KVAvailableRunsFile * GetAvailableRunsFile(const Char_t *type) const
Definition: KVDataSet.cpp:50
virtual void AddAvailableDataType(const Char_t *)
Definition: KVDataSet.cpp:532
virtual TList * GetListOfAvailableSystems(const Char_t *datatype, KVDBSystem *systol=0)
Definition: KVDataSet.cpp:623
Bool_t CheckRunfileUpToDate(const Char_t *data_type, Int_t run, KVDataRepository *other_repos)
Definition: KVDataSet.cpp:1555
void SetName(const char *name)
Definition: KVDataSet.cpp:697
KVDataAnalysisTask * GetAnalysisTask(Int_t) const
Definition: KVDataSet.cpp:598
virtual const Char_t * GetBaseFileName(const Char_t *type, Int_t run) const
Definition: KVDataSet.cpp:1013
virtual void SaveDataBase() const
Definition: KVDataSet.cpp:194
virtual KVDataAnalysisTask * GetAnalysisTaskAny(const Char_t *keywords) const
Definition: KVDataSet.cpp:1968
virtual void SetAnalysisTasks(const KVSeqCollection *)
Definition: KVDataSet.cpp:549
KVNumberList GetRunList_DateSelection(const Char_t *type, TDatime *min=0, TDatime *max=0)
Definition: KVDataSet.cpp:1165
virtual void CheckAvailable()
Definition: KVDataSet.cpp:475
const Char_t * GetRunfileName(const Char_t *type, Int_t run) const
Definition: KVDataSet.cpp:923
TDatime GetRunfileDate(const Char_t *type, Int_t run)
Definition: KVDataSet.cpp:951
const Char_t * GetDataSetEnv(const Char_t *type, const Char_t *defval="") const
Definition: KVDataSet.cpp:767
virtual Int_t GetNtasks() const
Definition: KVDataSet.cpp:583
KVNumberList GetRunList(const Char_t *data_type, const KVDBSystem *sys=0) const
Definition: KVDataSet.cpp:1699
TString GetFullPathToDataSetFile(const Char_t *filename)
Definition: KVDataSet.cpp:1898
TString GetFullPathToRunfile(const Char_t *type, Int_t run) const
Definition: KVDataSet.cpp:897
void CopyRunfilesFromRepository(const Char_t *type, KVNumberList runs, const Char_t *destdir)
Definition: KVDataSet.cpp:2089
void UpdateAvailableRuns(const Char_t *type)
Definition: KVDataSet.cpp:1045
virtual void MakeAnalysisClass(const Char_t *task, const Char_t *classname)
Definition: KVDataSet.cpp:1802
TObject * open_runfile(const Char_t *type, Int_t run)
Definition: KVDataSet.cpp:842
void CommitRunfile(const Char_t *type, Int_t run, TFile *file)
Definition: KVDataSet.cpp:1321
KVExpDB * GetDataBase(Option_t *opt="") const
Definition: KVDataSet.cpp:289
virtual Bool_t DataBaseNeedsUpdate() const
Definition: KVDataSet.cpp:1994
Bool_t OpenDataSetFile(const Char_t *filename, std::ifstream &file)
void SetDataSetSpecificTaskParameters(KVDataAnalysisTask *) const
Definition: KVDataSet.cpp:159
void cd() const
Definition: KVDataSet.cpp:745
virtual void WriteDBFile(const Char_t *full_path_to_dbfile) const
Definition: KVDataSet.cpp:255
const Char_t * GetFullPathToDB() const
Returns full path to file where database is written on disk.
Definition: KVDataSet.cpp:131
TFile * NewRunfile(const Char_t *type, Int_t run)
Definition: KVDataSet.cpp:1067
virtual Bool_t CheckUserCanAccess()
Definition: KVDataSet.cpp:1365
void SetRepository(KVDataRepository *)
Set pointer to data repository in which dataset is stored.
Definition: KVDataSet.cpp:1396
KVDataSet()
Default constructor.
Definition: KVDataSet.cpp:35
void CleanMultiRunfiles(const Char_t *data_type, Bool_t confirm=kTRUE)
Definition: KVDataSet.cpp:1472
virtual void OpenDataBase(Option_t *opt="") const
Definition: KVDataSet.cpp:335
virtual void Print(Option_t *opt="") const
Definition: KVDataSet.cpp:424
static Bool_t FindDataSetFile(const TString &dataset, const Char_t *filename)
Definition: KVDataSet.cpp:1932
Bool_t CheckRunfileAvailable(const Char_t *type, Int_t run)
Definition: KVDataSet.cpp:985
Extension of TDatime to handle various useful date formats.
Definition: KVDatime.h:33
Base class to describe database of an experiment ,,.
Definition: KVExpDB.h:20
virtual void cd()
Definition: KVExpDB.cpp:577
static KVExpDB * MakeDataBase(const Char_t *name, const Char_t *datasetdir)
Definition: KVExpDB.cpp:599
Extended TList class which owns its objects by default.
Definition: KVList.h:28
Strings used to represent a set of ranges of values.
Definition: KVNumberList.h:85
const Char_t * AsString(Int_t maxchars=0) const
Bool_t End(void) const
Definition: KVNumberList.h:199
void Remove(Int_t)
Remove value 'n' from the list.
Int_t GetNValues() const
void Begin(void) const
Int_t GetEntries() const
Definition: KVNumberList.h:171
void Add(Int_t)
Add value 'n' to the list.
Bool_t IsEmpty() const
Definition: KVNumberList.h:175
Int_t Next(void) const
Description of an individual run file in an experimental dataset.
Definition: KVRunFile.h:19
Int_t GetRunNumber() const
Definition: KVRunFile.h:35
const Char_t * GetVersion() const
Definition: KVRunFile.h:55
const KVDBRun * GetRun() const
Definition: KVRunFile.h:31
KaliVeda extensions to ROOT collection classes.
virtual TObject * At(Int_t idx) const
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
static TClass * GetClass(Bool_t load=kTRUE, Bool_t silent=kFALSE)
virtual Int_t GetEntries() const
const char * AsSQLString() const
void Set()
virtual Bool_t cd()
virtual const char * GetValue(const char *name, const char *dflt) const
virtual void SetValue(const char *name, const char *value, EEnvLevel level=kEnvChange, const char *type=nullptr)
Bool_t Defined(const char *name) const
TObject * FindObject(const char *name) const override
TObject * At(Int_t idx) const override
virtual void SetTitle(const char *title="")
const char * GetName() const override
const char * GetTitle() const override
virtual void SetName(const char *name)
TString & String()
const char * Data() const
void ToUpper()
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)
Bool_t cd(const char *path)
const char * pwd()
virtual int Chmod(const char *file, UInt_t mode)
virtual const char * DirName(const char *pathname)
virtual char * ConcatFileName(const char *dir, const char *name)
virtual int mkdir(const char *name, Bool_t recursive=kFALSE)
virtual Int_t Exec(const char *shellcmd)
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
virtual const char * BaseName(const char *pathname)
virtual Bool_t IsAbsoluteFileName(const char *dir)
void Error(const char *location, const char *fmt,...)
void Info(const char *location, const char *fmt,...)
void Warning(const char *location, const char *fmt,...)
double min(double x, double y)
double max(double x, double y)
const char * String
TArc a
ClassImp(TPyArg)