KaliVeda
Toolkit for HIC analysis
KVDataSet.cpp
1 /*
2 $Id: KVDataSet.cpp,v 1.41 2009/03/11 14:22:41 franklan Exp $
3 $Revision: 1.41 $
4 $Date: 2009/03/11 14:22:41 $
5 $Author: franklan $
6 */
7 
8 #include "TMethodCall.h"
9 #include "KVDataSet.h"
10 #include "KVDataRepository.h"
11 #include "KVDataRepositoryManager.h"
12 #include "KVDataSetManager.h"
13 #include "TSystem.h"
14 #include "TObjArray.h"
15 #include "TObjString.h"
16 #include "KVDBSystem.h"
17 #include "KVDBRun.h"
18 #include "TEnv.h"
19 #include "KVAvailableRunsFile.h"
20 #include "KVNumberList.h"
21 #include "TPluginManager.h"
22 #include "TClass.h"
23 #include "KVRunFile.h"
24 
25 using namespace std;
26 
28 
29 KVDataSet* gDataSet;
30 
31 
34 
36 {
37  //Default constructor
38  fRepository = nullptr;
39  fDataBase = nullptr;
40  fAllTasks.SetOwner(kTRUE);
41  fTasks.SetOwner(kFALSE);
42 }
43 
44 
45 
50 
52 {
53  // \param type name of data type ('raw', 'recon', ...)
54  // \returns pointer to available runs file object for given data type
55  // \note if no data repository is associated with dataset, returns nullptr
56  if (!fRepository) return nullptr;
57  KVAvailableRunsFile* avrf =
58  (KVAvailableRunsFile*) fAvailableRuns.FindObjectByName(type);
59  if (!avrf) {
60  avrf = fRepository->NewAvailableRunsFile(type, this);
61  fAvailableRuns.Add(avrf);
62  }
63  return avrf;
64 }
65 
66 
67 
83 
85 {
86  //Returns name of file containing database for dataset.
87  //
88  //This is fixed as `DataBase.root.M.m.p` where
89  // - `M` is the current major version number
90  // - `m` is the current minor version number
91  // - `p` is the current patch number
92  //
93  //(fixed to be consistent with CMake function INSTALL_KALIVEDA_DATASETS which sets up
94  //the Makefile for each dataset which automatically triggers rebuilding of the ROOT file
95  //when source files change: thus we must have the right file name!)
96  //
97  //This in order to avoid problems if several different versions of KaliVeda
98  //use the same working directory (in user's `$HOME/.kaliveda`) to write the
99  //database files, which are often incompatible between versions
100 
101  TString n = "DataBase.root";
102  n.Append(Form(".%d.%d.%d", GetKVMajorVersion(),
103  GetKVMinorVersion(), GetKVPatchVersion()));
104  return n;
105 }
106 
107 
108 
113 
115 {
116  //\returns name of database object in database file.
117  //
118  //If this is not set explicitly with SetDBName(), we use the name of the dataset by default
119 
120  return (fDBName != "" ? fDBName.Data() : GetName());
121 }
122 
123 
124 
125 
128 
129 void KVDataSet::OpenDBFile(const Char_t* full_path_to_dbfile) const
130 {
131  //Open the database from a file on disk.
132 
133  TDirectory* work_dir = gDirectory; //keep pointer to current directory
134  fDBase.reset(new TFile(full_path_to_dbfile, "READ"));
135 
136  if (fDBase->IsOpen()) {
137  fDataBase = dynamic_cast<KVExpDB*>(fDBase->Get(GetDBName()));
138  if (!fDataBase) {
139  Error("OpenDBFile", "%s not found in file %s", GetDBName().Data(),
140  GetDBFileName().Data());
141  }
142  else {
143  fDataBase->ReadObjects(fDBase.get()); // read any associated objects
144  }
145  work_dir->cd(); //back to initial working directory
146  }
147 }
148 
149 
150 
151 
154 
156 {
157  // \returns full path to file where database is written on disk
158 
159  TString dbfile = GetDBFileName();
160  TString dbfile_fullpath;
161  TString tmp;
162 
163  // If this dataset is just an alias for another dataset i.e. if DataSet.Directory
164  // is set with just the name of another dataset (not a full path to dataset files)
165  // then the database file should be written/found under the name of the alias.
166  TString dataset_alias = GetDataSetEnv("DataSet.Directory", GetName());
167  TString db_alias = GetName();
168  if (!gSystem->IsAbsoluteFileName(dataset_alias)) db_alias = dataset_alias;
169 
170  AssignAndDelete(tmp, gSystem->ConcatFileName(GetDATABASEFilePath(), db_alias.Data()));
171  AssignAndDelete(dbfile_fullpath, gSystem->ConcatFileName(tmp.Data(), dbfile.Data()));
172  return dbfile_fullpath;
173 }
174 
175 
176 
179 
181 {
182  //Check configuration variables to see if the task parameters have been "tweaked" for the dataset.
183 
184  KVString envar = GetDataSetEnv(Form("%s.DataAnalysisTask.Title", t->GetName()));
185  if (envar != "") t->SetTitle(envar);
186  envar = GetDataSetEnv(Form("%s.DataAnalysisTask.Analyser", t->GetName()));
187  if (envar != "") t->SetDataAnalyser(envar);
188  envar = GetDataSetEnv(Form("%s.DataAnalysisTask.UserClass.Base", t->GetName()));
189  if (envar != "") t->SetUserBaseClass(envar);
190  envar = GetDataSetEnv(Form("%s.DataAnalysisTask.Prereq", t->GetName()));
191  if (envar != "") t->SetPrereq(envar);
192  envar = GetDataSetEnv(Form("%s.DataAnalysisTask.UserClass.ExtraACliCIncludes", t->GetName()));
193  if (envar != "") t->SetExtraAClicIncludes(envar);
194  Int_t nev = (Int_t)GetDataSetEnv(Form("%s.DataAnalysisTask.StatusUpdateInterval", t->GetName()), 0.0);
195  if (nev > 0) t->SetStatusUpdateInterval(nev);
196 }
197 
198 
199 
200 
204 
206 {
207  // Write the experiment database for this dataset to disk (ROOT file), creating and setting
208  // permissions for any required directories
209 
210  TString dbfile_fullpath = GetFullPathToDB();
211  TString tmp = gSystem->DirName(dbfile_fullpath.Data()); //full path to directory $KVROOT/db/[dataset name]
212 
213  if (gSystem->AccessPathName(tmp.Data())) { // directory $KVROOT/db/[dataset name] does not exist
214 
215  if (gSystem->mkdir(tmp.Data()) == -1) { // problem creating $KVROOT/db/[dataset name]
216 
217  TString tmp2 = gSystem->DirName(tmp.Data());// full path to directory $KVROOT/db
218 
219  if (gSystem->AccessPathName(tmp2.Data())) { // directory $KVROOT/db does not exist
220 
221  if (gSystem->mkdir(tmp2.Data()) == -1) { // problem creating $KVROOT/db
222  Error("SaveDataBase", "Cannot create directory %s required to save database",
223  tmp2.Data());
224  return;
225  }
226  gSystem->Chmod(tmp2.Data(), 0775);
227  }
228  else {
229  Error("SaveDataBase", "Cannot create directory %s required to save database, even though %s exists: check disk space ?",
230  tmp.Data(), tmp2.Data());
231  return;
232  }
233  //try again
234  if (gSystem->mkdir(tmp.Data()) == -1) {
235  Error("SaveDataBase", "Cannot create directory %s required to save database",
236  tmp.Data());
237  return;
238  }
239  else {
240  gSystem->Chmod(tmp.Data(), 0775);
241  }
242  }
243  else {
244  gSystem->Chmod(tmp.Data(), 0775);
245  }
246  }
247 
248  WriteDBFile(dbfile_fullpath.Data());
249 }
250 
251 
252 
253 
256 
257 void KVDataSet::WriteDBFile(const Char_t* full_path_to_dbfile) const
258 {
259  //Write the database to disk.
260 
261  TDirectory* work_dir = gDirectory; //keep pointer to current directory
262  if (!fDataBase) {
263  Error("WriteDBFile", "Database has not been built");
264  return;
265  }
266  fDBase.reset(new TFile(full_path_to_dbfile, "recreate"));
267  fDBase->cd(); //set as current directory (maybe not necessary)
268  fDataBase->Write(GetDBName()); //write database to file with given name
269  fDataBase->WriteObjects(fDBase.get()); //write any associated objects
270  fDBase->Write(); // write file header etc.
271  fDBase->Close(); // close file
272  gSystem->Chmod(full_path_to_dbfile, 0664); // set permissions to rw-rw-r--
273  work_dir->cd(); //back to initial working directory
274 }
275 
276 
277 
289 
291 {
292  //\returns pointer to database associated with this dataset.
293  //
294  //Opens, updates or creates database file if necessary
295  //(the database is automatically rebuilt if the source files are
296  //more recent than the last database file).
297  //
298  //\param[in] opt optional option string:
299  // - if opt="update": force regeneration of the database from source files in dataset directory
300  // - if opt="minimal": if database not built/out of date, only build runs/systems database
301  // - note that both options can be given to force update of minimal database
302 
303  OpenDataBase(opt);
304  return fDataBase;
305 }
306 
307 
308 
320 
321 void KVDataSet::OpenDataBase(const TString& opt) const
322 {
323  //Open the database for this dataset.
324  //
325  //If the database does not exist or is older than the source files
326  //the database is automatically rebuilt (see DataBaseNeedUpdate()).
327  //
328  //\param[in] opt build option
329  //
330  // - if opt="update" we force rebuilding of the database
331  // - if opt="minimal" only a minimal database of runs & systems for the dataset is built
332  // - note that both options can be given to force update of minimal database
333 
334  TString _opt(opt);
335  _opt.ToUpper();
336  auto update = (_opt.Contains("UPDATE"));
337  auto minimal = (_opt.Contains("MINIMAL"));
338 
339  auto rebuild_database = [&]() {
340  Info("OpenDataBase", "Updating database file");
341  fDataBaseUpdateInProgress = true;
342  //check if it is the currently active database (gDataBase),
343  //in which case we must 'cd()' to it after rebuilding
344  auto is_glob_db = (fDataBase == gExpDB);
345  if (fDataBase) {
346  delete fDataBase;
347  fDataBase = 0;
348  }
349  fDataBase = KVExpDB::MakeDataBase(GetDBName(), GetDataSetDir(), minimal);
350  if (!fDataBase) {
351  // no database defined for dataset
352  Info("OpenDataBase", "No database defined for dataset");
353  fDataBaseUpdateInProgress = false;
354  return;
355  }
356  SaveDataBase();
357  if (fDataBase && is_glob_db) fDataBase->cd();
358  fDataBaseUpdateInProgress = false;
359  };
360 
361  if (update || DataBaseNeedsUpdate()) {
362  //if option="update" or database out of date or does not exist, (re)build the database
363  rebuild_database();
364  }
365  else if (!fDataBase) {
366  // if database is not in memory at this point, we need to
367  // open the database file and read in the database
368 
369  //load plugin for database
370  if (!LoadPlugin("KVExpDB", GetDBName())) {
371  Error("GetDataBase", "Cannot load required plugin library");
372  return;
373  }
374  //look for database file in dataset subdirectory
375  TString dbfile_fullpath = GetFullPathToDB();
376  //open database file
377  OpenDBFile(dbfile_fullpath.Data());
378 
379  // if the previously built database was minimal but nobody asked for
380  // a minimal database (=> they want the full monty), we rebuild a full database
381  if (fDataBase && fDataBase->IsMinimal() && !minimal)
382  rebuild_database();
383  }
384  else if (fDataBase && fDataBase->IsMinimal() && !minimal) {
385  // database is already open, but was only a minimal build
386  // now we want the full monty!
387  rebuild_database();
388  }
389 }
390 
391 
392 
393 
396 
398 {
399  //Print dataset information
400  cout << "Dataset name=" << GetName() << " (" << GetTitle() << ")";
401  if (IsAvailable()) {
402  cout << " [ AVAILABLE: ";
403  cout << fDatatypes.Data();
404  cout << "]";
405  }
406  else
407  cout << " [UNAVAILABLE]";
408  cout << endl;
409 }
410 
411 
412 
419 
420 void KVDataSet::Print(Option_t* opt) const
421 {
422  //Print dataset information
423  //
424  //param[in] opt select optional output formats:
425  // - if string contains "tasks", print numbered list of tasks that can be performed
426  // - if string contains "data", print list of available data types
427 
428  TString Sopt(opt);
429  Sopt.ToUpper();
430  if (Sopt.Contains("TASK")) {
431  if (!GetNtasks()) {
432  cout << " *** No available analysis tasks ***"
433  << endl;
434  return;
435  }
436  else {
437  for (int i = 1; i <= GetNtasks(); i++) {
438  KVDataAnalysisTask* dat = GetAnalysisTask(i);
439  cout << "\t" << i << ". " << dat->GetTitle() << endl;
440  }
441  }
442  cout << endl;
443  }
444  else if (Sopt.Contains("DATA")) {
445  cout << "Available data types: " << fDatatypes.Data() << endl;
446  }
447  else {
448  ls(opt);
449  }
450 }
451 
452 
453 
462 
464 {
465  //Check if this data set is physically present and available for analysis.
466  //
467  //In other words we check if the value of GetDataPathSubdir() is a subdirectory
468  //of the current data repository.
469  //If so, we proceed to check for the existence of sudirectories corresponding
470  // to any of the datatypes associated with the dataset.
471  //
472 
473  if (!fRepository) // for a stand-alone KVDataSetManager not linked to a KVDataRepository,
474  SetAvailable(); // all known datasets are 'available'
475  else
476  SetAvailable(fRepository->CheckSubdirExists(GetDataPathSubdir()));
477  if (!IsAvailable())
478  return;
479  //check subdirectories
480  KVString data_types = GetDataSetEnv("KVDataSet.DataTypes", "");
481  if (data_types == "") {
482  Warning("CheckAvailable", "No datatypes defined for this dataset: %s\nCheck value of KVDataSet.DataTypes or %s.KVDataSet.DataTypes",
483  GetName(), GetName());
484  SetAvailable(kFALSE);
485  }
486  fDatatypes = "";
487  // loop over data types
488  data_types.Begin(" ");
489  while (!data_types.End()) {
490  KVString type = data_types.Next(kTRUE);
491  if (!fRepository ||
492  (fRepository && fRepository->CheckSubdirExists(GetDataPathSubdir(), GetDataTypeSubdir(type.Data())))
493  ) {
494  AddAvailableDataType(type.Data());
495  }
496  }
497  //check at least one datatype exists
498  SetAvailable(fDatatypes != "");
499  //check user name against allowed groups
500  if (!CheckUserCanAccess()) {
501  SetAvailable(kFALSE);
502  return;
503  }
504 }
505 
506 
507 
509 
511 {
512  if (fDatatypes != "") fDatatypes += " ";
513  KVString _type = type;
514  _type.Remove(TString::kBoth, ' '); //strip whitespace
515  fDatatypes += _type;
516 }
517 
518 
519 
526 
528 {
529  // Add to fAllTasks list any data analysis task in list 'task_list'
530  //
531  // Add to fTasks list any data analysis task in list 'task_list' whose pre-requisite datatype is present for this dataset.
532  //
533  // Any dataset-specific "tweaking" of the task (including the prerequisite datatype) is done here.
534 
535  TString availables = gEnv->GetValue(Form("%s.DataAnalysisTask", GetName()), "");
536  fAllTasks.Clear();
537  fTasks.Clear();
538  TIter nxt(task_list);
539  KVDataAnalysisTask* dat;
540  while ((dat = (KVDataAnalysisTask*) nxt())) {
541  //make new copy of default analysis task
542  if (availables == "" || availables.Contains(dat->GetName())) {
543  KVDataAnalysisTask* new_task = new KVDataAnalysisTask(*dat);
544  //check if any dataset-specific parameters need to be changed
545  SetDataSetSpecificTaskParameters(new_task);
546  fAllTasks.Add(new_task);
547  // add tasks with available prerequisite data to fTasks
548  if (HasDataType(new_task->GetPrereq())) {
549  fTasks.Add(new_task);
550  }
551  }
552  }
553 }
554 
555 
556 
560 
562 {
563  //Returns the number of tasks associated to dataset which are compatible
564  //with the available data
565 
566  return fTasks.GetSize();
567 }
568 
569 
570 
575 
577 {
578  //Return kth analysis task in list of available tasks.
579  //
580  //\param[in] k task number in range [1, GetNtasks()]. Corresponds to the number shown next to the title of the task when Print("tasks") is called
581  return (KVDataAnalysisTask*) fTasks.At(k - 1);
582 }
583 
584 
585 
590 
592 {
593  //\returns list of available systems for this dataset and the given datatype
594  //
595  //\param[in] datatype type of data
596 
597  if (!GetAvailableRunsFile(datatype)) {
598  Error("GetListOfAvailableSystems(const Char_t*)",
599  "No available runs file for type %s", datatype.Data());
600  return {};
601  }
602  return GetAvailableRunsFile(datatype)->GetListOfAvailableSystems();
603 }
604 
605 
606 
611 
613 {
614  //\returns list of available systems for this dataset and the prerequisite datatype for the given analysis task
615  //
616  //\param[in] datan data analysis task
617 
618  return GetListOfAvailableSystems(datan->GetPrereq());
619 }
620 
621 
622 
630 
632 {
633  //\returns list of available runfiles for this dataset and the given datatype and system.
634  //
635  //\param[in] datatype type of data
636  //\param[in] systol pointer to system
637  //
638  //If no systems are defined for the dataset then we return a list of available runfiles for the given datatype
639 
640  if (!GetAvailableRunsFile(datatype)) {
641  Error("GetListOfAvailableSystems(const Char_t*)",
642  "No available runs file for type %s", datatype.Data());
643  return {};
644  }
645  return GetAvailableRunsFile(datatype)->GetListOfAvailableRunFilesForSystem(systol);
646 }
647 
648 
649 
657 
659 {
660  //\returns list of available runfiles for this dataset, given system, and the prerequisite datatype for the given analysis task
661  //
662  //\param[in] datan data analysis task
663  //\param[in] pointer to system
664  //
665  //If no systems are defined for the dataset then we return a list of available runfiles for the given datatype
666 
667  return GetListOfAvailableRunFilesForSystem(datan->GetPrereq(), systol);
668 }
669 
670 
671 
674 
676 {
677  // \returns the list of systems corresponding to the given list of runfiles & datatype
678 
679  if (!GetAvailableRunsFile(datatype)) {
680  Error("GetSystemsForRunFiles",
681  "No available runs file for type %s", datatype.Data());
682  return {};
683  }
684  return GetAvailableRunsFile(datatype)->GetSystemsForRunFiles(rl);
685 }
686 
687 
688 
709 
710 void KVDataSet::SetName(const char* name)
711 {
712  // Set name of dataset
713  //
714  // Also sets path to directory containing database informations
715  // for this dataset, i.e. list of runs, systems, calibration files etc.
716  //
717  // By default, just the name of the dataset is used, i.e.
718  // `[DATADIR]/name`
719  // (where `DATADIR` = path given by KVBase::GetDATADIRFilePath())
720  //
721  // However, if the variable
722  //~~~
723  // [name].DataSet.Directory: [path]
724  //~~~
725  // has been set, the value of `[path]` will be used:
726  // - if [path] is an absolute path name, it will be used as such
727  // - if [path] is an incomplete or relative path, it will be prepended with `[DATADIR]/`
728  //
729  // This allows to use one dataset as an alias for another, by setting `DataSet.Directory`
730  // to the name of an existing dataset
732  TString path = GetDataSetEnv("DataSet.Directory", name);
733  if (gSystem->IsAbsoluteFileName(path)) fCalibDir = path;
734  else {
735  // in this case (not an absolute path but just the name of another dataset)
736  // this dataset is an alias for another dataset.
737  fCalibDir = GetDATADIRFilePath(path);
738  // the name of the database object is the name of the "true" dataset
739  SetDBName(path);
740  }
741 }
742 
743 
744 
747 
749 {
750  //\returns full path to directory containing database and calibration/identification parameters etc. for this dataset.
751 
752  return fCalibDir.Data();
753 }
754 
755 
756 
769 
770 void KVDataSet::cd() const
771 {
772  // Makes this dataset the "currently active" or default dataset.
773  //
774  //At the same time, the database and data repository associated with
775  //this dataset also become the "currently active" ones:
776  //
777  // | global pointer | represents | base class |
778  // |----------------|------------|------------|
779  // | `gDataSet` | active dataset | KVDataSet |
780  // | `gExpDB` | associated experimental database | KVExpDB |
781  // | `gDataRepository` | repository containing runfiles | KVDataRepository |
782  //
783 
784  gDataSet = const_cast<KVDataSet*>(this);
785  if (fRepository) fRepository->cd();
786  KVExpDB* db = GetDataBase();
787  if (db) db->cd();
788 }
789 
790 
791 
819 
821 {
822  // Open file containing data of given datatype for given run number of this dataset.
823  //
824  // \returns a pointer to the opened file; if the file is not available, we return nullptr.
825  //
826  // The user must cast the returned pointer to the correct class, which will
827  // depend on the data type and the dataset
828  //
829  // **SPECIAL CASE: MFM data with EBYEDAT frames**
830  //
831  // If the variable
832  //
833  //~~~~~~~~~~~~~~~~~~~~~~~~~
834  // [dataset].MFM.WithEbyedat: yes
835  //~~~~~~~~~~~~~~~~~~~~~~~~~
836  //
837  // is set, then we expect to find the necessary `ACTIONS_*` files in the dataset directory
838  // in subdirectory `ebyedat` (they should have the same names as the data files prefixed by
839  // `ACTIONS_[expname].CHC_PAR.`).
840  //
841  // If in addition the variable
842  //
843  //~~~~~~~~~~~~~~~~~~~~~~~~~
844  // [dataset].MFM.EbyedatActionsExpName: [expname]
845  //~~~~~~~~~~~~~~~~~~~~~~~~~
846  //
847  // is set, then we use the same `ACTIONS` file for all runs, with name `ACTIONS_[expname].CHC_PAR`
848 
849 
850  if (!strcmp(type, "raw") && !strcmp(GetDataSetEnv("MFM.WithEbyedat", ""), "yes")) {
851  TString ebydir = GetDataSetDir();
852  ebydir += "/ebyedat";
853  gEnv->SetValue("KVMFMDataFileReader.ActionsDirectory", ebydir);
854  if (strcmp(GetDataSetEnv("MFM.EbyedatActionsExpName", ""), ""))
855  gEnv->SetValue("KVMFMDataFileReader.ActionsExpName", GetDataSetEnv("MFM.EbyedatActionsExpName", ""));
856  TObject* f = GetRepository()->OpenDataSetRunFile(this, type, run, GetName());
857  // reset in case another dataset opens a raw MFM file without EBYEDAT data
858  gEnv->SetValue("KVMFMDataFileReader.ActionsDirectory", "");
859  gEnv->SetValue("KVMFMDataFileReader.ActionsExpName", "");
860  return f;
861  }
862  return GetRepository()->OpenDataSetRunFile(this, type, run, GetName());
863 }
864 
865 
866 
867 
871 
873  const run_index_t& run) const
874 {
875  //\return full path to file containing data of given datatype for given run/index of this dataset
876  // \note only works for available run files, if their is no file in the repository for this run, the returned path will be empty
877 
878  TString file("");
879  if (fRepository) file = GetRunfileName(type, run);
880  if (file == "")
881  return file.Data();
882  return fRepository->GetFullPathToOpenFile(this, type, file.Data());
883 }
884 
885 
886 
887 
891 
893 {
894  //\return name of file containing data of given datatype for given run/index of this dataset
895  //\note only works for available run files, if there is no file in the repository for this run, the returned path will be empty
896 
897  if (!HasDataType(type)) {
898  Error("GetRunfileName",
899  "No data of type \"%s\" available for dataset %s", (const char*)type,
900  GetName());
901  return 0;
902  }
903  //get name of file from available runs file
904  return GetAvailableRunsFile(type)->GetFileName(run);
905 }
906 
907 
908 
909 
915 
916 std::optional<TDatime> KVDataSet::GetRunfileDate(const KVString& type, const run_index_t& run)
917 {
918  //\return date of file containing data of given datatype for given run/index of this dataset
919  //
920  //\note only works for available runfiles, if there is no file in the repository for this run/index,
921  //an error will be printed and std::optional will not contain a value
922 
923  if (!HasDataType(type)) {
924  Error("GetRunfileDate",
925  "No data of type \"%s\" available for dataset %s", (const char*)type,
926  GetName());
927  return std::nullopt;
928  }
929  //get date of file from available runs file
930  TDatime date;
932  if (!GetAvailableRunsFile(type)->GetRunInfo(run, date, filename)) {
933  Error("GetRunfileDate",
934  "Runfile not found for run %d index %d (data type: %s)", run.run(), run.index(), (const char*)type);
935  return std::nullopt;
936  }
937  return date;
938 }
939 
940 
941 
964 
965 std::optional<run_index_t> KVDataSet::GetRunNumberFromFileName(const TString& datatype, const TString& filename)
966 {
967  // \returns run number and eventual index by parsing the name of a runfile for given datatype. if filename does not have correct format, returns std::nullopt
968  //
969  // If the runfile in question was generated using an index multiplier, e.g. if it contains the number
970  // '17001' when the index multiplier defined for the dataset is 1000, we return '17' as the
971  // run number and '1' as the index.
972  //
973  // Usage examples (using global pointer gDataSet to currently 'active' dataset):
974  //~~~{.cpp}
975  //auto run = gDataSet->GetRunNumberFromFileName(filename);
976  //
977  //if(!run) // no value (std::nullopt) returned
978  //{
979  // std::cerr << "Filename " << filename << " is not right format\n";
980  //}
981  //else
982  //{
983  // std::cout << "Filename " << filename << " corresponds to run number " << run.value().run();
984  // if(run.has_index()) std::cout << ", file index = " << run.index();
985  // std::cout << std::endl;
986  //}
987  //~~~
988 
989  auto arf = GetAvailableRunsFile(datatype);
990  auto v = arf->IsRunFileName(filename);
991  if (!v) return v;
992  // if the returned value has a non-null index, there is nothing more to do
993  if (v.value().has_index()) return v;
994  int r = v.value().run();
995  // check if returned run number actually consists of run*multiplier+index
996  auto db = GetDataBase("minimal");
997  if (db->HasIndexMultiplier() && r > db->GetIndexMultiplier()) {
998  r /= db->GetIndexMultiplier();
999  int i = v.value().run() % db->GetIndexMultiplier();
1000  return run_index_t{r, i};
1001  }
1002  return v;
1003 }
1004 
1005 
1006 
1007 
1012 
1014 {
1015  //We check the availability of the run by looking in the available runs file associated
1016  //with the given datatype.
1017 
1018  //check data type is available
1019  if (!HasDataType(type)) {
1020  Error("CheckRunfileAvailable",
1021  "No data of type \"%s\" available for dataset %s", (const char*)type,
1022  GetName());
1023  return 0;
1024  }
1025  return GetAvailableRunsFile(type)->CheckAvailable(run);
1026 }
1027 
1028 
1029 
1030 
1045 
1046 const Char_t* KVDataSet::GetBaseFileName(const Char_t* type, const run_index_t& run) const
1047 {
1048  //PRIVATE METHOD: Returns base name of data file containing data for the run of given datatype.
1049  //The filename corresponds to one of the formats defined in $KVROOT/KVFiles/.kvrootrc
1050  //by variables like:
1051  //
1052  //~~~
1053  //[dataset].DataSet.RunFileName.[type]: run%R.dat
1054  //~~~
1055  //
1056  //%R will be replaced with the run number
1057  //
1058  //IF the format contains '%D' it will be replaced with the current date and time
1059  //
1060  // Any index will be appended at the end: ".index"
1061 
1062  static TString tmp;
1063  //get format string
1064  TString fmt = GetDataSetEnv(Form("DataSet.RunFileName.%s", type));
1065  TString run_num(Form("%d", run.run()));
1066  KVDatime now;
1067  TString date(now.AsSQLString());
1068  tmp = fmt;
1069  tmp.ReplaceAll("%R", run_num);
1070  if (fmt.Contains("%D")) {
1071  tmp.ReplaceAll("%D", date);
1072  }
1073  if (run.has_index()) tmp += Form(".%d", run.index());
1074  return tmp.Data();
1075 }
1076 
1077 
1078 
1079 
1089 
1091 {
1092  //Update list of available runs for given data 'type'
1093  //
1094  //As we never clear the sqlite database of any previously existing runfiles
1095  //beforehand, it is possible that newer versions of said files have been
1096  //added and that we will therefore end up with multiple copies of files in the
1097  //database. Therefore we perform an automatic 'CleanRunfileDataBase' afterwards,
1098  //but only to remove runfiles which no longer physically exist
1099 
1100  //check data type is available
1101  if (!HasDataType(type)) {
1102  Error("UpdateAvailableRuns",
1103  "No data of type \"%s\" available for dataset %s", (const char*)type,
1104  GetName());
1105  }
1106  KVAvailableRunsFile* a = GetAvailableRunsFile(type);
1107  a->Update();
1108  CleanRunfileDataBase(type);
1109 }
1110 
1111 
1112 
1113 
1118 
1120 {
1121  // Create a new runfile for the dataset of given datatype.
1122  // (only if this dataset is associated with a data repository)
1123  // Once the file has been filled, use CommitRunfile to submit it to the repository.
1124 
1125  if (!fRepository) return nullptr;
1126  TString tmp = GetBaseFileName(type, run);
1127  //turn any spaces into "_"
1128  tmp.ReplaceAll(" ", "_");
1129  return fRepository->CreateNewFile(this, type, tmp.Data());
1130 }
1131 
1132 
1133 
1134 
1143 
1144 void KVDataSet::DeleteRunfile(const KVString& type, const run_index_t& run, Bool_t confirm)
1145 {
1146  // Delete the file for the given run/index of data type "type" from the repository.
1147  // By default, confirm=kTRUE, which means that the user will be asked to confirm
1148  // that the file should be deleted. If confirm=kFALSE, no confirmation will be asked
1149  // for and the file will be deleted straight away.
1150  //
1151  // WARNING: this really does DELETE files in the repository, they cannot be
1152  // retrieved once they have been deleted.
1153 
1154  if (!fRepository) return;
1155 
1156  //get name of file to delete
1157  TString filename = GetAvailableRunsFile(type)->GetFileName(run);
1158  if (filename == "") {
1159  Error("DeleteRunfile", "Run %s of type %s does not exist.",
1160  run.as_string().Data(), (const char*)type);
1161  return;
1162  }
1163  //delete file
1164  //prevent accidental deletion of certain types of runfiles
1165  KVString doNotDelete = GetDataSetEnv("DataSet.RunFile.DoNotDelete", "all");
1166  if (doNotDelete == "all" || doNotDelete.Contains(type)) {
1167  Error("DeleteRunFile", "%s files cannot be deleted", (const char*)type);
1168  return;
1169  }
1170  fRepository->DeleteFile(this, type, filename.Data(), confirm);
1171  //was file deleted ? if so, remove entry from available runs file
1172  if (!fRepository->CheckFileStatus(this, type, filename.Data()))
1173  GetAvailableRunsFile(type)->Remove(run);
1174 }
1175 
1176 
1177 
1178 
1190 
1191 void KVDataSet::DeleteRunfiles(const Char_t* type, const run_index_list& nl, Bool_t confirm)
1192 {
1193  // Delete files corresponding to a list of runs/index of data type "type" from the repository.
1194  //
1195  // By default, confirm=kTRUE, which means that the user will be asked to confirm
1196  // that each file should be deleted.
1197  //
1198  // If confirm=kFALSE, no confirmation will be asked for and the file will be deleted straight away.
1199  //
1200  // if "nl" is empty (default value) all runs of the dataset corresponding to the given type will be deleted
1201  //
1202  // WARNING: this really does DELETE files in the repository, they cannot be retrieved once they have been deleted.
1203 
1204  auto NL = nl;
1205  if (NL.IsEmpty()) NL = GetRunList(type);
1206  if (NL.IsEmpty()) return;
1207  for (auto& r : NL)
1208  DeleteRunfile(type, r, confirm);
1209 }
1210 
1211 
1212 
1213 
1221 
1222 run_index_list KVDataSet::GetRunList_DateSelection(const TString& type, const KVUnownedList& systems, std::optional<KVDatime> min_date, std::optional<KVDatime> max_date)
1223 {
1224  // Prints out and returns list of runs after date / time selection
1225  //
1226  // Runs generated between ]min;max[ are selected
1227  // - if min=NULL runs with date <max are selected
1228  // - if max=NULL runs with date >min are selected
1229  // - if max and min are NULL returns empty list
1230 
1231  if (!min_date && !max_date) return {};
1232 
1233  if (min_date) printf("date minimum %s\n", min_date.value().AsString());
1234  if (max_date) printf("date maximum %s\n", max_date.value().AsString());
1235 
1236  run_index_list numb;
1237 
1238  for (auto _sys : systems) {
1239  auto sys = (KVDBSystem*)_sys;
1240  auto lrun = GetListOfAvailableRunFilesForSystem(type, sys);
1241 
1242  for (auto _run : lrun) {
1243  auto run = (KVRunFile*)_run;
1244 
1245  if (min_date && max_date) {
1246  if (min_date.value() < run->GetFileWrittenDatime() && run->GetFileWrittenDatime() < max_date.value()) {
1247  numb.Add(run->GetRunIndex());
1248  }
1249  }
1250  else if (min_date) {
1251  if (min_date.value() < run->GetFileWrittenDatime()) {
1252  numb.Add(run->GetRunIndex());
1253  }
1254  }
1255  else if (max_date) {
1256  if (run->GetFileWrittenDatime() < max_date.value()) {
1257  numb.Add(run->GetRunIndex());
1258  }
1259  }
1260  }
1261  }
1262  return numb;
1263 
1264 }
1265 
1266 
1267 
1268 
1275 
1277 {
1278  // Returns list of runs which are present for data type "base_type" but not for "other_type"
1279  //
1280  // If pointer to system is given, only runs for the system are considered.
1281  //
1282  // If OnlyCol=kTRUE (kFALSE default) only systems with KVDBSystem::IsCollision()=kTRUE are considered
1283 
1284  run_index_list manquant;
1285  auto ll = GetListOfAvailableSystems(ref_type);
1286  if (ll.IsEmpty()) {
1287  //numb.Clear();
1288  Info("GetRunList_StageSelection", "No data available of type \"%s\"", ref_type.Data());
1289  return manquant;
1290  }
1291  if (system && !ll.FindObject(system)) {
1292  Info("GetRunList_StageSelection", "No data available of type \"%s\" for system %s", ref_type.Data(), system->GetName());
1293  return manquant;
1294  }
1295 
1296  Info("GetRunList_StageSelection", "Liste des runs presents dans \"%s\" mais absent dans \"%s\"", ref_type.Data(), type.Data());
1297 
1298  KVDBSystem* sys = 0;
1299 
1300  for (Int_t nl = 0; nl < ll.GetEntries(); nl += 1) {
1301 
1302  sys = (KVDBSystem*)ll.At(nl);
1303  if (system && sys != system) continue;
1304  if (OnlyCol && !sys->IsCollision()) continue;
1305  auto nsys = GetRunList(type, sys);
1306  auto nsys_ref = GetRunList(ref_type, sys);
1307  Int_t nref = nsys_ref.GetNValues();
1308 
1309  nsys_ref.Remove(nsys);
1310 
1311  Info("GetRunList_StageSelection", "\nKVDBSystem : %s --> %d runs manquants sur %d : %s",
1312  sys->GetName(),
1313  nsys_ref.GetNValues(),
1314  nref,
1315  nsys_ref.AsString().Data()
1316  );
1317  manquant.Add(nsys_ref);
1318  }
1319  return manquant;
1320 }
1321 
1322 
1323 
1329 
1330 run_index_list KVDataSet::GetRunList_StageSelection(const TString& type, const TString& ref_type, const KVUnownedList& systems, Bool_t OnlyCol)
1331 {
1332  // \returns list of runfiless which are present for data type "base_type" but not for "other_type"
1333  // for the systems (KVDBSystem pointers) in the list.
1334  //
1335  // If OnlyCol=kTRUE (kFALSE default) only systems with KVDBSystem::IsCollision()=kTRUE are considered
1336 
1337  run_index_list manquant;
1338  auto ll = GetListOfAvailableSystems(ref_type);
1339  if (ll.IsEmpty()) {
1340  //numb.Clear();
1341  Info("GetRunList_StageSelection", "No data available of type \"%s\"", ref_type.Data());
1342  return manquant;
1343  }
1344 
1345  Info("GetRunList_StageSelection", "Liste des runs presents dans \"%s\" mais absent dans \"%s\"", ref_type.Data(), type.Data());
1346 
1347  KVDBSystem* sys = 0;
1348 
1349  for (Int_t nl = 0; nl < ll.GetEntries(); nl += 1) {
1350 
1351  sys = (KVDBSystem*)ll.At(nl);
1352  if (!systems.Contains(sys)) continue;
1353  if (OnlyCol && !sys->IsCollision()) continue;
1354  auto nsys = GetRunList(type, sys);
1355  auto nsys_ref = GetRunList(ref_type, sys);
1356  Int_t nref = nsys_ref.GetNValues();
1357 
1358  nsys_ref.Remove(nsys);
1359 
1360  Info("GetRunList_StageSelection", "\nKVDBSystem : %s --> %d runs manquants sur %d : %s",
1361  sys->GetName(),
1362  nsys_ref.GetNValues(),
1363  nref,
1364  nsys_ref.AsString().Data()
1365  );
1366  manquant.Add(nsys_ref);
1367  }
1368  return manquant;
1369 }
1370 
1371 
1372 
1377 
1379 {
1380  // Returns list of runs of given type that were created with the given version of KaliVeda.
1381  //
1382  // If system!="" then only runs for the given system are considered
1383 
1384  run_index_list runs;
1385  if (sys) {
1386  auto lrun = GetListOfAvailableRunFilesForSystem(type, sys);
1387  TIter next(&lrun);
1388  KVRunFile* run;
1389  while ((run = (KVRunFile*)next())) {
1390  if (!strcmp(run->GetVersion(), version)) runs.Add(run->GetRunIndex());
1391  }
1392  return runs;
1393  }
1394  auto ll = GetListOfAvailableSystems(type);
1395  if (ll.IsEmpty()) {
1396  //numb.Clear();
1397  Info("GetRunList_VersionSelection", "No data available of type \"%s\"", type.Data());
1398  return runs;
1399  }
1400  Int_t nsys = ll.GetEntries();
1401  for (Int_t nl = 0; nl < nsys; nl += 1) {
1402  sys = (KVDBSystem*)ll.At(nl);
1403  auto lrun = GetListOfAvailableRunFilesForSystem(type, sys);
1404  TIter next(&lrun);
1405  KVRunFile* run;
1406  while ((run = (KVRunFile*)next())) {
1407  if (!strcmp(run->GetVersion(), version)) runs.Add(run->GetRunIndex());
1408  }
1409  }
1410  return runs;
1411 }
1412 
1413 
1414 
1419 
1420 void KVDataSet::CommitRunfile(const KVString& type, const run_index_t& run, TFile* file)
1421 {
1422  // Commit a runfile previously created with NewRunfile() to the repository.
1423  // Any previous version of the runfile will be deleted.
1424  // The available runs list for this data 'type' is updated.
1425 
1426  if (!fRepository) return;
1427 
1428  //keep name of file for updating available runs list
1429  TString newfile = gSystem->BaseName(file->GetName());
1430 
1431  fRepository->CommitFile(file, type, this);
1432  //update list of available datatypes of dataset,
1433  //in case this addition has created a new subdirectory
1434  CheckAvailable();
1435  //check if previous version of file exists
1436  //get name of file from available runs file
1437  //note that when the file is the first of a new subdirectory, GetAvailableRunsFile->GetFileName
1438  //will cause the available runs file to be created, and it will contain one entry:
1439  //the new file!
1440  TString oldfile = GetAvailableRunsFile(type)->GetFileName(run);
1441  if (oldfile != "" && oldfile != newfile) {
1442  //delete previous version - no confirmation
1443  fRepository->DeleteFile(this, type, oldfile.Data(),
1444  kFALSE);
1445  //was file deleted ? if so, remove entry from available runs file
1446  if (!fRepository->CheckFileStatus(this, type, oldfile.Data()))
1447  GetAvailableRunsFile(type)->Remove(run);
1448  }
1449  if (oldfile != newfile) {
1450  //add entry for new run in available runs file
1451  GetAvailableRunsFile(type)->Add(run, newfile.Data());
1452  }
1453 }
1454 
1455 
1456 
1457 
1463 
1465 {
1466  //if fUserGroups has been set with SetUserGroups(), we check that the current user's name
1467  //(gSystem->GetUserInfo()->fUser) appears in at least one of the groups in the list.
1468  //Returns kFALSE if user's name is not found in any of the groups.
1469  //if fUserGroups="" (default), we return kTRUE for all users.
1470 
1471  if (fUserGroups == "")
1472  return kTRUE; /* no groups set, all users have access */
1473 
1474  //split into array of group names
1475  unique_ptr<TObjArray> toks(fUserGroups.Tokenize(' '));
1476  TObjString* group_name;
1477  TIter next_name(toks.get());
1478  while ((group_name = (TObjString*) next_name())) {
1479  //for each group_name, we check if the user's name appears in the group
1480  if (!fRepository || (fRepository && fRepository->GetDataSetManager()->
1481  CheckUser(group_name->String().Data()))
1482  ) {
1483  return kTRUE;
1484  }
1485  }
1486  return kFALSE;
1487 }
1488 
1489 
1490 
1491 
1494 
1496 {
1497  //Set pointer to data repository in which dataset is stored
1498  fRepository = dr;
1499 }
1500 
1501 
1502 
1503 
1506 
1508 {
1509  //Get pointer to data repository in which dataset is stored
1510  return fRepository;
1511 }
1512 
1513 
1514 
1515 
1520 
1522 {
1523  //Check all runs for a given datatype and make sure that only one version
1524  //exists for each runfile. If not, we print a report on the runfiles which occur
1525  //multiple times, with the associated date and file name.
1526 
1527  auto doubles = GetAvailableRunsFile(data_type)->CheckMultiRunfiles();
1528  if (doubles.empty()) {
1529  cout << "OK. No runs appear more than once." << endl;
1530  }
1531  else {
1532  cout << "Runs which appear more than once: " << endl << endl;
1533  //print dates and filenames for each run
1534 
1535  for (auto& rr : doubles) {
1536  KVList filenames, dates;
1537 
1538  //get infos for current run
1539  GetAvailableRunsFile(data_type)->GetRunInfos(rr, dates, filenames);
1540 
1541  cout << "Run " << rr << " : " << dates.GetEntries() << " files >>>>>>" << endl;
1542  for (int i = 0; i < dates.GetEntries(); i++) {
1543 
1544  cout << "\t" << ((TObjString*) filenames.At(i))->String().
1545  Data() << "\t" << ((TObjString*) dates.At(i))->String().
1546  Data() << endl;
1547 
1548  }
1549  }
1550  }
1551 }
1552 
1553 
1554 
1555 
1566 
1567 void KVDataSet::CleanMultiRunfiles(const Char_t* data_type, Bool_t confirm)
1568 {
1569  // Check all runs for a given datatype and make sure that only one version
1570  // exists for each run. If not, we print a report on the runfiles which occur
1571  // multiple times, with the associated date and file name, and then we
1572  // destroy all but the most recent version of the file in the repository, and
1573  // update the runlist accordingly.
1574  //
1575  // By default, we ask for confirmation before deleting each file.
1576  //
1577  // Call with confirm=kFALSE to delete WITHOUT CONFIRMATION (DANGER!! WARNING!!!)
1578 
1579  if (!fRepository) return;
1580 
1581  KVAvailableRunsFile* ARF = GetAvailableRunsFile(data_type);
1582  auto doubles = ARF->CheckMultiRunfiles();
1583  if (doubles.empty()) {
1584  cout << "OK. No runs appear more than once." << endl;
1585  }
1586  else {
1587  cout << "Runs which appear more than once: " << endl << endl;
1588  //print dates and filenames for each run
1589 
1590  KVList filenames, dates;
1591  for (auto& rr : doubles) {
1592  //get infos for current run
1593  ARF->GetRunInfos(rr, dates, filenames);
1594  TDatime most_recent("1998-12-25 00:00:00");
1595  Int_t i_most_recent = 0;
1596  cout << "Run " << rr << " : " << dates.GetEntries() << " files >>>>>>" << endl;
1597  for (int i = 0; i < dates.GetEntries(); i++) {
1598  //check if run is most recent
1599  TDatime rundate(((TObjString*) dates.At(i))->String().Data());
1600  if (rundate > most_recent) {
1601  most_recent = rundate;
1602  i_most_recent = i;
1603  }
1604  }
1605  //Now, we loop over the list again, this time we destroy all but the most recent
1606  //version of the runfile
1607  for (int i = 0; i < dates.GetEntries(); i++) {
1608  if (i == i_most_recent) {
1609  cout << "KEEP : ";
1610  }
1611  else {
1612  cout << "DELETE : ";
1613  }
1614  cout << "\t" << ((TObjString*) filenames.At(i))->String().
1615  Data() << "\t" << ((TObjString*) dates.At(i))->String().
1616  Data() << endl;
1617  if (i != i_most_recent) {
1618  //delete file from repository forever and ever
1619  fRepository->DeleteFile(this, data_type,
1620  ((TObjString*) filenames.At(i))->
1621  String().Data(), confirm);
1622  //remove file entry from available runlist
1623  ARF->Remove(rr,
1624  ((TObjString*) filenames.At(i))->String());
1625  }
1626  }
1627  }
1628  }
1629 }
1630 
1631 
1632 
1637 
1639 {
1640  // Similar to CleanMultiRunfiles(), but here the aim is only to remove from the
1641  // sqlite database any runfiles which are no longer physically present in the
1642  // repository i.e. they have already been deleted but our database was not updated.
1643 
1644  if (!fRepository) return;
1645 
1646  Info("CleanRunfileDataBase", "Checking for spurious duplicates (non-existent files)...");
1647 
1648  KVAvailableRunsFile* ARF = GetAvailableRunsFile(data_type);
1649 
1650  auto doubles = ARF->CheckMultiRunfiles();
1651  if (!doubles.empty()) {
1652  for (auto& ri : doubles) {
1653  // for each run/index, get full list of available files
1654  KVList dates, files;
1655  ARF->GetRunInfos(ri, dates, files);
1656  // now check that each file is physically present
1657  for (auto f : files) {
1658  TString fname = dynamic_cast<TObjString*>(f)->GetString();
1659  if (!fRepository->CheckFileStatus(this, data_type, fname)) {
1660  Info("CleanRunfileDataBase", "File %s does not exist : remove from database...", fname.Data());
1661  ARF->Remove(ri, fname);
1662  }
1663  }
1664  }
1665  }
1666  else
1667  Info("CleanRunfileDataBase", "Database is apparently consistent");
1668 }
1669 
1670 
1671 
1672 
1679 
1681  KVDataRepository* other_repos)
1682 {
1683  //Use this method to check whether the file of type "data_type" for run number "run"
1684  //in the data repository "other_repos" is more recent than the file contained in the data
1685  //repository corresponding to this dataset.
1686  //
1687  //Returns kFALSE if file in other repository is more recent.
1688 
1689  if (!other_repos)
1690  return kTRUE;
1691  //get dataset with same name as this one from dataset manager of other repository
1692  KVDataSet* ds = other_repos->GetDataSetManager()->GetDataSet(GetName());
1693  if (!ds) {
1694  Error("CheckRunfileUpToDate",
1695  "Dataset \"%s\" not found in repository \"%s\"", GetName(),
1696  other_repos->GetName());
1697  return kFALSE;
1698  }
1699  //compare dates of the two runfiles
1700  if (GetRunfileDate(data_type, run) < ds->GetRunfileDate(data_type, run))
1701  return kFALSE;
1702  return kTRUE;
1703 }
1704 
1705 
1706 
1707 
1714 
1716  const KVString& other_repos)
1717 {
1718  //Use this method to check whether the file of type "data_type" for run number "run"
1719  //in the data repository "other_repos" is more recent than the file contained in the data
1720  //repository corresponding to this dataset.
1721  //Returns kTRUE if no repository with name "other_repos" exists.
1722  //Returns kFALSE if file in other repository is more recent.
1723 
1724  KVDataRepository* _or =
1725  gDataRepositoryManager->GetRepository(other_repos);
1726  if (_or)
1727  return CheckRunfileUpToDate(data_type, run, _or);
1728  Error("CheckRunfileUpToDate",
1729  "No data repository known with this name : %s", (const char*) other_repos);
1730  return kTRUE;
1731 }
1732 
1733 
1734 
1735 
1739 
1740 void KVDataSet::CheckUpToDate(const Char_t* data_type,
1741  const Char_t* other_repos)
1742 {
1743  //Check whether all files of type "data_type" for run number "run" in the data repository
1744  //are up to date (i.e. at least as recent) as compared to the files in data repository "other_repos".
1745 
1746  if (!fRepository) return;
1747 
1748  KVDataRepository* _or =
1749  gDataRepositoryManager->GetRepository(other_repos);
1750  if (!_or) {
1751  Error("CheckUpToDate",
1752  "No data repository known with this name : %s", other_repos);
1753  return;
1754  }
1755  auto runlist = GetAvailableRunsFile(data_type)->GetRunList();
1756  Int_t need_update = 0;
1757  for (auto& rr : runlist) {
1758  //check run
1759  if (!CheckRunfileUpToDate(data_type, rr, _or)) {
1760  cout << " *** run " << rr << " needs update ***" <<
1761  endl;
1762  cout << "\t\tREPOSITORY: " << fRepository->
1763  GetName() << "\tDATE: " << GetRunfileDate(data_type, rr).value().AsString() << endl;
1764  cout << "\t\tREPOSITORY: " << other_repos << "\tDATE: " << _or->
1765  GetDataSetManager()->GetDataSet(GetName())->
1766  GetRunfileDate(data_type, rr).value().AsString() << endl;
1767  need_update++;
1768  }
1769  }
1770  if (!need_update) {
1771  cout << " *** All runfiles are up to date for data type " <<
1772  data_type << endl;
1773  }
1774 }
1775 
1776 
1777 
1778 
1782 
1784  const Char_t* other_repos)
1785 {
1786  //Returns list of all runs of type "data_type" which may be updated
1787  //from the repository named "other_repos". See CheckUpToDate().
1788 
1789  run_index_list updates;
1790  if (!fRepository) return updates;
1791 
1792  KVDataRepository* _or =
1793  gDataRepositoryManager->GetRepository(other_repos);
1794  if (!_or) {
1795  Error("CheckUpToDate",
1796  "No data repository known with this name : %s", other_repos);
1797  return updates;
1798  }
1799  auto runlist = GetAvailableRunsFile(data_type)->GetRunList();
1800  for (auto& rr : runlist) {
1801  //check run
1802  if (!CheckRunfileUpToDate(data_type, rr, _or)) {
1803  //run is out of date
1804  updates.Add(rr);
1805  }
1806  }
1807  return updates;
1808 }
1809 
1810 
1811 
1812 
1817 
1819  const KVDBSystem* system) const
1820 {
1821  //Returns list of all files available for given "data_type"
1822  //
1823  //If a pointer to a reaction system is given, only files for the given system will be included in the list.
1824 
1825  if (!fRepository || !HasDataType(data_type)) {
1826  Error("GetRunList",
1827  "No data of type %s available. Runlist will be empty.",
1828  data_type);
1829  return {};
1830  }
1831 
1832  return GetAvailableRunsFile(data_type)->GetRunList(system);
1833 }
1834 
1835 
1836 
1837 
1868 
1870 {
1871  //This method returns a pointer to the available analysis task whose description (title) contains
1872  //all of the whitespace-separated keywords (which may be regular expressions)
1873  //given in the string "keywords". The comparison is case-insensitive.
1874  //
1875  //WARNING: this method can only be used to access analysis tasks that are
1876  //available for this dataset, i.e. for which the corresponding prerequisite data type
1877  //is available in the repository.
1878  //For unavailable data/tasks, use GetAnalysisTaskAny(const Char_t*).
1879  //
1880  //EXAMPLES
1881  //Let us suppose that the current dataset has the following list of tasks:
1882  //~~~
1883  // root [2] gDataSet->Print("tasks")
1884  // 1. Event reconstruction from raw data (raw->recon)
1885  // 2. Analysis of raw data
1886  // 3. Identification of reconstructed events (recon->ident)
1887  // 4. Analysis of reconstructed events (recon)
1888  // 5. Analysis of partially identified & calibrated reconstructed events (ident)
1889  // 6. Analysis of fully calibrated physical data (root)
1890  //~~~
1891  //Then the following will occur:
1892  //~~~
1893  // root [14] gDataSet->GetAnalysisTask("raw->recon")->Print()
1894  // KVDataAnalysisTask : Event reconstruction from raw data (raw->recon)
1895  //
1896  // root [10] gDataSet->GetAnalysisTask("analysis root")->Print()
1897  // KVDataAnalysisTask : Analysis of fully calibrated physical data (root)
1898  //~~~
1899 
1900  //case-insensitive search for matches in list based on 'title' attribute
1901  return (KVDataAnalysisTask*)fTasks.FindObjectAny("title", keywords, kTRUE, kFALSE);
1902 }
1903 
1904 
1905 
1906 
1908 
1910 {
1911  if (!dat->WithUserClass()) {
1912  Error("MakeAnalysisClass",
1913  "No user class required for analysis task \"%s\"", dat->GetTitle());
1914  return false;
1915  }
1916 
1917  //all analysis base classes must define a static Make(const Char_t * classname)
1918  //which generates the skeleton class files.
1919 
1920  TClass* cl = nullptr;
1921  //has the user base class for the task been compiled and loaded ?
1923  else
1924  return false;
1925 
1926  //set up call to static Make method
1927  unique_ptr<TMethodCall> methcall(new TMethodCall(cl, "Make", Form("\"%s\"", classname)));
1928 
1929  if (!methcall->IsValid()) {
1930  Error("MakeAnalysisClass", "static Make(const Char_t*) method for class %s is not valid",
1931  cl->GetName());
1932  return false;
1933  }
1934 
1935  //generate skeleton class
1936  methcall->Execute();
1937 
1938  return true;
1939 }
1940 
1941 
1942 
1955 
1956 bool KVDataSet::MakeAnalysisClass(const Char_t* task, const Char_t* classname)
1957 {
1958  //Create a skeleton analysis class to be used for analysis of the data belonging to this dataset.
1959  //
1960  // task = keywords contained in title of analysis task (see GetAnalysisTask(const Char_t*))
1961  // (you do not need to include 'analysis', it is added automatically)
1962  // classname = name of new analysis class
1963  //
1964  //Example:
1965  // MakeAnalysisClass("raw", "MyRawDataAnalysis")
1966  // --> make skeleton raw data analysis class in files MyRawDataAnalysis.cpp & MyRawDataAnalysis.h
1967  // MakeAnalysisClass("fully calibrated", "MyDataAnalysis")
1968  // --> make skeleton data analysis class in files MyDataAnalysis.cpp & MyDataAnalysis.h
1969 
1970  KVString _task = task;
1971  if (!_task.Contains("nalysis")) _task += " analysis";
1972  //We want to be able to write analysis classes even when we don't have any data
1973  //to analyse. Therefore we use GetAnalysisTaskAny.
1974  auto dat = GetAnalysisTaskAny(_task.Data());
1975  if (!dat) {
1976  Error("MakeAnalysisClass",
1977  "called for unknown or unavailable analysis task : %s", _task.Data());
1978  return false;
1979  }
1980  return make_analysis_class(dat, classname);
1981 }
1982 
1983 
1984 
1991 
1992 bool KVDataSet::MakeAnalysisClass(int task, const Char_t* classname)
1993 {
1994  //Create a skeleton analysis class to be used for analysis of the data belonging to this dataset.
1995  //
1996  // task = index of analysis task as shown in KVDataSet::Print("tasks")
1997  // classname = name of new analysis class
1998  //
1999 
2000  auto dat = GetAnalysisTask(task);
2001  if (!dat) {
2002  Error("MakeAnalysisClass",
2003  "called for unknown or unavailable analysis task index : %d", task);
2004  return false;
2005  }
2006  return make_analysis_class(dat, classname);
2007 }
2008 
2009 
2010 
2011 
2015 
2016 Bool_t KVDataSet::OpenDataSetFile(const Char_t* filename, ifstream& file)
2017 {
2018  // Look for (and open for reading, if found) the named file in the directory which
2019  // contains the files for this dataset (given by GetDataSetDir())
2020 
2021  return OpenDataSetFile(GetName(), filename, file);
2022 }
2023 
2024 
2025 
2029 
2030 Bool_t KVDataSet::OpenDataSetFile(const TString& dataset, const Char_t* filename, ifstream& file)
2031 {
2032  // Static method to look for (and open for reading, if found) the named file in the directory which
2033  // contains the files for the dataset
2034 
2035  TString datasetdir = KVBase::GetDataSetEnv(dataset, "DataSet.Directory", dataset);
2036  if (gSystem->IsAbsoluteFileName(datasetdir)) {
2037  // dataset directory is outside of standard KV installation directories
2038  // use absolute path to search for file
2039  TString abspath;
2040  abspath.Form("%s/%s", datasetdir.Data(), filename);
2041  return SearchAndOpenKVFile(abspath, file);
2042  }
2043  // dataset directory is a subdirectory of GetDATADIRFilePath()
2044  return SearchAndOpenKVFile(filename, file, datasetdir);
2045 }
2046 
2047 
2048 
2052 
2054 {
2055  // Find a file in the dataset directory (given by GetDataSetDir())
2056  // Returns full path to file if found, empty string if not
2057 
2058  return GetFullPathToDataSetFile(GetName(), filename);
2059 }
2060 
2061 
2062 
2066 
2068 {
2069  // Static method to find a file in the dataset directory (given by GetDataSetDir())
2070  // Returns full path to file if found, empty string if not
2071 
2072  TString fullpath;
2073  TString datasetdir = KVBase::GetDataSetEnv(dataset, "DataSet.Directory", dataset);
2074  if (!SearchKVFile(filename, fullpath, datasetdir)) {
2075  ::Warning("KVDataSet::GetFullPathToDataSetFile", "File %s not found in dataset subdirectory %s", filename, datasetdir.Data());
2076  fullpath = "";
2077  }
2078  return fullpath;
2079 }
2080 
2081 
2082 
2086 
2087 Bool_t KVDataSet::FindDataSetFile(const TString& dataset, const Char_t* filename)
2088 {
2089  // Static method to find a file in the dataset directory (given by GetDataSetDir())
2090  // Returns kTRUE if found, kFALSE if not
2091 
2092  TString fullpath;
2093  TString datasetdir = KVBase::GetDataSetEnv(dataset, "DataSet.Directory", dataset);
2094  return SearchKVFile(filename, fullpath, datasetdir);
2095 }
2096 
2097 
2098 
2102 
2104 {
2105  // Find a file in the dataset directory (given by GetDataSetDir())
2106  // Returns kTRUE if found, kFALSE if not
2107 
2108  return FindDataSetFile(GetName(), filename);
2109 }
2110 
2111 
2112 
2113 
2122 
2124 {
2125  //This method returns the analysis task whose description (title) contains
2126  //all of the whitespace-separated keywords (which may be regular expressions)
2127  //given in the string "keywords". The comparison is case-insensitive.
2128  //The analysis task does not need to be "available", i.e. the associated prerequisite
2129  //data type does not have to be present in the repository (see GetAnalysisTask).
2130  //
2131  // If no task is found, returns nullptr
2132 
2133  KVDataAnalysisTask* tsk = (KVDataAnalysisTask*)fAllTasks.FindObjectAny("title", keywords, kTRUE, kFALSE);
2134  if (!tsk) {
2135  Error("GetAnalysisTaskAny", "No task found with the following keywords in its title : %s", keywords);
2136  }
2137  return tsk;
2138 }
2139 
2140 
2141 
2142 
2149 
2151 {
2152  // Returns kTRUE if database needs to be regenerated from source files,
2153  // i.e. if source files are more recent than DataBase.root
2154  //
2155  // In case no directory exists for dataset (dataset added 'on the fly')
2156  // we create the directory and fill it with dummy files (Makefile, Runlist.csv, Systems.dat)
2157 
2158  TString pwd = gSystem->pwd();
2159 
2160  TString path = "";
2161  if (!SearchKVFile(GetDataSetDir(), path)) {
2162  // dataset directory doesn't exist - create it
2163  Info("DataBaseNeedsUpdate", "%s: Creating new dataset directory %s",
2164  GetName(), GetDataSetDir());
2165  if (gSystem->mkdir(GetDataSetDir())) {
2166  // problem creating directory
2167  Error("DataBaseNeedsUpdate",
2168  "%s: Dataset directory %s does not exist and cannot be created ?",
2169  GetName(), GetDataSetDir());
2170  return kFALSE;
2171  }
2172  // create dummy files
2173  SearchKVFile(GetDataSetDir(), path); // get full path
2174  path += "/";
2175  TString filename = path + "Makefile";
2176  ofstream of1(filename.Data());
2177  of1 << "$(KV_WORK_DIR)/db/" << GetName() << "/DataBase.root : Runlist.csv Systems.dat" << endl;
2178  of1 << "\t@echo Database needs update" << endl;
2179  of1.close();
2180  filename = path + "Runlist.csv";
2181  ofstream of2(filename.Data());
2182  of2 << "# Automatically generated dummy Runlist.csv file" << endl;
2183  of2.close();
2184  filename = path + "Systems.dat";
2185  ofstream of3(filename.Data());
2186  of3 << "# Automatically generated dummy Systems.dat file" << endl;
2187  of3.close();
2188  }
2189  gSystem->cd(GetDataSetDir());
2190  TString cmd = "make -q";
2191  Int_t ret = gSystem->Exec(cmd.Data());
2192  gSystem->cd(pwd.Data());
2193  return (ret != 0);
2194 }
2195 
2196 
2197 
2214 
2216 {
2217  // Returns name of output repository for given task.
2218  // By default it is the name of the repository associated with this dataset,
2219  // but can be changed by the following environment variables:
2220  //
2221  // [repository].DefaultOutputRepository: [other repository]
2222  // - this means that all tasks carried out on data in [repository]
2223  // will have their output files placed in [other repository]
2224  //
2225  // [taskname].DataAnalysisTask.OutputRepository: [other repository]
2226  // - this means that for [taskname], any output files will
2227  // be placed in [other repository]
2228  //
2229  // [dataset].[taskname].DataAnalysisTask.OutputRepository: [other repository]
2230  // - this means that for given [dataset] & [taskname],
2231  // any output files will be placed in [other repository]
2232 
2233  if (gEnv->Defined(Form("%s.DataRepository.DefaultOutputRepository", GetRepository()->GetName())))
2234  return TString(gEnv->GetValue(Form("%s.DataRepository.DefaultOutputRepository", GetRepository()->GetName()), ""));
2235  TString orep = GetDataSetEnv(Form("%s.DataAnalysisTask.OutputRepository", taskname), GetRepository()->GetName());
2236  return orep;
2237 }
2238 
2239 
2240 
2241 
2244 
2245 void KVDataSet::CopyRunfilesFromRepository(const Char_t* type, const run_index_list& runs, const Char_t* destdir)
2246 {
2247  // Copies the runfiles of given "type" into the local directory "destdir".
2248 
2249  KVDataRepository* repo = GetRepository();
2250  for (auto& run : runs) {
2251  TString filename = GetRunfileName(type, run);
2252  TString destpath;
2253  AssignAndDelete(destpath, gSystem->ConcatFileName(destdir, filename));
2254  repo->CopyFileFromRepository(this, type, filename, destpath);
2255  }
2256 }
2257 
2258 
2259 
2260 
2264 
2265 void KVDataSet::CopyRunfilesToRepository(const Char_t* type, const run_index_list& runs, const Char_t* destrepo)
2266 {
2267  // Copies the runfiles of given "type" from the data repository associated
2268  // with this dataset into the local repository "destrepo".
2269 
2270  KVDataRepository* repo = GetRepository();
2271  KVDataRepository* dest_repo = gDataRepositoryManager->GetRepository(destrepo);
2272 
2273  if (!dest_repo) {
2274  Error("CopyRunfilesToRepository", "Unknown destination repository : %s", destrepo);
2275  gDataRepositoryManager->Print();
2276  return;
2277  }
2278 
2279  KVDataSet* dest_ds = dest_repo->GetDataSetManager()->GetDataSet(GetName());
2280  dest_repo->CreateAllNeededSubdirectories(dest_ds, type);
2281  for (auto& run : runs) {
2282  TString filename = GetRunfileName(type, run);
2283  TString destpath = dest_repo->GetFullPathToTransferFile(dest_ds, type, filename);
2284  repo->CopyFileFromRepository(this, type, filename, destpath);
2285  }
2286 }
2287 
2288 
int Int_t
ROOT::R::TRInterface & r
#define f(i)
bool Bool_t
char Char_t
constexpr Bool_t kFALSE
constexpr Bool_t kTRUE
const char Option_t
#define gDirectory
R__EXTERN TEnv * gEnv
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
char name[80]
char * Form(const char *fmt,...)
void AssignAndDelete(TString &target, char *tobedeleted)
R__EXTERN TSystem * gSystem
Handles lists of available runs for different datasets and types of data.
void GetRunInfos(const run_index_t &run, KVList &dates, KVList &names)
virtual void Remove(const run_index_t &run, const KVString &filename="")
Remove from the db ALL entries corresponding to the given run/index (and filename if given)
std::forward_list< run_index_t > CheckMultiRunfiles()
Returns a list with all run/indexes for which more than one file is in the available runs db.
virtual void Add(const run_index_t &run, const KVString &filename)
static ValType GetDataSetEnv(const KVString &dataset, const KVString &type, const ValType &defval)
Definition: KVBase.h:305
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:128
Define and manage data analysis tasks.
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
virtual Bool_t CheckUserBaseClassIsLoaded() 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)
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:146
std::optional< TDatime > GetRunfileDate(const KVString &type, const run_index_t &run)
Definition: KVDataSet.cpp:916
TString GetFullPathToRunfile(const KVString &type, const run_index_t &run) const
Definition: KVDataSet.cpp:872
TString GetFullPathToDB() const
Definition: KVDataSet.cpp:155
void ls(Option_t *opt="") const override
Print dataset information.
Definition: KVDataSet.cpp:397
TString GetOutputRepository(const Char_t *taskname) const
Definition: KVDataSet.cpp:2215
virtual void OpenDBFile(const Char_t *full_path_to_dbfile) const
Open the database from a file on disk.
Definition: KVDataSet.cpp:129
TString GetDBName() const
Definition: KVDataSet.cpp:114
void CheckMultiRunfiles(const Char_t *data_type)
Definition: KVDataSet.cpp:1521
Bool_t CheckRunfileAvailable(const KVString &type, const run_index_t &run)
Definition: KVDataSet.cpp:1013
virtual const Char_t * GetBaseFileName(const Char_t *type, const run_index_t &run) const
Definition: KVDataSet.cpp:1046
void CleanRunfileDataBase(const Char_t *data_type)
Definition: KVDataSet.cpp:1638
void CheckUpToDate(const Char_t *data_type, const Char_t *other_repos)
Definition: KVDataSet.cpp:1740
run_index_list GetRunList(const Char_t *data_type, const KVDBSystem *sys=0) const
Definition: KVDataSet.cpp:1818
virtual void OpenDataBase(const TString &="") const
Definition: KVDataSet.cpp:321
TString GetFullPathToDataSetFile(const Char_t *filename) const
Definition: KVDataSet.cpp:2053
void CopyRunfilesFromRepository(const Char_t *type, const run_index_list &runs, const Char_t *destdir)
Copies the runfiles of given "type" into the local directory "destdir".
Definition: KVDataSet.cpp:2245
KVDataRepository * GetRepository() const
Get pointer to data repository in which dataset is stored.
Definition: KVDataSet.cpp:1507
run_index_list GetRunList_DateSelection(const TString &type, const KVUnownedList &systems, std::optional< KVDatime > min_date=std::nullopt, std::optional< KVDatime > max_date=std::nullopt)
Definition: KVDataSet.cpp:1222
const Char_t * GetDataSetDir() const
Definition: KVDataSet.cpp:748
void CommitRunfile(const KVString &type, const run_index_t &run, TFile *file)
Definition: KVDataSet.cpp:1420
virtual void AddAvailableDataType(const Char_t *)
Definition: KVDataSet.cpp:510
KVUniqueNameList GetSystemsForRunFiles(const TString &datatype, const run_index_list &) const
Definition: KVDataSet.cpp:675
bool make_analysis_class(const KVDataAnalysisTask *, const Char_t *classname)
Definition: KVDataSet.cpp:1909
KVDataAnalysisTask * GetAnalysisTask(Int_t) const
Definition: KVDataSet.cpp:576
KVAvailableRunsFile * GetAvailableRunsFile(const TString &type) const
Definition: KVDataSet.cpp:51
virtual void SaveDataBase() const
Definition: KVDataSet.cpp:205
virtual KVDataAnalysisTask * GetAnalysisTaskAny(const Char_t *keywords) const
Definition: KVDataSet.cpp:2123
virtual void SetAnalysisTasks(const KVSeqCollection *)
Definition: KVDataSet.cpp:527
TFile * NewRunfile(const KVString &type, const run_index_t &run)
Definition: KVDataSet.cpp:1119
KVList GetListOfAvailableRunFilesForSystem(const TString &datatype, KVDBSystem *systol)
Definition: KVDataSet.cpp:631
Bool_t CheckRunfileUpToDate(const KVString &data_type, const run_index_t &run, KVDataRepository *other_repos)
Definition: KVDataSet.cpp:1680
virtual void CheckAvailable()
Definition: KVDataSet.cpp:463
void DeleteRunfile(const KVString &type, const run_index_t &run, Bool_t confirm=kTRUE)
Definition: KVDataSet.cpp:1144
virtual Int_t GetNtasks() const
Definition: KVDataSet.cpp:561
run_index_list GetRunList_VersionSelection(const TString &type, const TString &version, KVDBSystem *sys=0)
Definition: KVDataSet.cpp:1378
KVExpDB * GetDataBase(const TString &opt="") const
Definition: KVDataSet.cpp:290
void DeleteRunfiles(const Char_t *type, const run_index_list &lrun={}, Bool_t confirm=kTRUE)
Definition: KVDataSet.cpp:1191
TObject * open_runfile(const KVString &type, const run_index_t &run)
Definition: KVDataSet.cpp:820
void CopyRunfilesToRepository(const Char_t *type, const run_index_list &runs, const Char_t *destrepo)
Definition: KVDataSet.cpp:2265
KVString GetRunfileName(const KVString &type, const run_index_t &run) const
Definition: KVDataSet.cpp:892
virtual Bool_t DataBaseNeedsUpdate() const
Definition: KVDataSet.cpp:2150
Bool_t OpenDataSetFile(const Char_t *filename, std::ifstream &file)
void SetDataSetSpecificTaskParameters(KVDataAnalysisTask *) const
Check configuration variables to see if the task parameters have been "tweaked" for the dataset.
Definition: KVDataSet.cpp:180
run_index_list GetRunList_StageSelection(const TString &other_type, const TString &base_type, KVDBSystem *sys=0, Bool_t OnlyCol=kFALSE)
Definition: KVDataSet.cpp:1276
void cd() const
Definition: KVDataSet.cpp:770
virtual void WriteDBFile(const Char_t *full_path_to_dbfile) const
Write the database to disk.
Definition: KVDataSet.cpp:257
void Print(Option_t *opt="") const override
Definition: KVDataSet.cpp:420
void SetName(const char *name) override
Definition: KVDataSet.cpp:710
virtual Bool_t CheckUserCanAccess()
Definition: KVDataSet.cpp:1464
void UpdateAvailableRuns(const KVString &type)
Definition: KVDataSet.cpp:1090
run_index_list GetUpdatableRuns(const Char_t *data_type, const Char_t *other_repos)
Definition: KVDataSet.cpp:1783
void SetRepository(KVDataRepository *)
Set pointer to data repository in which dataset is stored.
Definition: KVDataSet.cpp:1495
bool MakeAnalysisClass(const Char_t *task, const Char_t *classname)
Definition: KVDataSet.cpp:1956
KVDataSet()
Default constructor.
Definition: KVDataSet.cpp:35
std::optional< run_index_t > GetRunNumberFromFileName(const TString &datatype, const TString &filename)
Definition: KVDataSet.cpp:965
void CleanMultiRunfiles(const Char_t *data_type, Bool_t confirm=kTRUE)
Definition: KVDataSet.cpp:1567
static Bool_t FindDataSetFile(const TString &dataset, const Char_t *filename)
Definition: KVDataSet.cpp:2087
KVUnownedList GetListOfAvailableSystems(const TString &datatype)
Definition: KVDataSet.cpp:591
TString GetDBFileName() const
Definition: KVDataSet.cpp:84
Extension of TDatime to handle various useful date formats.
Definition: KVDatime.h:33
Base class to describe database of an experiment ,,.
Definition: KVExpDB.h:61
virtual void cd()
Definition: KVExpDB.cpp:757
static KVExpDB * MakeDataBase(const Char_t *name, const Char_t *datasetdir, Bool_t minimal=false)
Definition: KVExpDB.cpp:778
Extended TList class which owns its objects by default.
Definition: KVList.h:22
Description of an individual data file in an experimental dataset.
Definition: KVRunFile.h:19
const Char_t * GetVersion() const
Definition: KVRunFile.h:84
const run_index_t & GetRunIndex() const
Definition: KVRunFile.h:56
KaliVeda extensions to ROOT collection classes.
TObject * At(Int_t idx) const override
Extension of ROOT TString class which allows backwards compatibility with ROOT v3....
Definition: KVString.h:73
void Begin(TString delim) const
Definition: KVString.cpp:565
Bool_t End() const
Definition: KVString.cpp:634
KVString Next(Bool_t strip_whitespace=kFALSE) const
Definition: KVString.cpp:695
Optimised list in which named objects can only be placed once.
Extended TList class which does not own its objects by default.
Definition: KVUnownedList.h:20
static TClass * GetClass(Bool_t load=kTRUE, Bool_t silent=kFALSE)
virtual Int_t GetEntries() const
Bool_t Contains(const char *name) const
const char * AsSQLString() const
virtual Bool_t cd()
virtual const char * GetValue(const char *name, const char *dflt) const
virtual void SetValue(const char *name, const char *value, EEnvLevel level=kEnvChange, const char *type=nullptr)
Bool_t Defined(const char *name) const
TObject * FindObject(const char *name) const override
virtual void SetTitle(const char *title="")
const char * GetName() const override
const char * GetTitle() const override
virtual void SetName(const char *name)
TString & String()
const char * Data() const
void ToUpper()
void Form(const char *fmt,...)
TString & Remove(EStripType s, char c)
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
TString & ReplaceAll(const char *s1, const char *s2)
Bool_t cd(const char *path)
const char * pwd()
virtual int Chmod(const char *file, UInt_t mode)
virtual const char * DirName(const char *pathname)
virtual char * ConcatFileName(const char *dir, const char *name)
virtual int mkdir(const char *name, Bool_t recursive=kFALSE)
virtual Int_t Exec(const char *shellcmd)
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
virtual const char * BaseName(const char *pathname)
virtual Bool_t IsAbsoluteFileName(const char *dir)
List of runfiles specified by run number and file index ,.
Int_t GetEntries() const
void Add(const run_index_t &r)
Specifies a runfile according to run number and file index ,.
Definition: run_index.h:31
int run() const
Definition: run_index.h:50
TString as_string() const
Definition: run_index.h:95
int index(int no_index=-1) const
Definition: run_index.h:55
bool has_index() const
Definition: run_index.h:59
const Int_t n
void Error(const char *location, const char *fmt,...)
void Info(const char *location, const char *fmt,...)
void Warning(const char *location, const char *fmt,...)
void update(const LAYERDATA &prevLayerData, LAYERDATA &currLayerData, double factorWeightDecay, EnumRegularization regularization)
const char * String
v
TArc a
ClassImp(TPyArg)