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