KaliVeda  1.13/01
Heavy-Ion Analysis Toolkit
KVDataSet.cpp
Go to the documentation of this file.
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"
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 
30 
31 
34 
36 {
37  //Default constructor
38  fRepository = nullptr;
39  fDataBase = nullptr;
40 }
41 
42 
43 
47 
49 {
50  //Returns available runs file object for given data 'type' (="raw", "recon", "ident", "root")
51  //Object will be created and added to internal list if it does not exist
52 
53  if (!fRepository) return nullptr;
54  KVAvailableRunsFile* avrf =
55  (KVAvailableRunsFile*) fAvailableRuns.FindObjectByName(type);
56  if (!avrf) {
57  avrf = fRepository->NewAvailableRunsFile(type, this);
58  fAvailableRuns.Add(avrf);
59  }
60  return avrf;
61 }
62 
63 
64 
69 
71 {
72  //Returns name of file containing database for dataset.
73  //If this is not set explicitly with SetDBFileName(), the default value defined by DataSet.DatabaseFile
74  //in $KVROOT/KVFiles/.kvrootrc will be returned.
75 
76  if (fDBFileName != "")
77  return fDBFileName.Data();
78  return gEnv->GetValue("DataSet.DatabaseFile", "");
79 }
80 
81 
82 
86 
88 {
89  //Returns name of database object in database file.
90  //If this is not set explicitly with SetDBName(), we use the name of the dataset by default
91 
92  if (fDBName != "")
93  return fDBName.Data();
94  return GetName();
95 }
96 
97 
98 
99 
102 
103 void KVDataSet::OpenDBFile(const Char_t* full_path_to_dbfile) const
104 {
105  //Open the database from a file on disk.
106 
107  TDirectory* work_dir = gDirectory; //keep pointer to current directory
108  fDBase.reset(new TFile(full_path_to_dbfile, "READ"));
109 
110  if (fDBase->IsOpen()) {
111  fDataBase = dynamic_cast<KVExpDB*>(fDBase->Get(GetDBName()));
112  if (!fDataBase) {
113  Error("OpenDBFile", "%s not found in file %s", GetDBName(),
114  GetDBFileName());
115  }
116  else {
117  fDataBase->ReadObjects(fDBase.get()); // read any associated objects
118  }
119  work_dir->cd(); //back to initial working directory
120  }
121 }
122 
123 
124 
125 
128 
130 {
131  // Returns full path to file where database is written on disk
132 
133  TString dbfile = GetDBFileName();
134  static TString dbfile_fullpath;
135  TString tmp;
136 
137  // If this dataset is just an alias for another dataset i.e. if DataSet.Directory
138  // is set with just the name of another dataset (not a full path to dataset files)
139  // then the database file should be written/found under the name of the alias.
140  TString dataset_alias = GetDataSetEnv("DataSet.Directory", GetName());
141  TString db_alias = GetName();
142  if (!gSystem->IsAbsoluteFileName(dataset_alias)) db_alias = dataset_alias;
143 
144  AssignAndDelete(tmp, gSystem->ConcatFileName(GetDATABASEFilePath(), db_alias.Data()));
145  AssignAndDelete(dbfile_fullpath, gSystem->ConcatFileName(tmp.Data(), dbfile.Data()));
146  return dbfile_fullpath.Data();
147 }
148 
149 
150 
156 
158 {
159  //PROTECTED METHOD
160  //Called by KVDataSet::SetAnalysisTasks
161  //Check environment variables (i.e. .kvrootrc) to see if the task parameters
162  //have been "tweaked" for the dataset.
163 
164  KVString envar = GetDataSetEnv(Form("%s.DataAnalysisTask.Analyser", t->GetName()));
165  if (envar != "") t->SetDataAnalyser(envar);
166  envar = GetDataSetEnv(Form("%s.DataAnalysisTask.UserClass.Base", t->GetName()));
167  if (envar != "") t->SetUserBaseClass(envar);
168  envar = GetDataSetEnv(Form("%s.DataAnalysisTask.Prereq", t->GetName()));
169  if (envar != "") t->SetPrereq(envar);
170  envar = GetDataSetEnv(Form("%s.DataAnalysisTask.UserClass.ExtraACliCIncludes", t->GetName()));
171  if (envar != "") t->SetExtraAClicIncludes(envar);
172  Int_t nev = (Int_t)GetDataSetEnv(Form("%s.DataAnalysisTask.StatusUpdateInterval", t->GetName()), 0.0);
173  if (nev > 0) t->SetStatusUpdateInterval(nev);
174 }
175 
176 
177 
178 
189 
191 {
192  // Write the database to disk (ROOT file).
193  // It will be written in the directory
194  // $KVROOT/db/[dataset name]
195  // If the directory does not exist, it will be created. Permissions are set to 775 (rwxrwxr-x).
196  //
197  // # Default name of database file containing informations on runs, systems, calibration parameters etc.
198  // DataSet.DatabaseFile: DataBase.root
199  // # Default name of database object in file
200  // DataSet.DatabaseName: DataBase
201 
202  TString dbfile_fullpath = GetFullPathToDB();
203  TString tmp = gSystem->DirName(dbfile_fullpath.Data()); //full path to directory $KVROOT/db/[dataset name]
204 
205  if (gSystem->AccessPathName(tmp.Data())) { // directory $KVROOT/db/[dataset name] does not exist
206 
207  if (gSystem->mkdir(tmp.Data()) == -1) { // problem creating $KVROOT/db/[dataset name]
208 
209  TString tmp2 = gSystem->DirName(tmp.Data());// full path to directory $KVROOT/db
210 
211  if (gSystem->AccessPathName(tmp2.Data())) { // directory $KVROOT/db does not exist
212 
213  if (gSystem->mkdir(tmp2.Data()) == -1) { // problem creating $KVROOT/db
214  Error("SaveDataBase", "Cannot create directory %s required to save database",
215  tmp2.Data());
216  return;
217  }
218  gSystem->Chmod(tmp2.Data(), 0775);
219  }
220  else {
221  Error("SaveDataBase", "Cannot create directory %s required to save database, even though %s exists: check disk space ?",
222  tmp.Data(), tmp2.Data());
223  return;
224  }
225  //try again
226  if (gSystem->mkdir(tmp.Data()) == -1) {
227  Error("SaveDataBase", "Cannot create directory %s required to save database",
228  tmp.Data());
229  return;
230  }
231  else {
232  gSystem->Chmod(tmp.Data(), 0775);
233  }
234  }
235  else {
236  gSystem->Chmod(tmp.Data(), 0775);
237  }
238  }
239 
240  WriteDBFile(dbfile_fullpath.Data());
241 }
242 
243 
244 
245 
250 
251 void KVDataSet::WriteDBFile(const Char_t* full_path_to_dbfile) const
252 {
253  //PRIVATE METHOD
254  //Write the database to disk.
255  //Set permissions to rw for user & group
256 
257  TDirectory* work_dir = gDirectory; //keep pointer to current directory
258  if (!fDataBase) {
259  Error("WriteDBFile", "Database has not been built");
260  return;
261  }
262  fDBase.reset(new TFile(full_path_to_dbfile, "recreate"));
263  fDBase->cd(); //set as current directory (maybe not necessary)
264  fDataBase->Write(GetDBName()); //write database to file with given name
265  fDataBase->WriteObjects(fDBase.get()); //write any associated objects
266  fDBase->Write(); // write file header etc.
267  fDBase->Close(); // close file
268  gSystem->Chmod(full_path_to_dbfile, 0664); // set permissions to rw-rw-r--
269  work_dir->cd(); //back to initial working directory
270 }
271 
272 
273 
284 
286 {
287  //Returns pointer to database associated with this dataset.
288  //Opens, updates or creates database file if necessary
289  //(the database is automatically rebuilt if the source files are
290  //more recent than the last database file).
291  //
292  //If opt="update":
293  // close and delete database if already open
294  // regenerate database from source files
295  //Use this option to force the regeneration of the database.
296 
297  TString _opt(opt);
298  _opt.ToUpper();
299  if (_opt == "UPDATE") {
300  OpenDataBase(_opt.Data());
301  }
302  else {
303  OpenDataBase();
304  }
305  return fDataBase;
306 }
307 
308 
309 
330 
332 {
333  //Open the database for this dataset.
334  //If the database does not exist or is older than the source files
335  //the database is automatically rebuilt
336  //(see DataBaseNeedUpdate()).
337  //Use opt="UPDATE" to force rebuilding of the database.
338  //
339  //First, we look in to see if the database file exists
340  //(if no database file name given, use default name for database file defined in
341  //.rootrc config files).
342  //If so, we open the database contained in the file, after first loading the required plugin
343  //library if needed.
344  //
345  //The name of the dataset must correspond to the name of one of the Plugin.KVDataBase
346  //plugins defined in the .rootrc configuration files
347  //
348  //WARNING: if the database needs to be (re)built, we set gDataSet to
349  //point to this dataset in case it was not already done,
350  //as in order to (re)build the database it may be necessary for
351  //gDataSet to point to the current dataset.
352 
353  Bool_t is_glob_db = kFALSE;
354  //if option="update" or database out of date or does not exist, (re)build the database
355  if ((!strcmp(opt, "UPDATE")) || DataBaseNeedsUpdate()) {
356  //check if it is the currently active database (gDataBase),
357  //in which case we must 'cd()' to it after rebuilding
358  Info("OpenDataBase", "Updating database file");
359  fDataBaseUpdateInProgress = true;
360  is_glob_db = (fDataBase == gExpDB);
361  if (fDataBase) {
362  delete fDataBase;
363  fDataBase = 0;
364  }
365  // make sure gDataSet is set & points to us
366  gDataSet = const_cast<KVDataSet*>(this);
367  fDataBase = KVExpDB::MakeDataBase(GetDBName(), GetDataSetDir());
368  if (!fDataBase) {
369  // no database defined for dataset
370  Info("OpenDataBase", "No database defined for dataset");
371  return;
372  }
373  SaveDataBase();
374  if (fDataBase && is_glob_db) fDataBase->cd();
375  fDataBaseUpdateInProgress = false;
376  }
377  else if (!fDataBase) {
378  // if database is not in memory at this point, we need to
379  // open the database file and read in the database
380 
381  //load plugin for database
382  if (!LoadPlugin("KVExpDB", GetDBName())) {
383  Error("GetDataBase", "Cannot load required plugin library");
384  return;
385  }
386  //look for database file in dataset subdirectory
387  TString dbfile_fullpath = GetFullPathToDB();
388  //open database file
389  OpenDBFile(dbfile_fullpath.Data());
390  }
391 }
392 
393 
394 
395 
398 
400 {
401  //Print dataset information
402  cout << "Dataset name=" << GetName() << " (" << GetTitle() << ")";
403  if (IsAvailable()) {
404  cout << " [ AVAILABLE: ";
405  cout << fDatatypes.Data();
406  cout << "]";
407  }
408  else
409  cout << " [UNAVAILABLE]";
410  cout << endl;
411 }
412 
413 
414 
419 
420 void KVDataSet::Print(Option_t* opt) const
421 {
422  //Print dataset information
423  //If option string contains "tasks", print numbered list of tasks that can be performed
424  //If option string contains "data", print list of available data types
425 
426  TString Sopt(opt);
427  Sopt.ToUpper();
428  if (Sopt.Contains("TASK")) {
429  if (!GetNtasks()) {
430  cout << " *** No available analysis tasks ***"
431  << endl;
432  return;
433  }
434  else {
435  for (int i = 1; i <= GetNtasks(); i++) {
436  KVDataAnalysisTask* dat = GetAnalysisTask(i);
437  cout << "\t" << i << ". " << dat->GetTitle() << endl;
438  }
439  }
440  cout << endl;
441  }
442  else if (Sopt.Contains("DATA")) {
443  cout << "Available data types: " << fDatatypes.Data() << endl;
444  }
445  else {
446  ls(opt);
447  }
448 }
449 
450 
451 
470 
472 {
473  //Check if this data set is physically present and available for analysis.
474  //In other words we check if the value of GetDatapathSubdir() is a subdirectory
475  //of the given data repository
476  //If so, we proceed to check for the existence of any of the datatypes defined in
477  //
478  //KVDataSet.DataTypes:
479  //
480  //by checking for the associated sudirectories defined in the corresponding variables:
481  //
482  //KVDataSet.DataType.Subdir.[type]:
483  //
484  //If none of them exists, the dataset will be reset to 'unavailable'
485  //Otherwise the corresponding flags are set.
486  //
487  //Note that if SetUserGroups has been called with a list of groups allowed to read this data,
488  //the current user's name (gSystem->GetUserInfo()->fUser) will be used to check if the
489  //dataset is available. The user name must appear in the group defined by SetUserGroups.
490 
491  if (!fRepository) // for a stand-alone KVDataSetManager not linked to a KVDataRepository,
492  SetAvailable(); // all known datasets are 'available'
493  else
494  SetAvailable(fRepository->CheckSubdirExists(GetDataPathSubdir()));
495  if (!IsAvailable())
496  return;
497  //check subdirectories
498  KVString data_types = GetDataSetEnv("KVDataSet.DataTypes", "");
499  if (data_types == "") {
500  Warning("CheckAvailable", "No datatypes defined for this dataset: %s\nCheck value of KVDataSet.DataTypes or %s.KVDataSet.DataTypes",
501  GetName(), GetName());
502  SetAvailable(kFALSE);
503  }
504  fDatatypes = "";
505  // loop over data types
506  data_types.Begin(" ");
507  while (!data_types.End()) {
508  KVString type = data_types.Next(kTRUE);
509  if (!fRepository ||
510  (fRepository && fRepository->CheckSubdirExists(GetDataPathSubdir(), GetDataTypeSubdir(type.Data())))
511  ) {
512  AddAvailableDataType(type.Data());
513  }
514  }
515  //check at least one datatype exists
516  SetAvailable(fDatatypes != "");
517  //check user name against allowed groups
518  if (!CheckUserCanAccess()) {
519  SetAvailable(kFALSE);
520  return;
521  }
522 }
523 
524 
525 
527 
529 {
530  if (fDatatypes != "") fDatatypes += " ";
531  KVString _type = type;
532  _type.Remove(TString::kBoth, ' '); //strip whitespace
533  fDatatypes += _type;
534 }
535 
536 
537 
542 
544 {
545  // Add to fTasks list any data analysis task in list 'task_list'
546  // whose pre-requisite datatype is present for this dataset.
547  // Any dataset-specific "tweaking" of the task (including the prerequisite datatype) is done here.
548 
549  TString availables = gEnv->GetValue(Form("%s.DataAnalysisTask", GetName()), "");
550  fTasks.Delete();
551  TIter nxt(task_list);
552  KVDataAnalysisTask* dat;
553  while ((dat = (KVDataAnalysisTask*) nxt())) {
554  //make new copy of default analysis task
555  if (availables == "" || availables.Contains(dat->GetName())) {
556  KVDataAnalysisTask* new_task = new KVDataAnalysisTask(*dat);
557  //check if any dataset-specific parameters need to be changed
558  SetDataSetSpecificTaskParameters(new_task);
559  if (HasDataType(new_task->GetPrereq())) {
560  fTasks.Add(new_task);
561  }
562  else
563  delete new_task;
564  }
565  }
566 }
567 
568 
569 
573 
575 {
576  //Returns the number of tasks associated to dataset which are compatible
577  //with the available data
578 
579  return fTasks.GetSize();
580 }
581 
582 
583 
588 
590 {
591  //Return kth analysis task in list of available tasks.
592  //k=[1, GetNtasks()] and corresponds to the number shown next to the title of the task when
593  //KVDataSet::Print("tasks") is called
594  return (KVDataAnalysisTask*) fTasks.At(k - 1);
595 }
596 
597 
598 
613 
615 {
616  //Create and fill a list of available systems for this dataset and the given datatype
617  //
618  //This uses the database associated to the dataset.
619  //USER MUST DELETE THE LIST AFTER USE.
620  //
621  //For each system in the list we set the number of available runs : this number
622  //can be retrieved with KVDBSystem::GetNumberRuns()
623  //
624  //If systol!=0 then in fact the list contains a list of runs for the given system which are available.
625  //
626  //If no systems are defined for the dataset then we return a list of available runs
627  //for the given datatype
628 
629  //open the available runs file for the data type
630  if (!GetAvailableRunsFile(datatype)) {
631  Error("GetListOfAvailableSystems(const Char_t*)",
632  "No available runs file for type %s", datatype);
633  return 0;
634  }
635  return GetAvailableRunsFile(datatype)->GetListOfAvailableSystems(systol);
636 }
637 
638 
639 
653 
655 {
656  //Create and fill a list of available systems for this dataset and the prerequisite
657  //datatype for the given data analysis task.
658  //This uses the database associated to the dataset.
659  //USER MUST DELETE THE LIST AFTER USE.
660  //
661  //For each system in the list we set the number of available runs : this number
662  //can be retrieved with KVDBSystem::GetNumberRuns()
663  //
664  //If systol!=0 then in fact the list contains a list of runs for the given system which are available.
665  //
666  //If no systems are defined for the dataset then we return a list of available runs
667  //for the given datatype
668 
669  return GetListOfAvailableSystems(datan->GetPrereq(), systol);
670 }
671 
672 
673 
687 
688 void KVDataSet::SetName(const char* name)
689 {
690  // Set name of dataset.
691  // Also sets path to directory containing database informations
692  // for this dataset, i.e. list of runs, systems, calibration files etc.
693  // By default, just the name of the dataset is used, i.e.
694  // [DATADIR]/name
695  // (where DATADIR = path given by KVBase::GetDATADIRFilePath())
696  // However, if the variable
697  // [name].DataSet.Directory: [path]
698  // has been set, the value of [path] will be used.
699  // If [path] is an absolute path name, it will be used as such.
700  // If [path] is an incomplete or relative path, it will be prepended
701  // with [DATADIR]/
702  TNamed::SetName(name);
703  TString path = GetDataSetEnv("DataSet.Directory", name);
704  if (gSystem->IsAbsoluteFileName(path)) fCalibDir = path;
705  else {
706  // in this case (not an absolute path but just the name of another dataset)
707  // this dataset is an alias for another dataset.
708  fCalibDir = GetDATADIRFilePath(path);
709  // the name of the database object is the name of the "true" dataset
710  SetDBName(path);
711  }
712 }
713 
714 
715 
719 
721 {
722  //Returns full path to directory containing database and calibration/identification parameters etc.
723  //for this dataset.
724  return fCalibDir.Data();
725 }
726 
727 
728 
735 
736 void KVDataSet::cd() const
737 {
738  //Data analysis can only be performed if the data set in question
739  //is "activated" or "selected" using this method.
740  //At the same time, the data repository, dataset manager and database associated with
741  //this dataset also become the "active" ones (pointed to by the respective global
742  //pointers, gDataRepository, gDataBase, etc. etc.)
743 
744  gDataSet = const_cast<KVDataSet*>(this);
745  if (fRepository) fRepository->cd();
746  KVExpDB* db = GetDataBase();
747  if (db) db->cd();
748 }
749 
750 
751 
752 
757 
758 const Char_t* KVDataSet::GetDataSetEnv(const Char_t* type, const Char_t* defval) const
759 {
760  //Will look for gEnv->GetValue "name_of_dataset.type"
761  //then simply "type" if no dataset-specific value is found.
762  //If neither resource is defined, return the "defval" default value (="" by default)
763 
764  return KVBase::GetDataSetEnv(GetName(), type, defval);
765 }
766 
767 
768 
769 
774 
776 {
777  //Will look for gEnv->GetValue "name_of_dataset.type"
778  //then simply "type" if no dataset-specific value is found.
779  //If neither resource is defined, return the "defval" default value
780 
781  return KVBase::GetDataSetEnv(GetName(), type, defval);
782 }
783 
784 
785 
786 
791 
792 Bool_t KVDataSet::GetDataSetEnv(const Char_t* type, Bool_t defval) const
793 {
794  //Will look for gEnv->GetValue "name_of_dataset.type"
795  //then simply "type" if no dataset-specific value is found.
796  //If neither resource is defined, return the "defval" default value
797 
798  return KVBase::GetDataSetEnv(GetName(), type, defval);
799 }
800 
801 
802 
803 
804 
832 
834 {
835  // Open file containing data of given datatype for given run number of this dataset.
836  //
837  // Returns a pointer to the opened file; if the file is not available, we return nullptr.
838  //
839  // The user must cast the returned pointer to the correct class, which will
840  // depend on the data type and the dataset (see `$KVROOT/KVFiles/.kvrootrc`)
841  //
842  // **SPECIAL CASE: MFM data with EBYEDAT frames**
843  //
844  // If the variable
845  //
846  //~~~~~~~~~~~~~~~~~~~~~~~~~
847  // [dataset].MFM.WithEbyedat: yes
848  //~~~~~~~~~~~~~~~~~~~~~~~~~
849  //
850  // is set, then we expect to find the necessary `ACTIONS_*` files in the dataset directory
851  // in subdirectory `ebyedat` (they should have the same names as the data files prefixed by
852  // `ACTIONS_[expname].CHC_PAR.`).
853  //
854  // If in addition the variable
855  //
856  //~~~~~~~~~~~~~~~~~~~~~~~~~
857  // [dataset].MFM.EbyedatActionsExpName: [expname]
858  //~~~~~~~~~~~~~~~~~~~~~~~~~
859  //
860  // is set, then we use the same `ACTIONS` file for all runs, with name `ACTIONS_[expname].CHC_PAR`
861 
862 
863  if (!strcmp(type, "raw") && !strcmp(GetDataSetEnv("MFM.WithEbyedat", ""), "yes")) {
864  TString ebydir = GetDataSetDir();
865  ebydir += "/ebyedat";
866  gEnv->SetValue("KVMFMDataFileReader.ActionsDirectory", ebydir);
867  if (strcmp(GetDataSetEnv("MFM.EbyedatActionsExpName", ""), ""))
868  gEnv->SetValue("KVMFMDataFileReader.ActionsExpName", GetDataSetEnv("MFM.EbyedatActionsExpName", ""));
869  TObject* f = GetRepository()->OpenDataSetRunFile(this, type, run, GetName());
870  // reset in case another dataset opens a raw MFM file without EBYEDAT data
871  gEnv->SetValue("KVMFMDataFileReader.ActionsDirectory", "");
872  gEnv->SetValue("KVMFMDataFileReader.ActionsExpName", "");
873  return f;
874  }
875  return GetRepository()->OpenDataSetRunFile(this, type, run, GetName());
876 }
877 
878 
879 
880 
887 
889  Int_t run) const
890 {
891  //Return full path to file containing data of given datatype for given run number
892  //of this dataset. NB. only works for available run files, if their is no file in the repository for this run,
893  //the returned path will be empty.
894  //This path should be used with e.g. TChain::Add.
895 
896  //get name of file from available runs file
897  TString file("");
898  if (fRepository) file = GetRunfileName(type, run);
899  if (file == "")
900  return file.Data();
901  return fRepository->GetFullPathToOpenFile(this, type, file.Data());
902 }
903 
904 
905 
906 
913 
914 const Char_t* KVDataSet::GetRunfileName(const Char_t* type, Int_t run) const
915 {
916  //Return name of file containing data of given datatype
917  //for given run number of this dataset.
918  //NB. only works for available run files, if there is no file in the repository for this run,
919  //the returned path will be empty.
920 
921  //check data type is available
922  if (!HasDataType(type)) {
923  Error("GetRunfileName",
924  "No data of type \"%s\" available for dataset %s", type,
925  GetName());
926  return 0;
927  }
928  //get name of file from available runs file
929  return GetAvailableRunsFile(type)->GetFileName(run);
930 }
931 
932 
933 
934 
941 
943 {
944  //Return date of file containing data of given datatype
945  //for given run number of this dataset.
946  //NB. only works for available run files, if there is no file in the repository for this run,
947  //an error will be printed and the returned data is set to "Sun Jan 1 00:00:00 1995"
948  //(earliest possible date for TDatime class).
949 
950  static TDatime date;
951  date.Set(1995, 1, 1, 0, 0, 0);
952  //check data type is available
953  if (!HasDataType(type)) {
954  Error("GetRunfileDate",
955  "No data of type \"%s\" available for dataset %s", type,
956  GetName());
957  return date;
958  }
959  //get date of file from available runs file
960  TString filename;
961  if (!GetAvailableRunsFile(type)->GetRunInfo(run, date, filename)) {
962  Error("GetRunfileDate",
963  "Runfile not found for run %d (data type: %s)", run, type);
964  }
965  return date;
966 }
967 
968 
969 
970 
975 
977 {
978  //We check the availability of the run by looking in the available runs file associated
979  //with the given datatype.
980 
981  //check data type is available
982  if (!HasDataType(type)) {
983  Error("CheckRunfileAvailable",
984  "No data of type \"%s\" available for dataset %s", type,
985  GetName());
986  return 0;
987  }
988  return GetAvailableRunsFile(type)->CheckAvailable(run);
989 }
990 
991 
992 
993 
1003 
1004 const Char_t* KVDataSet::GetBaseFileName(const Char_t* type, Int_t run) const
1005 {
1006  //PRIVATE METHOD: Returns base name of data file containing data for the run of given datatype.
1007  //The filename corresponds to one of the formats defined in $KVROOT/KVFiles/.kvrootrc
1008  //by variables like:
1009  //
1010  //[dataset].DataSet.RunFileName.[type]: run%R.dat
1011  //
1012  //%R will be replaced with the run number
1013  //IF the format contains '%D' it will be replaced with the current date and time
1014 
1015  static TString tmp;
1016  //get format string
1017  TString fmt = GetDataSetEnv(Form("DataSet.RunFileName.%s", type));
1018  TString run_num(Form("%d", run));
1019  KVDatime now;
1020  TString date(now.AsSQLString());
1021  tmp = fmt;
1022  tmp.ReplaceAll("%R", run_num);
1023  if (fmt.Contains("%D")) {
1024  tmp.ReplaceAll("%D", date);
1025  }
1026  return tmp.Data();
1027 }
1028 
1029 
1030 
1031 
1035 
1037 {
1038  //Update list of available runs for given data 'type'
1039 
1040  //check data type is available
1041  if (!HasDataType(type)) {
1042  Error("UpdateAvailableRuns",
1043  "No data of type \"%s\" available for dataset %s", type,
1044  GetName());
1045  }
1046  KVAvailableRunsFile* a = GetAvailableRunsFile(type);
1047  a->Update(!a->FileExists());
1048 }
1049 
1050 
1051 
1052 
1057 
1059 {
1060  // Create a new runfile for the dataset of given datatype.
1061  // (only if this dataset is associated with a data repository)
1062  // Once the file has been filled, use CommitRunfile to submit it to the repository.
1063 
1064  if (!fRepository) return nullptr;
1065  TString tmp = GetBaseFileName(type, run);
1066  //turn any spaces into "_"
1067  tmp.ReplaceAll(" ", "_");
1068  return fRepository->CreateNewFile(this, type, tmp.Data());
1069 }
1070 
1071 
1072 
1073 
1082 
1083 void KVDataSet::DeleteRunfile(const Char_t* type, Int_t run, Bool_t confirm)
1084 {
1085  // Delete the file for the given run of data type "type" from the repository.
1086  // By default, confirm=kTRUE, which means that the user will be asked to confirm
1087  // that the file should be deleted. If confirm=kFALSE, no confirmation will be asked
1088  // for and the file will be deleted straight away.
1089  //
1090  // WARNING: this really does DELETE files in the repository, they cannot be
1091  // retrieved once they have been deleted.
1092 
1093  if (!fRepository) return;
1094 
1095  //get name of file to delete
1096  TString filename = GetAvailableRunsFile(type)->GetFileName(run);
1097  if (filename == "") {
1098  Error("DeleteRunfile", "Run %d of type %s does not exist.", run, type);
1099  return;
1100  }
1101  //delete file
1102  //prevent accidental deletion of certain types of runfiles
1103  KVString doNotDelete = GetDataSetEnv("DataSet.RunFile.DoNotDelete", "all");
1104  if (doNotDelete == "all" || doNotDelete.Contains(type)) {
1105  Error("DeleteRunFile", "%s files cannot be deleted", type);
1106  return;
1107  }
1108  fRepository->DeleteFile(this, type, filename.Data(), confirm);
1109  //was file deleted ? if so, remove entry from available runs file
1110  if (!fRepository->CheckFileStatus(this, type, filename.Data()))
1111  GetAvailableRunsFile(type)->Remove(run);
1112 }
1113 
1114 
1115 
1116 
1126 
1127 void KVDataSet::DeleteRunfiles(const Char_t* type, KVNumberList nl, Bool_t confirm)
1128 {
1129  //Delete files corresponding to a list of runs of data type "type" from the repository.
1130  //By default, confirm=kTRUE, which means that the user will be asked to confirm
1131  //that each file should be deleted. If confirm=kFALSE, no confirmation will be asked
1132  //for and the file will be deleted straight away.
1133  //if "nl" is empty (default value) all runs of the dataset corresponding to the given type
1134  //will be deleted
1135  //WARNING: this really does DELETE files in the repository, they cannot be
1136  //retrieved once they have been deleted.
1137 
1138  if (nl.IsEmpty()) nl = GetRunList(type);
1139  if (nl.IsEmpty()) return;
1140  nl.Begin();
1141  while (!nl.End()) {
1142  DeleteRunfile(type, nl.Next(), confirm);
1143  }
1144 }
1145 
1146 
1147 
1148 
1155 
1157 {
1158  //Prints out and returns list of runs after date / time selection
1159  //Runs generated between ]min;max[ are selected
1160  //if min=NULL runs with date <max are selected
1161  //if max=NULL runs with date >min are selected
1162  //if max and min are NULL returns empty KVNumberList
1163 
1164  if (!min && !max) return 0;
1165 
1166  if (min) printf("date minimum %s\n", min->AsString());
1167  if (max) printf("date maximum %s\n", max->AsString());
1168 
1169  KVNumberList numb;
1170 
1171  unique_ptr<TList> ll(GetListOfAvailableSystems(type));
1172  KVDBSystem* sys = 0;
1173  KVRunFile* run = 0;
1174  unique_ptr<TList> lrun;
1175  for (Int_t nl = 0; nl < ll->GetEntries(); nl += 1) {
1176  sys = (KVDBSystem*)ll->At(nl);
1177  lrun.reset(GetListOfAvailableSystems(type, sys));
1178  KVNumberList oldList = numb;
1179  for (Int_t nr = 0; nr < lrun->GetEntries(); nr += 1) {
1180  run = (KVRunFile*)lrun->At(nr);
1181 
1182  if (min && max) {
1183  if (*min < run->GetRun()->GetDatime() && run->GetRun()->GetDatime() < *max) {
1184  numb.Add(run->GetRunNumber());
1185  }
1186  }
1187  else if (min) {
1188  if (*min < run->GetRun()->GetDatime()) {
1189  numb.Add(run->GetRunNumber());
1190  }
1191  }
1192  else if (max) {
1193  if (run->GetRun()->GetDatime() < *max) {
1194  numb.Add(run->GetRunNumber());
1195  }
1196  }
1197  }
1198  // print runs for system if any
1199  if (numb.GetEntries() > oldList.GetEntries()) printf("%s : %s\n", sys->GetName(), (numb - oldList).AsString());
1200  }
1201  return numb;
1202 
1203 }
1204 
1205 
1206 
1207 
1213 
1214 KVNumberList KVDataSet::GetRunList_StageSelection(const Char_t* type, const Char_t* ref_type, KVDBSystem* system, Bool_t OnlyCol)
1215 {
1216  // Returns list of runs which are present for data type "base_type" but not for "other_type"
1217  // if type is NULL or ="" returns empty KVNumberList
1218  // If pointer to system is given, only runs for the system are considered.
1219  // If OnlyCol=kTRUE (kFALSE default) only systems with KVDBSystem::IsCollision()=kTRUE are considered
1220 
1221  KVNumberList manquant;
1222  TList* ll = GetListOfAvailableSystems(ref_type);
1223  if (!ll || !ll->GetEntries()) {
1224  //numb.Clear();
1225  Info("GetRunList_StageSelection", "No data available of type \"%s\"", ref_type);
1226  if (ll) delete ll;
1227  return manquant;
1228  }
1229  if (system && !ll->FindObject(system)) {
1230  Info("GetRunList_StageSelection", "No data available of type \"%s\" for system %s", ref_type, system->GetName());
1231  delete ll;
1232  return manquant;
1233  }
1234 
1235  Info("GetRunList_StageSelection", "Liste des runs presents dans \"%s\" mais absent dans \"%s\"", ref_type, type);
1236 
1237  KVDBSystem* sys = 0;
1238  KVNumberList nsys_ref;
1239  KVNumberList nsys;
1240 
1241  for (Int_t nl = 0; nl < ll->GetEntries(); nl += 1) {
1242 
1243  sys = (KVDBSystem*)ll->At(nl);
1244  if (system && sys != system) continue;
1245  if (OnlyCol && !sys->IsCollision()) continue;
1246  nsys = GetRunList(type, sys);
1247  nsys_ref = GetRunList(ref_type, sys);
1248  Int_t nref = nsys_ref.GetNValues();
1249 
1250  nsys_ref.Remove(nsys);
1251 
1252  Info("GetRunList_StageSelection", "\nKVDBSystem : %s --> %d runs manquants sur %d : %s",
1253  sys->GetName(),
1254  nsys_ref.GetNValues(),
1255  nref,
1256  nsys_ref.AsString()
1257  );
1258  manquant.Add(nsys_ref);
1259  }
1260  delete ll;
1261  return manquant;
1262 
1263 }
1264 
1265 
1266 
1270 
1272 {
1273  // Returns list of runs of given type that were created with the given version of KaliVeda.
1274  // If system!="" then only runs for the given system are considered
1275 
1276  KVNumberList runs;
1277  if (sys) {
1278  unique_ptr<TList> lrun(GetListOfAvailableSystems(type, sys));
1279  TIter next(lrun.get());
1280  KVRunFile* run;
1281  while ((run = (KVRunFile*)next())) {
1282  if (!strcmp(run->GetVersion(), version)) runs.Add(run->GetRunNumber());
1283  }
1284  return runs;
1285  }
1286  unique_ptr<TList> ll(GetListOfAvailableSystems(type));
1287  if (!ll.get() || !ll->GetEntries()) {
1288  //numb.Clear();
1289  Info("GetRunList_VersionSelection", "No data available of type \"%s\"", type);
1290  return runs;
1291  }
1292  Int_t nsys = ll->GetEntries();
1293  for (Int_t nl = 0; nl < nsys; nl += 1) {
1294  sys = (KVDBSystem*)ll->At(nl);
1295  unique_ptr<TList> lrun(GetListOfAvailableSystems(type, sys));
1296  TIter next(lrun.get());
1297  KVRunFile* run;
1298  while ((run = (KVRunFile*)next())) {
1299  if (!strcmp(run->GetVersion(), version)) runs.Add(run->GetRunNumber());
1300  }
1301  }
1302  return runs;
1303 }
1304 
1305 
1306 
1311 
1313 {
1314  // Commit a runfile previously created with NewRunfile() to the repository.
1315  // Any previous version of the runfile will be deleted.
1316  // The available runs list for this data 'type' is updated.
1317 
1318  if (!fRepository) return;
1319 
1320  //keep name of file for updating available runs list
1321  TString newfile = gSystem->BaseName(file->GetName());
1322 
1323  fRepository->CommitFile(file, type, this);
1324  //update list of available datatypes of dataset,
1325  //in case this addition has created a new subdirectory
1326  CheckAvailable();
1327  //check if previous version of file exists
1328  //get name of file from available runs file
1329  //note that when the file is the first of a new subdirectory, GetAvailableRunsFile->GetFileName
1330  //will cause the available runs file to be created, and it will contain one entry:
1331  //the new file!
1332  TString oldfile = GetAvailableRunsFile(type)->GetFileName(run);
1333  if (oldfile != "" && oldfile != newfile) {
1334  //delete previous version - no confirmation
1335  fRepository->DeleteFile(this, type, oldfile.Data(),
1336  kFALSE);
1337  //was file deleted ? if so, remove entry from available runs file
1338  if (!fRepository->CheckFileStatus(this, type, oldfile.Data()))
1339  GetAvailableRunsFile(type)->Remove(run);
1340  }
1341  if (oldfile != newfile) {
1342  //add entry for new run in available runs file
1343  GetAvailableRunsFile(type)->Add(run, newfile.Data());
1344  }
1345 }
1346 
1347 
1348 
1349 
1355 
1357 {
1358  //if fUserGroups has been set with SetUserGroups(), we check that the current user's name
1359  //(gSystem->GetUserInfo()->fUser) appears in at least one of the groups in the list.
1360  //Returns kFALSE if user's name is not found in any of the groups.
1361  //if fUserGroups="" (default), we return kTRUE for all users.
1362 
1363  if (fUserGroups == "")
1364  return kTRUE; /* no groups set, all users have access */
1365 
1366  //split into array of group names
1367  unique_ptr<TObjArray> toks(fUserGroups.Tokenize(' '));
1368  TObjString* group_name;
1369  TIter next_name(toks.get());
1370  while ((group_name = (TObjString*) next_name())) {
1371  //for each group_name, we check if the user's name appears in the group
1372  if (!fRepository || (fRepository && fRepository->GetDataSetManager()->
1373  CheckUser(group_name->String().Data()))
1374  ) {
1375  return kTRUE;
1376  }
1377  }
1378  return kFALSE;
1379 }
1380 
1381 
1382 
1383 
1386 
1388 {
1389  //Set pointer to data repository in which dataset is stored
1390  fRepository = dr;
1391 }
1392 
1393 
1394 
1395 
1398 
1400 {
1401  //Get pointer to data repository in which dataset is stored
1402  return fRepository;
1403 }
1404 
1405 
1406 
1407 
1412 
1414 {
1415  //Check all runs for a given datatype and make sure that only one version
1416  //exists for each run. If not, we print a report on the runfiles which occur
1417  //multiple times, with the associated date and file name.
1418 
1419  KVNumberList doubles =
1420  GetAvailableRunsFile(data_type)->CheckMultiRunfiles();
1421  if (doubles.IsEmpty()) {
1422  cout << "OK. No runs appear more than once." << endl;
1423  }
1424  else {
1425  cout << "Runs which appear more than once: " << doubles.
1426  AsString() << endl << endl;
1427  //print dates and filenames for each run
1428 
1429  doubles.Begin();
1430  KVList filenames, dates;
1431  while (!doubles.End()) {
1432 
1433  Int_t rr = doubles.Next();
1434 
1435  //get infos for current run
1436  GetAvailableRunsFile(data_type)->GetRunInfos(rr, &dates, &filenames);
1437 
1438  cout << "Run " << rr << " : " << dates.
1439  GetEntries() << " files >>>>>>" << endl;
1440  for (int i = 0; i < dates.GetEntries(); i++) {
1441 
1442  cout << "\t" << ((TObjString*) filenames.At(i))->String().
1443  Data() << "\t" << ((TObjString*) dates.At(i))->String().
1444  Data() << endl;
1445 
1446  }
1447  }
1448  }
1449 }
1450 
1451 
1452 
1453 
1462 
1463 void KVDataSet::CleanMultiRunfiles(const Char_t* data_type, Bool_t confirm)
1464 {
1465  // Check all runs for a given datatype and make sure that only one version
1466  // exists for each run. If not, we print a report on the runfiles which occur
1467  // multiple times, with the associated date and file name, and then we
1468  // destroy all but the most recent version of the file in the repository, and
1469  // update the runlist accordingly.
1470  // By default, we ask for confirmation before deleting each file.
1471  // Call with confirm=kFALSE to delete WITHOUT CONFIRMATION (DANGER!! WARNING!!!)
1472 
1473  if (!fRepository) return;
1474 
1475  KVAvailableRunsFile* ARF = GetAvailableRunsFile(data_type);
1476  KVNumberList doubles = ARF->CheckMultiRunfiles();
1477  if (doubles.IsEmpty()) {
1478  cout << "OK. No runs appear more than once." << endl;
1479  }
1480  else {
1481  cout << "Runs which appear more than once: " << doubles.
1482  AsString() << endl << endl;
1483  //print dates and filenames for each run
1484 
1485  KVList filenames, dates;
1486  doubles.Begin();
1487  while (!doubles.End()) {
1488 
1489  Int_t rr = doubles.Next();
1490 
1491  //get infos for current run
1492  ARF->GetRunInfos(rr, &dates, &filenames);
1493 
1494  TDatime most_recent("1998-12-25 00:00:00");
1495  Int_t i_most_recent = 0;
1496  cout << "Run " << rr << " : " << dates.
1497  GetEntries() << " files >>>>>>" << endl;
1498  for (int i = 0; i < dates.GetEntries(); i++) {
1499 
1500  //check if run is most recent
1501  TDatime rundate(((TObjString*) dates.At(i))->String().Data());
1502  if (rundate > most_recent) {
1503 
1504  most_recent = rundate;
1505  i_most_recent = i;
1506 
1507  }
1508  }
1509  //Now, we loop over the list again, this time we destroy all but the most recent
1510  //version of the runfile
1511  for (int i = 0; i < dates.GetEntries(); i++) {
1512 
1513  if (i == i_most_recent) {
1514  cout << "KEEP : ";
1515  }
1516  else {
1517  cout << "DELETE : ";
1518  }
1519  cout << "\t" << ((TObjString*) filenames.At(i))->String().
1520  Data() << "\t" << ((TObjString*) dates.At(i))->String().
1521  Data() << endl;
1522  if (i != i_most_recent) {
1523  //delete file from repository forever and ever
1524  fRepository->DeleteFile(this, data_type,
1525  ((TObjString*) filenames.At(i))->
1526  String().Data(), confirm);
1527  //remove file entry from available runlist
1528  ARF->Remove(rr,
1529  ((TObjString*) filenames.At(i))->String().
1530  Data());
1531  }
1532  }
1533  }
1534  }
1535 }
1536 
1537 
1538 
1539 
1545 
1547  KVDataRepository* other_repos)
1548 {
1549  //Use this method to check whether the file of type "data_type" for run number "run"
1550  //in the data repository "other_repos" is more recent than the file contained in the data
1551  //repository corresponding to this dataset.
1552  //Returns kFALSE if file in other repository is more recent.
1553 
1554  if (!other_repos)
1555  return kTRUE;
1556  //get dataset with same name as this one from dataset manager of other repository
1557  KVDataSet* ds = other_repos->GetDataSetManager()->GetDataSet(GetName());
1558  if (!ds) {
1559  Error("CheckRunfileUpToDate",
1560  "Dataset \"%s\" not found in repository \"%s\"", GetName(),
1561  other_repos->GetName());
1562  return kFALSE;
1563  }
1564  //compare dates of the two runfiles
1565  if (GetRunfileDate(data_type, run) < ds->GetRunfileDate(data_type, run))
1566  return kFALSE;
1567  return kTRUE;
1568 }
1569 
1570 
1571 
1572 
1579 
1581  const Char_t* other_repos)
1582 {
1583  //Use this method to check whether the file of type "data_type" for run number "run"
1584  //in the data repository "other_repos" is more recent than the file contained in the data
1585  //repository corresponding to this dataset.
1586  //Returns kTRUE if no repository with name "other_repos" exists.
1587  //Returns kFALSE if file in other repository is more recent.
1588 
1589  KVDataRepository* _or =
1590  gDataRepositoryManager->GetRepository(other_repos);
1591  if (_or)
1592  return CheckRunfileUpToDate(data_type, run, _or);
1593  Error("CheckRunfileUpToDate",
1594  "No data repository known with this name : %s", other_repos);
1595  return kTRUE;
1596 }
1597 
1598 
1599 
1600 
1604 
1605 void KVDataSet::CheckUpToDate(const Char_t* data_type,
1606  const Char_t* other_repos)
1607 {
1608  //Check whether all files of type "data_type" for run number "run" in the data repository
1609  //are up to date (i.e. at least as recent) as compared to the files in data repository "other_repos".
1610 
1611  if (!fRepository) return;
1612 
1613  KVDataRepository* _or =
1614  gDataRepositoryManager->GetRepository(other_repos);
1615  if (!_or) {
1616  Error("CheckUpToDate",
1617  "No data repository known with this name : %s", other_repos);
1618  return;
1619  }
1620  KVNumberList runlist = GetAvailableRunsFile(data_type)->GetRunList();
1621  runlist.Begin();
1622  Int_t need_update = 0;
1623  while (!runlist.End()) {
1624  //check run
1625  Int_t rr = runlist.Next();
1626  if (!CheckRunfileUpToDate(data_type, rr, _or)) {
1627  cout << " *** run " << rr << " needs update ***" <<
1628  endl;
1629  cout << "\t\tREPOSITORY: " << fRepository->
1630  GetName() << "\tDATE: " << GetRunfileDate(data_type,
1631  rr).
1632  AsString() << endl;
1633  cout << "\t\tREPOSITORY: " << other_repos << "\tDATE: " << _or->
1634  GetDataSetManager()->GetDataSet(GetName())->
1635  GetRunfileDate(data_type,
1636  rr).AsString() << endl;
1637  need_update++;
1638  }
1639  }
1640  if (!need_update) {
1641  cout << " *** All runfiles are up to date for data type " <<
1642  data_type << endl;
1643  }
1644 }
1645 
1646 
1647 
1648 
1652 
1654  const Char_t* other_repos)
1655 {
1656  //Returns list of all runs of type "data_type" which may be updated
1657  //from the repository named "other_repos". See CheckUpToDate().
1658 
1659  KVNumberList updates;
1660  if (!fRepository) return updates;
1661 
1662  KVDataRepository* _or =
1663  gDataRepositoryManager->GetRepository(other_repos);
1664  if (!_or) {
1665  Error("CheckUpToDate",
1666  "No data repository known with this name : %s", other_repos);
1667  return updates;
1668  }
1669  KVNumberList runlist = GetAvailableRunsFile(data_type)->GetRunList();
1670  runlist.Begin();
1671  while (!runlist.End()) {
1672  //check run
1673  Int_t rr = runlist.Next();
1674  if (!CheckRunfileUpToDate(data_type, rr, _or)) {
1675  //run is out of date
1676  updates.Add(rr);
1677  }
1678  }
1679  return updates;
1680 }
1681 
1682 
1683 
1684 
1689 
1691  const KVDBSystem* system) const
1692 {
1693  //Returns list of all runs available for given "data_type"
1694  //If a pointer to a reaction system is given, only runs for the
1695  //given system will be included in the list.
1696  KVNumberList list;
1697  if (!fRepository || !HasDataType(data_type)) {
1698  Error("GetRunList",
1699  "No data of type %s available. Runlist will be empty.",
1700  data_type);
1701  }
1702  else {
1703  list = GetAvailableRunsFile(data_type)->GetRunList(system);
1704  }
1705  return list;
1706 }
1707 
1708 
1709 
1710 
1740 
1742 {
1743  //This method returns a pointer to the available analysis task whose description (title) contains
1744  //all of the whitespace-separated keywords (which may be regular expressions)
1745  //given in the string "keywords". The comparison is case-insensitive.
1746  //
1747  //WARNING: this method can only be used to access analysis tasks that are
1748  //available for this dataset, i.e. for which the corresponding prerequisite data type
1749  //is available in the repository.
1750  //For unavailable data/tasks, use GetAnalysisTaskAny(const Char_t*).
1751  //
1752  //EXAMPLES
1753  //Let us suppose that the current dataset has the following list of tasks:
1754  //
1755 // root [2] gDataSet->Print("tasks")
1756 // 1. Event reconstruction from raw data (raw->recon)
1757 // 2. Analysis of raw data
1758 // 3. Identification of reconstructed events (recon->ident)
1759 // 4. Analysis of reconstructed events (recon)
1760 // 5. Analysis of partially identified & calibrated reconstructed events (ident)
1761 // 6. Analysis of fully calibrated physical data (root)
1762  //Then the following will occur:
1763  //
1764 // root [14] gDataSet->GetAnalysisTask("raw->recon")->Print()
1765 // KVDataAnalysisTask : Event reconstruction from raw data (raw->recon)
1766 //
1767 // root [10] gDataSet->GetAnalysisTask("analysis root")->Print()
1768 // KVDataAnalysisTask : Analysis of fully calibrated physical data (root)
1769 //
1770 
1771  //case-insensitive search for matches in list based on 'title' attribute
1772  return (KVDataAnalysisTask*)fTasks.FindObjectAny("title", keywords, kTRUE, kFALSE);
1773 }
1774 
1775 
1776 
1777 
1790 
1791 void KVDataSet::MakeAnalysisClass(const Char_t* task, const Char_t* classname)
1792 {
1793  //Create a skeleton analysis class to be used for analysis of the data belonging to this dataset.
1794  //
1795  // task = keywords contained in title of analysis task (see GetAnalysisTask(const Char_t*))
1796  // (you do not need to include 'analysis', it is added automatically)
1797  // classname = name of new analysis class
1798  //
1799  //Example:
1800  // MakeAnalysisClass("raw", "MyRawDataAnalysis")
1801  // --> make skeleton raw data analysis class in files MyRawDataAnalysis.cpp & MyRawDataAnalysis.h
1802  // MakeAnalysisClass("fully calibrated", "MyDataAnalysis")
1803  // --> make skeleton data analysis class in files MyDataAnalysis.cpp & MyDataAnalysis.h
1804 
1805  KVString _task = task;
1806  _task += " analysis";
1807  //We want to be able to write analysis classes even when we don't have any data
1808  //to analyse. Therefore we use GetAnalysisTaskAny.
1809  KVDataAnalysisTask dat = GetAnalysisTaskAny(_task.Data());
1810  if (dat.IsZombie()) {
1811  Error("MakeAnalysisClass",
1812  "called for unknown or unavailable analysis task : %s", _task.Data());
1813  return;
1814  }
1815  if (!dat.WithUserClass()) {
1816  Error("MakeAnalysisClass",
1817  "no user analysis class for analysis task : %s", dat.GetTitle());
1818  return;
1819  }
1820 
1821  //all analysis base classes must define a static Make(const Char_t * classname)
1822  //which generates the skeleton class files.
1823 
1824  TClass* cl = nullptr;
1825  //has the user base class for the task been compiled and loaded ?
1827  else
1828  return;
1829 
1830  //set up call to static Make method
1831  unique_ptr<TMethodCall> methcall(new TMethodCall(cl, "Make", Form("\"%s\"", classname)));
1832 
1833  if (!methcall->IsValid()) {
1834  Error("MakeAnalysisClass", "static Make(const Char_t*) method for class %s is not valid",
1835  cl->GetName());
1836  return;
1837  }
1838 
1839  //generate skeleton class
1840  methcall->Execute();
1841 }
1842 
1843 
1844 
1845 
1849 
1850 Bool_t KVDataSet::OpenDataSetFile(const Char_t* filename, ifstream& file)
1851 {
1852  // Look for (and open for reading, if found) the named file in the directory which
1853  // contains the files for this dataset (given by GetDataSetDir())
1854 
1855  return OpenDataSetFile(GetName(), filename, file);
1856 }
1857 
1858 
1859 
1863 
1864 Bool_t KVDataSet::OpenDataSetFile(const TString& dataset, const Char_t* filename, ifstream& file)
1865 {
1866  // Static method to look for (and open for reading, if found) the named file in the directory which
1867  // contains the files for the dataset
1868 
1869  TString datasetdir = KVBase::GetDataSetEnv(dataset, "DataSet.Directory", dataset);
1870  if (gSystem->IsAbsoluteFileName(datasetdir)) {
1871  // dataset directory is outside of standard KV installation directories
1872  // use absolute path to search for file
1873  TString abspath;
1874  abspath.Form("%s/%s", datasetdir.Data(), filename);
1875  return SearchAndOpenKVFile(abspath, file);
1876  }
1877  // dataset directory is a subdirectory of GetDATADIRFilePath()
1878  return SearchAndOpenKVFile(filename, file, datasetdir);
1879 }
1880 
1881 
1882 
1886 
1888 {
1889  // Find a file in the dataset directory (given by GetDataSetDir())
1890  // Returns full path to file if found, empty string if not
1891 
1892  return GetFullPathToDataSetFile(GetName(), filename);
1893 }
1894 
1895 
1896 
1900 
1902 {
1903  // Static method to find a file in the dataset directory (given by GetDataSetDir())
1904  // Returns full path to file if found, empty string if not
1905 
1906  TString fullpath;
1907  TString datasetdir = KVBase::GetDataSetEnv(dataset, "DataSet.Directory", dataset);
1908  if (!SearchKVFile(filename, fullpath, datasetdir)) {
1909  ::Warning("KVDataSet::GetFullPathToDataSetFile", "File %s not found in dataset subdirectory %s", filename, datasetdir.Data());
1910  fullpath = "";
1911  }
1912  return fullpath;
1913 }
1914 
1915 
1916 
1920 
1921 Bool_t KVDataSet::FindDataSetFile(const TString& dataset, const Char_t* filename)
1922 {
1923  // Static method to find a file in the dataset directory (given by GetDataSetDir())
1924  // Returns kTRUE if found, kFALSE if not
1925 
1926  TString fullpath;
1927  TString datasetdir = KVBase::GetDataSetEnv(dataset, "DataSet.Directory", dataset);
1928  return SearchKVFile(filename, fullpath, datasetdir);
1929 }
1930 
1931 
1932 
1936 
1938 {
1939  // Find a file in the dataset directory (given by GetDataSetDir())
1940  // Returns kTRUE if found, kFALSE if not
1941 
1942  return FindDataSetFile(GetName(), filename);
1943 }
1944 
1945 
1946 
1947 
1958 
1960 {
1961  //This method returns a copy of the analysis task whose description (title) contains
1962  //all of the whitespace-separated keywords (which may be regular expressions)
1963  //given in the string "keywords". The comparison is case-insensitive.
1964  //The analysis task does not need to be "available", i.e. the associated prerequisite
1965  //data type does not have to be present in the repository (see GetAnalysisTask).
1966  //
1967  // If no task is found, the returned KVDataAnalysisTask object will be a zombie
1968  // (test with IsZombie()).
1969 
1970  //case-insensitive search for matches in list of all analysis tasks, based on 'title' attribute
1971  KVDataAnalysisTask* tsk =
1973  if (!tsk) {
1974  Error("GetAnalysisTaskAny", "No task found with the following keywords in its title : %s",
1975  keywords);
1976  KVDataAnalysisTask bad_task;
1977  bad_task.SetBit(kZombie);
1978  return bad_task;
1979  }
1980  //make new copy of default analysis task
1981  KVDataAnalysisTask new_task(*tsk);
1982  //check if any dataset-specific parameters need to be changed
1983  SetDataSetSpecificTaskParameters(&new_task);
1984  return new_task;
1985 }
1986 
1987 
1988 
1989 
1995 
1997 {
1998  // Returns kTRUE if database needs to be regenerated from source files,
1999  // i.e. if source files are more recent than DataBase.root
2000  // In case no directory exists for dataset (dataset added 'on the fly')
2001  // we create the directory and fill it with dummy files (Makefile, Runlist.csv, Systems.dat)
2002 
2003  TString pwd = gSystem->pwd();
2004 
2005  TString path = "";
2006  if (!SearchKVFile(GetDataSetDir(), path)) {
2007  // dataset directory doesn't exist - create it
2008  Info("DataBaseNeedsUpdate", "%s: Creating new dataset directory %s",
2009  GetName(), GetDataSetDir());
2010  if (gSystem->mkdir(GetDataSetDir())) {
2011  // problem creating directory
2012  Error("DataBaseNeedsUpdate",
2013  "%s: Dataset directory %s does not exist and cannot be created ?",
2014  GetName(), GetDataSetDir());
2015  return kFALSE;
2016  }
2017  // create dummy files
2018  SearchKVFile(GetDataSetDir(), path); // get full path
2019  path += "/";
2020  TString filename = path + "Makefile";
2021  ofstream of1(filename.Data());
2022  of1 << "$(KV_WORK_DIR)/db/" << GetName() << "/DataBase.root : Runlist.csv Systems.dat" << endl;
2023  of1 << "\t@echo Database needs update" << endl;
2024  of1.close();
2025  filename = path + "Runlist.csv";
2026  ofstream of2(filename.Data());
2027  of2 << "# Automatically generated dummy Runlist.csv file" << endl;
2028  of2.close();
2029  filename = path + "Systems.dat";
2030  ofstream of3(filename.Data());
2031  of3 << "# Automatically generated dummy Systems.dat file" << endl;
2032  of3.close();
2033  }
2034  gSystem->cd(GetDataSetDir());
2035  TString cmd = "make -q";
2036  Int_t ret = gSystem->Exec(cmd.Data());
2037  gSystem->cd(pwd.Data());
2038  return (ret != 0);
2039 }
2040 
2041 
2042 
2059 
2061 {
2062  // Returns name of output repository for given task.
2063  // By default it is the name of the repository associated with this dataset,
2064  // but can be changed by the following environment variables:
2065  //
2066  // [repository].DefaultOutputRepository: [other repository]
2067  // - this means that all tasks carried out on data in [repository]
2068  // will have their output files placed in [other repository]
2069  //
2070  // [taskname].DataAnalysisTask.OutputRepository: [other repository]
2071  // - this means that for [taskname], any output files will
2072  // be placed in [other repository]
2073  //
2074  // [dataset].[taskname].DataAnalysisTask.OutputRepository: [other repository]
2075  // - this means that for given [dataset] & [taskname],
2076  // any output files will be placed in [other repository]
2077 
2078  if (gEnv->Defined(Form("%s.DataRepository.DefaultOutputRepository", GetRepository()->GetName())))
2079  return TString(gEnv->GetValue(Form("%s.DataRepository.DefaultOutputRepository", GetRepository()->GetName()), ""));
2080  TString orep = GetDataSetEnv(Form("%s.DataAnalysisTask.OutputRepository", taskname), GetRepository()->GetName());
2081  return orep;
2082 }
2083 
2084 
2085 
2086 
2090 
2091 void KVDataSet::CopyRunfilesFromRepository(const Char_t* type, KVNumberList runs, const Char_t* destdir)
2092 {
2093  // Copies the runfiles of given "type" into the local directory "destdir".
2094  // Run numbers given as a list of type "1-10".
2095 
2096  KVDataRepository* repo = GetRepository();
2097  runs.Begin();
2098  while (!runs.End()) {
2099  int run = runs.Next();
2100  TString filename = GetRunfileName(type, run);
2101  TString destpath;
2102  AssignAndDelete(destpath, gSystem->ConcatFileName(destdir, filename));
2103  repo->CopyFileFromRepository(this, type, filename, destpath);
2104  }
2105 }
2106 
2107 
2108 
2109 
2114 
2115 void KVDataSet::CopyRunfilesToRepository(const Char_t* type, KVNumberList runs, const Char_t* destrepo)
2116 {
2117  // Copies the runfiles of given "type" from the data repository associated
2118  // with this dataset into the local repository "destrepo".
2119  // Run numbers given as a list of type "1-10".
2120 
2121  KVDataRepository* repo = GetRepository();
2122  KVDataRepository* dest_repo = gDataRepositoryManager->GetRepository(destrepo);
2123 
2124  if (!dest_repo) {
2125  Error("CopyRunfilesToRepository", "Unknown destination repository : %s", destrepo);
2127  return;
2128  }
2129 
2130  KVDataSet* dest_ds = dest_repo->GetDataSetManager()->GetDataSet(GetName());
2131  dest_repo->CreateAllNeededSubdirectories(dest_ds, type);
2132  runs.Begin();
2133  while (!runs.End()) {
2134  int run = runs.Next();
2135  TString filename = GetRunfileName(type, run);
2136  TString destpath = dest_repo->GetFullPathToTransferFile(dest_ds, type, filename);
2137  repo->CopyFileFromRepository(this, type, filename, destpath);
2138  }
2139 }
2140 
2141 
int Int_t
void AssignAndDelete(TString &target, char *tobedeleted)
KVDataRepositoryManager * gDataRepositoryManager
KVDataSetManager * gDataSetManager
KVDataSet * gDataSet
Definition: KVDataSet.cpp:29
KVExpDB * gExpDB
Definition: KVExpDB.cpp:13
ClassImp(KVPartitionList) void KVPartitionList
Initialisation.
#define f(i)
char Char_t
const Bool_t kFALSE
bool Bool_t
double Double_t
const Bool_t kTRUE
const char Option_t
#define gDirectory
R__EXTERN TEnv * gEnv
int type
char * Form(const char *fmt,...)
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:113
Database class used to store information on different colliding systems studied during an experiment.
Definition: KVDBSystem.h:51
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 Bool_t CheckUserBaseClassIsLoaded()
virtual void SetDataAnalyser(const Char_t *d)
virtual Bool_t WithUserClass() const
virtual void SetPrereq(const Char_t *p)
virtual void SetStatusUpdateInterval(Long64_t n)
virtual const Char_t * GetUserBaseClass() const
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)
const KVSeqCollection * GetAnalysisTaskList() const
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:207
TString GetOutputRepository(const Char_t *taskname) const
Definition: KVDataSet.cpp:2060
virtual void OpenDBFile(const Char_t *full_path_to_dbfile) const
Open the database from a file on disk.
Definition: KVDataSet.cpp:103
KVNumberList GetRunList_VersionSelection(const Char_t *type, const Char_t *version, KVDBSystem *sys=0)
Definition: KVDataSet.cpp:1271
void CheckMultiRunfiles(const Char_t *data_type)
Definition: KVDataSet.cpp:1413
KVNumberList GetRunList_StageSelection(const Char_t *other_type, const Char_t *base_type, KVDBSystem *sys=0, Bool_t OnlyCol=kFALSE)
Definition: KVDataSet.cpp:1214
void CheckUpToDate(const Char_t *data_type, const Char_t *other_repos)
Definition: KVDataSet.cpp:1605
const Char_t * GetDBName() const
Definition: KVDataSet.cpp:87
KVDataRepository * GetRepository() const
Get pointer to data repository in which dataset is stored.
Definition: KVDataSet.cpp:1399
void CopyRunfilesToRepository(const Char_t *type, KVNumberList runs, const Char_t *destrepo)
Definition: KVDataSet.cpp:2115
const Char_t * GetDBFileName() const
Definition: KVDataSet.cpp:70
const Char_t * GetDataSetDir() const
Definition: KVDataSet.cpp:720
void DeleteRunfiles(const Char_t *type, KVNumberList lrun="", Bool_t confirm=kTRUE)
Definition: KVDataSet.cpp:1127
KVNumberList GetUpdatableRuns(const Char_t *data_type, const Char_t *other_repos)
Definition: KVDataSet.cpp:1653
virtual void ls(Option_t *opt="") const
Print dataset information.
Definition: KVDataSet.cpp:399
void DeleteRunfile(const Char_t *type, Int_t run, Bool_t confirm=kTRUE)
Definition: KVDataSet.cpp:1083
KVAvailableRunsFile * GetAvailableRunsFile(const Char_t *type) const
Definition: KVDataSet.cpp:48
virtual void AddAvailableDataType(const Char_t *)
Definition: KVDataSet.cpp:528
virtual TList * GetListOfAvailableSystems(const Char_t *datatype, KVDBSystem *systol=0)
Definition: KVDataSet.cpp:614
Bool_t CheckRunfileUpToDate(const Char_t *data_type, Int_t run, KVDataRepository *other_repos)
Definition: KVDataSet.cpp:1546
void SetName(const char *name)
Definition: KVDataSet.cpp:688
KVDataAnalysisTask * GetAnalysisTask(Int_t) const
Definition: KVDataSet.cpp:589
virtual const Char_t * GetBaseFileName(const Char_t *type, Int_t run) const
Definition: KVDataSet.cpp:1004
virtual void SaveDataBase() const
Definition: KVDataSet.cpp:190
virtual void SetAnalysisTasks(const KVSeqCollection *)
Definition: KVDataSet.cpp:543
KVNumberList GetRunList_DateSelection(const Char_t *type, TDatime *min=0, TDatime *max=0)
Definition: KVDataSet.cpp:1156
virtual void CheckAvailable()
Definition: KVDataSet.cpp:471
const Char_t * GetRunfileName(const Char_t *type, Int_t run) const
Definition: KVDataSet.cpp:914
TDatime GetRunfileDate(const Char_t *type, Int_t run)
Definition: KVDataSet.cpp:942
const Char_t * GetDataSetEnv(const Char_t *type, const Char_t *defval="") const
Definition: KVDataSet.cpp:758
virtual Int_t GetNtasks() const
Definition: KVDataSet.cpp:574
KVNumberList GetRunList(const Char_t *data_type, const KVDBSystem *sys=0) const
Definition: KVDataSet.cpp:1690
TString GetFullPathToDataSetFile(const Char_t *filename)
Definition: KVDataSet.cpp:1887
TString GetFullPathToRunfile(const Char_t *type, Int_t run) const
Definition: KVDataSet.cpp:888
void CopyRunfilesFromRepository(const Char_t *type, KVNumberList runs, const Char_t *destdir)
Definition: KVDataSet.cpp:2091
void UpdateAvailableRuns(const Char_t *type)
Definition: KVDataSet.cpp:1036
virtual void MakeAnalysisClass(const Char_t *task, const Char_t *classname)
Definition: KVDataSet.cpp:1791
TObject * open_runfile(const Char_t *type, Int_t run)
Definition: KVDataSet.cpp:833
void CommitRunfile(const Char_t *type, Int_t run, TFile *file)
Definition: KVDataSet.cpp:1312
KVExpDB * GetDataBase(Option_t *opt="") const
Definition: KVDataSet.cpp:285
virtual KVDataAnalysisTask GetAnalysisTaskAny(const Char_t *keywords) const
Definition: KVDataSet.cpp:1959
virtual Bool_t DataBaseNeedsUpdate() const
Definition: KVDataSet.cpp:1996
Bool_t OpenDataSetFile(const Char_t *filename, std::ifstream &file)
Definition: KVDataSet.cpp:1850
void SetDataSetSpecificTaskParameters(KVDataAnalysisTask *) const
Definition: KVDataSet.cpp:157
void cd() const
Definition: KVDataSet.cpp:736
virtual void WriteDBFile(const Char_t *full_path_to_dbfile) const
Definition: KVDataSet.cpp:251
const Char_t * GetFullPathToDB() const
Returns full path to file where database is written on disk.
Definition: KVDataSet.cpp:129
TFile * NewRunfile(const Char_t *type, Int_t run)
Definition: KVDataSet.cpp:1058
virtual Bool_t CheckUserCanAccess()
Definition: KVDataSet.cpp:1356
void SetRepository(KVDataRepository *)
Set pointer to data repository in which dataset is stored.
Definition: KVDataSet.cpp:1387
void CleanMultiRunfiles(const Char_t *data_type, Bool_t confirm=kTRUE)
Definition: KVDataSet.cpp:1463
virtual void OpenDataBase(Option_t *opt="") const
Definition: KVDataSet.cpp:331
virtual void Print(Option_t *opt="") const
Definition: KVDataSet.cpp:420
static Bool_t FindDataSetFile(const TString &dataset, const Char_t *filename)
Definition: KVDataSet.cpp:1921
Bool_t CheckRunfileAvailable(const Char_t *type, Int_t run)
Definition: KVDataSet.cpp:976
Extension of TDatime to handle various useful date formats.
Definition: KVDatime.h:32
Base class to describe database of an experiment ,.
Definition: KVExpDB.h:19
virtual void cd()
Definition: KVExpDB.cpp:548
static KVExpDB * MakeDataBase(const Char_t *name, const Char_t *datasetdir)
Definition: KVExpDB.cpp:570
Extended TList class which owns its objects by default.
Definition: KVList.h:27
Strings used to represent a set of ranges of values.
Definition: KVNumberList.h:83
const Char_t * AsString(Int_t maxchars=0) const
Bool_t End(void) const
Definition: KVNumberList.h:197
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:169
void Add(Int_t)
Add value 'n' to the list.
Bool_t IsEmpty() const
Definition: KVNumberList.h:173
Int_t Next(void) const
Description of an individual run file in an experimental dataset.
Definition: KVRunFile.h:18
Int_t GetRunNumber() const
Definition: KVRunFile.h:34
const Char_t * GetVersion() const
Definition: KVRunFile.h:54
const KVDBRun * GetRun() const
Definition: KVRunFile.h:30
KaliVeda extensions to ROOT collection classes.
virtual TObject * At(Int_t idx) const
virtual TObject * FindObjectAny(const Char_t *att, const Char_t *keys, Bool_t contains_all=kFALSE, Bool_t case_sensitive=kTRUE) const
Extension of ROOT TString class which allows backwards compatibility with ROOT v3....
Definition: KVString.h:72
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()
const char * AsString() const
virtual Bool_t cd(const char *path=nullptr)
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
virtual TObject * FindObject(const char *name) const
virtual TObject * At(Int_t idx) const
virtual const char * GetName() const
virtual const char * GetTitle() const
virtual void SetName(const char *name)
TString & String()
void SetBit(UInt_t f)
R__ALWAYS_INLINE Bool_t IsZombie() const
void ToUpper()
const char * Data() 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)
Bool_t cd(const char *path)
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)
const char * pwd()
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)
const long double cl
Definition: KVUnits.h:85
void Info(const char *location, const char *va_(fmt),...)
void Error(const char *location, const char *va_(fmt),...)
void Warning(const char *location, const char *va_(fmt),...)
const char * String
auto * a