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 "KVDataSetRepository.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  fAllTasks.SetOwner(kTRUE);
39  fTasks.SetOwner(kFALSE);
40 }
41 
42 
43 
48 
50 {
51  // \param type name of data type ('raw', 'recon', ...)
52  // \returns pointer to available runs file object for given data type
53  // \note if no data repository is associated with dataset, returns nullptr
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 
81 
83 {
84  //Returns name of file containing database for dataset.
85  //
86  //This is fixed as `DataBase.root.M.m.p` where
87  // - `M` is the current major version number
88  // - `m` is the current minor version number
89  // - `p` is the current patch number
90  //
91  //(fixed to be consistent with CMake function INSTALL_KALIVEDA_DATASETS which sets up
92  //the Makefile for each dataset which automatically triggers rebuilding of the ROOT file
93  //when source files change: thus we must have the right file name!)
94  //
95  //This in order to avoid problems if several different versions of KaliVeda
96  //use the same working directory (in user's `$HOME/.kaliveda`) to write the
97  //database files, which are often incompatible between versions
98 
99  TString n = "DataBase.root";
100  n.Append(Form(".%d.%d.%d", GetKVMajorVersion(),
101  GetKVMinorVersion(), GetKVPatchVersion()));
102  return n;
103 }
104 
105 
106 
111 
113 {
114  //\returns name of database object in database file.
115  //
116  //If this is not set explicitly with SetDBName(), we use the name of the dataset by default
117 
118  return (fDBName != "" ? fDBName.Data() : GetName());
119 }
120 
121 
122 
123 
126 
127 void KVDataSet::OpenDBFile(const Char_t* full_path_to_dbfile) const
128 {
129  //Open the database from a file on disk.
130 
131  TDirectory* work_dir = gDirectory; //keep pointer to current directory
132  fDBase.reset(new TFile(full_path_to_dbfile, "READ"));
133 
134  if (fDBase->IsOpen()) {
135  fDataBase = dynamic_cast<KVExpDB*>(fDBase->Get(GetDBName()));
136  if (!fDataBase) {
137  KVError::Error(this, "OpenDBFile", "%s not found in file %s", GetDBName().Data(),
138  GetDBFileName().Data());
139  }
140  else {
141  fDataBase->ReadObjects(fDBase.get()); // read any associated objects
142  }
143  work_dir->cd(); //back to initial working directory
144  }
145 }
146 
147 
148 
149 
152 
154 {
155  // \returns full path to file where database is written on disk
156 
157  TString dbfile = GetDBFileName();
158  TString dbfile_fullpath;
159  TString tmp;
160 
161  // If this dataset is just an alias for another dataset i.e. if DataSet.Directory
162  // is set with just the name of another dataset (not a full path to dataset files)
163  // then the database file should be written/found under the name of the alias.
164  TString dataset_alias = GetDataSetEnv("DataSet.Directory", GetName());
165  TString db_alias = GetName();
166  if (!gSystem->IsAbsoluteFileName(dataset_alias)) db_alias = dataset_alias;
167 
168  AssignAndDelete(tmp, gSystem->ConcatFileName(GetDATABASEFilePath(), db_alias.Data()));
169  AssignAndDelete(dbfile_fullpath, gSystem->ConcatFileName(tmp.Data(), dbfile.Data()));
170  return dbfile_fullpath;
171 }
172 
173 
174 
177 
179 {
180  //Check configuration variables to see if the task parameters have been "tweaked" for the dataset.
181 
182  auto envar = GetDataSetEnv<KVString>(Form("%s.DataAnalysisTask.Title", t->GetName()));
183  if (envar != "") t->SetTitle(envar);
184  envar = GetDataSetEnv<KVString>(Form("%s.DataAnalysisTask.Analyser", t->GetName()));
185  if (envar != "") t->SetDataAnalyser(envar);
186  envar = GetDataSetEnv<KVString>(Form("%s.DataAnalysisTask.UserClass.Base", t->GetName()));
187  if (envar != "") t->SetUserBaseClass(envar);
188  envar = GetDataSetEnv<KVString>(Form("%s.DataAnalysisTask.Prereq", t->GetName()));
189  if (envar != "") t->SetPrereq(envar);
190  envar = GetDataSetEnv<KVString>(Form("%s.DataAnalysisTask.UserClass.ExtraACliCIncludes", t->GetName()));
191  if (envar != "") t->SetExtraAClicIncludes(envar);
192  auto nev = GetDataSetEnv<int>(Form("%s.DataAnalysisTask.StatusUpdateInterval", t->GetName()));
193  if (nev > 0) t->SetStatusUpdateInterval(nev);
194 }
195 
196 
197 
198 
202 
204 {
205  // Write the experiment database for this dataset to disk (ROOT file), creating and setting
206  // permissions for any required directories
207 
208  TString dbfile_fullpath = GetFullPathToDB();
209  TString tmp = gSystem->DirName(dbfile_fullpath.Data()); //full path to directory $KVROOT/db/[dataset name]
210 
211  if (gSystem->AccessPathName(tmp.Data())) { // directory $KVROOT/db/[dataset name] does not exist
212 
213  if (gSystem->mkdir(tmp.Data()) == -1) { // problem creating $KVROOT/db/[dataset name]
214 
215  TString tmp2 = gSystem->DirName(tmp.Data());// full path to directory $KVROOT/db
216 
217  if (gSystem->AccessPathName(tmp2.Data())) { // directory $KVROOT/db does not exist
218 
219  if (gSystem->mkdir(tmp2.Data()) == -1) { // problem creating $KVROOT/db
220  KVError::Error(this, "SaveDataBase", "Cannot create directory %s required to save database",
221  tmp2.Data());
222  return;
223  }
224  gSystem->Chmod(tmp2.Data(), 0775);
225  }
226  else {
227  KVError::Error(this, "SaveDataBase", "Cannot create directory %s required to save database, even though %s exists: check disk space ?",
228  tmp.Data(), tmp2.Data());
229  return;
230  }
231  //try again
232  if (gSystem->mkdir(tmp.Data()) == -1) {
233  KVError::Error(this, "SaveDataBase", "Cannot create directory %s required to save database",
234  tmp.Data());
235  return;
236  }
237  else {
238  gSystem->Chmod(tmp.Data(), 0775);
239  }
240  }
241  else {
242  gSystem->Chmod(tmp.Data(), 0775);
243  }
244  }
245 
246  WriteDBFile(dbfile_fullpath.Data());
247 }
248 
249 
250 
251 
254 
255 void KVDataSet::WriteDBFile(const Char_t* full_path_to_dbfile) const
256 {
257  //Write the database to disk.
258 
259  TDirectory* work_dir = gDirectory; //keep pointer to current directory
260  if (!fDataBase) {
261  KVError::Error(this, "WriteDBFile", "Database has not been built");
262  return;
263  }
264  fDBase.reset(new TFile(full_path_to_dbfile, "recreate"));
265  fDBase->cd(); //set as current directory (maybe not necessary)
266  fDataBase->Write(GetDBName()); //write database to file with given name
267  fDataBase->WriteObjects(fDBase.get()); //write any associated objects
268  fDBase->Write(); // write file header etc.
269  fDBase->Close(); // close file
270  gSystem->Chmod(full_path_to_dbfile, 0664); // set permissions to rw-rw-r--
271  work_dir->cd(); //back to initial working directory
272 }
273 
274 
275 
287 
289 {
290  //\returns pointer to database associated with this dataset.
291  //
292  //Opens, updates or creates database file if necessary
293  //(the database is automatically rebuilt if the source files are
294  //more recent than the last database file).
295  //
296  //\param[in] opt optional option string:
297  // - if opt="update": force regeneration of the database from source files in dataset directory
298  // - if opt="minimal": if database not built/out of date, only build runs/systems database
299  // - note that both options can be given to force update of minimal database
300 
301  OpenDataBase(opt);
302  return fDataBase;
303 }
304 
305 
306 
318 
319 void KVDataSet::OpenDataBase(const TString& opt) const
320 {
321  //Open the database for this dataset.
322  //
323  //If the database does not exist or is older than the source files
324  //the database is automatically rebuilt (see DataBaseNeedUpdate()).
325  //
326  //\param[in] opt build option
327  //
328  // - if opt="update" we force rebuilding of the database
329  // - if opt="minimal" only a minimal database of runs & systems for the dataset is built
330  // - note that both options can be given to force update of minimal database
331 
332  TString _opt(opt);
333  _opt.ToUpper();
334  auto update = (_opt.Contains("UPDATE"));
335  auto minimal = (_opt.Contains("MINIMAL"));
336 
337  auto rebuild_database = [&](bool start_from_minimal = false) {
338  start_from_minimal = false;//never start from minimal
339  if(start_from_minimal)
340  Info("OpenDataBase", "Updating existing minimal database...");
341  else
342  {
343  if(minimal)
344  Info("OpenDataBase", "Creating a new minimal database...");
345  else
346  Info("OpenDataBase", "Creating a new full database...");
347  }
348 
349  fDataBaseUpdateInProgress = true;
350  //check if it is the currently active database (gDataBase),
351  //in which case we must 'cd()' to it after rebuilding
352  auto is_glob_db = (fDataBase == gExpDB);
353  if(!start_from_minimal)
354  {
355  if (fDataBase) {
356  delete fDataBase;
357  fDataBase = 0;
358  }
359  fDataBase = KVExpDB::MakeDataBase(GetDBName(), GetDataSetDir(), minimal);
360  if (!fDataBase) {
361  // no database defined for dataset
362  Info("OpenDataBase", "No database defined for dataset");
363  fDataBaseUpdateInProgress = false;
364  return;
365  }
366  }
367  else
368  fDataBase->CompleteDataBase();
369  SaveDataBase();
370  if (fDataBase && is_glob_db) fDataBase->cd();
371  fDataBaseUpdateInProgress = false;
372  };
373 
374  if (update || DataBaseNeedsUpdate()) {
375  //if option="update" or database out of date or does not exist, (re)build the database
376  rebuild_database();
377  }
378  else if (!fDataBase) {
379  // if database is not in memory at this point, we need to
380  // open the database file and read in the database
381 
382  //load plugin for database
383  if (!LoadPlugin("KVExpDB", GetDBName())) {
384  KVError::Error(this, "GetDataBase", "Cannot load required plugin library");
385  return;
386  }
387  //look for database file in dataset subdirectory
388  TString dbfile_fullpath = GetFullPathToDB();
389  //open database file
390  OpenDBFile(dbfile_fullpath.Data());
391 
392  // if the previously built database was minimal but nobody asked for
393  // a minimal database (=> they want the full monty), we rebuild a full database
394  if (fDataBase && fDataBase->IsMinimal() && !minimal)
395  rebuild_database(true);
396  }
397  else if (fDataBase && fDataBase->IsMinimal() && !minimal) {
398  // database is already open, but was only a minimal build
399  // now we want the full monty!
400  rebuild_database(true);
401  }
402 }
403 
404 
405 
406 
409 
411 {
412  //Print dataset information
413  cout << "Dataset name=" << GetName() << " (" << GetTitle() << ")";
414  if (IsAvailable()) {
415  cout << " [ AVAILABLE: ";
416  cout << fDatatypes.Data();
417  cout << "]";
418  }
419  else
420  cout << " [UNAVAILABLE]";
421  cout << endl;
422 }
423 
424 
425 
432 
433 void KVDataSet::Print(Option_t* opt) const
434 {
435  //Print dataset information
436  //
437  //param[in] opt select optional output formats:
438  // - if string contains "tasks", print numbered list of tasks that can be performed
439  // - if string contains "data", print list of available data types
440 
441  TString Sopt(opt);
442  Sopt.ToUpper();
443  if (Sopt.Contains("TASK")) {
444  if (!GetNtasks()) {
445  cout << " *** No available analysis tasks ***"
446  << endl;
447  return;
448  }
449  else {
450  for (int i = 1; i <= GetNtasks(); i++) {
451  KVDataAnalysisTask* dat = GetAnalysisTask(i);
452  cout << "\t" << i << ". " << dat->GetTitle() << endl;
453  }
454  }
455  cout << endl;
456  }
457  else if (Sopt.Contains("DATA")) {
458  cout << "Available data types: " << fDatatypes.Data() << endl;
459  }
460  else {
461  ls(opt);
462  }
463 }
464 
465 
466 
475 
477 {
478  //Check if this data set is physically present and available for analysis.
479  //
480  //In other words we check if the value of GetDataPathSubdir() is a subdirectory
481  //of the current data repository.
482  //If so, we proceed to check for the existence of sudirectories corresponding
483  // to any of the datatypes associated with the dataset.
484  //
485 
486  if (!fRepository) // for a stand-alone KVDataSetManager not linked to a KVDataRepository,
487  SetAvailable(); // all known datasets are 'available'
488  else
489  SetAvailable(fRepository->CheckSubdirExists(GetDataPathSubdir()));
490  if (!IsAvailable())
491  return;
492  //check subdirectories
493  auto data_types = GetDataSetEnv<KVString>("KVDataSet.DataTypes");
494  if (data_types == "") {
495  KVError::Warning(this, "CheckAvailable", "No datatypes defined for this dataset: %s\nCheck value of KVDataSet.DataTypes or %s.KVDataSet.DataTypes",
496  GetName(), GetName());
497  SetAvailable(kFALSE);
498  }
499  fDatatypes = "";
500  // loop over data types
501  data_types.Begin(" ");
502  while (!data_types.End()) {
503  KVString type = data_types.Next(kTRUE);
504  if (!fRepository ||
505  (fRepository && fRepository->CheckSubdirExists(GetDataPathSubdir(), GetDataTypeSubdir(type.Data())))
506  ) {
507  AddAvailableDataType(type.Data());
508  }
509  }
510  //check at least one datatype exists
511  SetAvailable(fDatatypes != "");
512 }
513 
514 
515 
517 
519 {
520  if (fDatatypes != "") fDatatypes += " ";
521  KVString _type = type;
522  _type.Remove(TString::kBoth, ' '); //strip whitespace
523  fDatatypes += _type;
524 }
525 
526 
527 
534 
536 {
537  // Add to fAllTasks list any data analysis task in list 'task_list'
538  //
539  // Add to fTasks list any data analysis task in list 'task_list' whose pre-requisite datatype is present for this dataset.
540  //
541  // Any dataset-specific "tweaking" of the task (including the prerequisite datatype) is done here.
542 
543  TString availables = gEnv->GetValue(Form("%s.DataAnalysisTask", GetName()), "");
544  fAllTasks.Clear();
545  fTasks.Clear();
546  TIter nxt(task_list);
547  KVDataAnalysisTask* dat;
548  while ((dat = (KVDataAnalysisTask*) nxt())) {
549  //make new copy of default analysis task
550  if (availables == "" || availables.Contains(dat->GetName())) {
551  KVDataAnalysisTask* new_task = new KVDataAnalysisTask(*dat);
552  //check if any dataset-specific parameters need to be changed
553  SetDataSetSpecificTaskParameters(new_task);
554  fAllTasks.Add(new_task);
555  // add tasks with available prerequisite data to fTasks
556  if (HasDataType(new_task->GetPrereq())) {
557  fTasks.Add(new_task);
558  }
559  }
560  }
561 }
562 
563 
564 
568 
570 {
571  //Returns the number of tasks associated to dataset which are compatible
572  //with the available data
573 
574  return fTasks.GetSize();
575 }
576 
577 
578 
583 
585 {
586  //Return kth analysis task in list of available tasks.
587  //
588  //\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
589  return (KVDataAnalysisTask*) fTasks.At(k - 1);
590 }
591 
592 
593 
598 
600 {
601  //\returns list of available systems for this dataset and the given datatype
602  //
603  //\param[in] datatype type of data
604 
605  if (!GetAvailableRunsFile(datatype)) {
606  KVError::Error(this, "GetListOfAvailableSystems(const Char_t*)",
607  "No available runs file for type %s", datatype.Data());
608  return {};
609  }
610  return GetAvailableRunsFile(datatype)->GetListOfAvailableSystems();
611 }
612 
613 
614 
619 
621 {
622  //\returns list of available systems for this dataset and the prerequisite datatype for the given analysis task
623  //
624  //\param[in] datan data analysis task
625 
626  return GetListOfAvailableSystems(datan->GetPrereq());
627 }
628 
629 
630 
638 
640 {
641  //\returns list of available runfiles for this dataset and the given datatype and system.
642  //
643  //\param[in] datatype type of data
644  //\param[in] systol pointer to system
645  //
646  //If no systems are defined for the dataset then we return a list of available runfiles for the given datatype
647 
648  if (!GetAvailableRunsFile(datatype)) {
649  KVError::Error(this, "GetListOfAvailableSystems(const Char_t*)",
650  "No available runs file for type %s", datatype.Data());
651  return {};
652  }
653  return GetAvailableRunsFile(datatype)->GetListOfAvailableRunFilesForSystem(systol);
654 }
655 
656 
657 
665 
667 {
668  //\returns list of available runfiles for this dataset, given system, and the prerequisite datatype for the given analysis task
669  //
670  //\param[in] datan data analysis task
671  //\param[in] pointer to system
672  //
673  //If no systems are defined for the dataset then we return a list of available runfiles for the given datatype
674 
675  return GetListOfAvailableRunFilesForSystem(datan->GetPrereq(), systol);
676 }
677 
678 
679 
682 
684 {
685  // \returns the list of systems corresponding to the given list of runfiles & datatype
686 
687  if (!GetAvailableRunsFile(datatype)) {
688  KVError::Error(this, "GetSystemsForRunFiles",
689  "No available runs file for type %s", datatype.Data());
690  return {};
691  }
692  return GetAvailableRunsFile(datatype)->GetSystemsForRunFiles(rl);
693 }
694 
695 
696 
717 
718 void KVDataSet::SetName(const char* name)
719 {
720  // Set name of dataset
721  //
722  // Also sets path to directory containing database informations
723  // for this dataset, i.e. list of runs, systems, calibration files etc.
724  //
725  // By default, just the name of the dataset is used, i.e.
726  // `[DATADIR]/name`
727  // (where `DATADIR` = path given by KVBase::GetDATADIRFilePath())
728  //
729  // However, if the variable
730  //~~~
731  // [name].DataSet.Directory: [path]
732  //~~~
733  // has been set, the value of `[path]` will be used:
734  // - if [path] is an absolute path name, it will be used as such
735  // - if [path] is an incomplete or relative path, it will be prepended with `[DATADIR]/`
736  //
737  // This allows to use one dataset as an alias for another, by setting `DataSet.Directory`
738  // to the name of an existing dataset
740  TString path = GetDataSetEnv("DataSet.Directory", name);
741  if (gSystem->IsAbsoluteFileName(path)) fCalibDir = path;
742  else {
743  // in this case (not an absolute path but just the name of another dataset)
744  // this dataset is an alias for another dataset.
745  fCalibDir = GetDATADIRFilePath(path);
746  // the name of the database object is the name of the "true" dataset
747  SetDBName(path);
748  }
749 }
750 
751 
752 
755 
757 {
758  //\returns full path to directory containing database and calibration/identification parameters etc. for this dataset.
759 
760  return fCalibDir.Data();
761 }
762 
763 
764 
777 
778 void KVDataSet::cd() const
779 {
780  // Makes this dataset the "currently active" or default dataset.
781  //
782  //At the same time, the database and data repository associated with
783  //this dataset also become the "currently active" ones:
784  //
785  // | global pointer | represents | base class |
786  // |----------------|------------|------------|
787  // | `gDataSet` | active dataset | KVDataSet |
788  // | `gExpDB` | associated experimental database | KVExpDB |
789  // | `gDataRepository` | repository containing runfiles | KVDataRepository |
790  //
791 
792  gDataSet = const_cast<KVDataSet*>(this);
793  if (fRepository) fRepository->cd();
794  KVExpDB* db = GetDataBase();
795  if (db) db->cd();
796 }
797 
798 
799 
827 
829 {
830  // Open file containing data of given datatype for given run number of this dataset.
831  //
832  // \returns a pointer to the opened file; if the file is not available, we return nullptr.
833  //
834  // The user must cast the returned pointer to the correct class, which will
835  // depend on the data type and the dataset
836  //
837  // **SPECIAL CASE: MFM data with EBYEDAT frames**
838  //
839  // If the variable
840  //
841  //~~~~~~~~~~~~~~~~~~~~~~~~~
842  // [dataset].MFM.WithEbyedat: yes
843  //~~~~~~~~~~~~~~~~~~~~~~~~~
844  //
845  // is set, then we expect to find the necessary `ACTIONS_*` files in the dataset directory
846  // in subdirectory `ebyedat` (they should have the same names as the data files prefixed by
847  // `ACTIONS_[expname].CHC_PAR.`).
848  //
849  // If in addition the variable
850  //
851  //~~~~~~~~~~~~~~~~~~~~~~~~~
852  // [dataset].MFM.EbyedatActionsExpName: [expname]
853  //~~~~~~~~~~~~~~~~~~~~~~~~~
854  //
855  // is set, then we use the same `ACTIONS` file for all runs, with name `ACTIONS_[expname].CHC_PAR`
856 
857  if (!GetRepository()) return nullptr;
858 
859  auto file_open = [&](const TString & fpth) {
860  return file_opener(type, fpth, GetName());
861  };
862 
863  if (type=="raw" && GetDataSetEnv<KVString>("MFM.WithEbyedat")=="yes") {
864  TString ebydir = GetDataSetDir();
865  ebydir += "/ebyedat";
866  gEnv->SetValue("KVMFMDataFileReader.ActionsDirectory", ebydir);
867  if (GetDataSetEnv<KVString>("MFM.EbyedatActionsExpName")!="")
868  gEnv->SetValue("KVMFMDataFileReader.ActionsExpName", GetDataSetEnv<KVString>("MFM.EbyedatActionsExpName"));
869  TObject* f = GetRepository()->OpenFile(GetRunfileName(type, run), file_open, GetDataPathSubdir(), GetDataTypeSubdir(type));
870  // reset in case another dataset opens a raw MFM file without EBYEDAT data
871  gEnv->SetValue("KVMFMDataFileReader.ActionsDirectory", "");
872  gEnv->SetValue("KVMFMDataFileReader.ActionsExpName", "");
873  return f;
874  }
875  return GetRepository()->OpenFile(GetRunfileName(type, run), file_open, GetDataPathSubdir(), GetDataTypeSubdir(type));
876 }
877 
878 
879 
880 
884 
886  const run_index_t& run) const
887 {
888  //\return full path to file containing data of given datatype for given run/index of this dataset
889  // \note only works for available run files, if their is no file in the repository for this run, the returned path will be empty
890 
891  TString file("");
892  if (fRepository) file = GetRunfileName(type, run);
893  if (file == "")
894  return file.Data();
895  return fRepository->GetFullPathToOpenFile(file, GetDataPathSubdir(), GetDataTypeSubdir(type));
896 }
897 
898 
899 
900 
904 
906 {
907  //\return name of file containing data of given datatype for given run/index of this dataset
908  //\note only works for available run files, if there is no file in the repository for this run, the returned path will be empty
909 
910  if (!HasDataType(type)) {
911  KVError::Error(this, "GetRunfileName",
912  "No data of type \"%s\" available for dataset %s", (const char*)type,
913  GetName());
914  return 0;
915  }
916  //get name of file from available runs file
917  return GetAvailableRunsFile(type)->GetFileName(run);
918 }
919 
920 
921 
922 
928 
929 std::optional<TDatime> KVDataSet::GetRunfileDate(const KVString& type, const run_index_t& run)
930 {
931  //\return date of file containing data of given datatype for given run/index of this dataset
932  //
933  //\note only works for available runfiles, if there is no file in the repository for this run/index,
934  //an error will be printed and std::optional will not contain a value
935 
936  if (!HasDataType(type)) {
937  KVError::Error(this, "GetRunfileDate",
938  "No data of type \"%s\" available for dataset %s", (const char*)type,
939  GetName());
940  return std::nullopt;
941  }
942  //get date of file from available runs file
943  TDatime date;
945  if (!GetAvailableRunsFile(type)->GetRunInfo(run, date, filename)) {
946  KVError::Error(this, "GetRunfileDate",
947  "Runfile not found for run %d index %d (data type: %s)", run.run(), run.index(), (const char*)type);
948  return std::nullopt;
949  }
950  return date;
951 }
952 
953 
954 
977 
978 std::optional<run_index_t> KVDataSet::GetRunNumberFromFileName(const TString& datatype, const TString& filename)
979 {
980  // \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
981  //
982  // If the runfile in question was generated using an index multiplier, e.g. if it contains the number
983  // '17001' when the index multiplier defined for the dataset is 1000, we return '17' as the
984  // run number and '1' as the index.
985  //
986  // Usage examples (using global pointer gDataSet to currently 'active' dataset):
987  //~~~{.cpp}
988  //auto run = gDataSet->GetRunNumberFromFileName(filename);
989  //
990  //if(!run) // no value (std::nullopt) returned
991  //{
992  // std::cerr << "Filename " << filename << " is not right format\n";
993  //}
994  //else
995  //{
996  // std::cout << "Filename " << filename << " corresponds to run number " << run.value().run();
997  // if(run.has_index()) std::cout << ", file index = " << run.index();
998  // std::cout << std::endl;
999  //}
1000  //~~~
1001 
1002  auto arf = GetAvailableRunsFile(datatype);
1003  auto v = arf->IsRunFileName(filename);
1004  if (!v) return v;
1005  // if the returned value has a non-null index, there is nothing more to do
1006  if (v.value().has_index()) return v;
1007  int r = v.value().run();
1008  // check if returned run number actually consists of run*multiplier+index
1009  auto db = GetDataBase("minimal");
1010  if (db->HasIndexMultiplier() && r > db->GetIndexMultiplier()) {
1011  r /= db->GetIndexMultiplier();
1012  int i = v.value().run() % db->GetIndexMultiplier();
1013  return run_index_t{r, i};
1014  }
1015  return v;
1016 }
1017 
1018 
1019 
1020 
1025 
1027 {
1028  //We check the availability of the run by looking in the available runs file associated
1029  //with the given datatype.
1030 
1031  //check data type is available
1032  if (!HasDataType(type)) {
1033  KVError::Error(this, "CheckRunfileAvailable",
1034  "No data of type \"%s\" available for dataset %s", (const char*)type,
1035  GetName());
1036  return 0;
1037  }
1038  return GetAvailableRunsFile(type)->CheckAvailable(run);
1039 }
1040 
1041 
1042 
1043 
1058 
1060 {
1061  //PRIVATE METHOD: Returns base name of data file containing data for the run of given datatype.
1062  //The filename corresponds to one of the formats defined in $KVROOT/KVFiles/.kvrootrc
1063  //by variables like:
1064  //
1065  //~~~
1066  //[dataset].DataSet.RunFileName.[type]: run%R.dat
1067  //~~~
1068  //
1069  //%R will be replaced with the run number
1070  //
1071  //IF the format contains '%D' it will be replaced with the current date and time
1072  //
1073  // Any index will be appended at the end: ".index"
1074 
1075  TString tmp;
1076  //get format string
1077  auto fmt = GetDataSetEnv<TString>(Form("DataSet.RunFileName.%s", type));
1078  TString run_num(Form("%d", run.run()));
1079  KVDatime now;
1080  TString date(now.AsSQLString());
1081  tmp = fmt;
1082  tmp.ReplaceAll("%R", run_num);
1083  if (fmt.Contains("%D")) {
1084  tmp.ReplaceAll("%D", date);
1085  }
1086  if (run.has_index()) tmp += Form(".%d", run.index());
1087  return tmp;
1088 }
1089 
1090 
1091 
1092 
1102 
1104 {
1105  //Update list of available runs for given data 'type'
1106  //
1107  //As we never clear the sqlite database of any previously existing runfiles
1108  //beforehand, it is possible that newer versions of said files have been
1109  //added and that we will therefore end up with multiple copies of files in the
1110  //database. Therefore we perform an automatic 'CleanRunfileDataBase' afterwards,
1111  //but only to remove runfiles which no longer physically exist
1112 
1113  //check data type is available
1114  if (!HasDataType(type)) {
1115  KVError::Error(this, "UpdateAvailableRuns",
1116  "No data of type \"%s\" available for dataset %s", (const char*)type,
1117  GetName());
1118  }
1119  KVAvailableRunsFile* a = GetAvailableRunsFile(type);
1120  a->Update();
1121  CleanRunfileDataBase(type);
1122 }
1123 
1124 
1125 
1126 
1131 
1133 {
1134  // Create a new runfile for the dataset of given datatype.
1135  // (only if this dataset is associated with a data repository)
1136  // Once the file has been filled, use CommitRunfile to submit it to the repository.
1137 
1138  if (!fRepository) return nullptr;
1139  TString tmp = GetBaseFileName(type, run);
1140  //turn any spaces into "_"
1141  tmp.ReplaceAll(" ", "_");
1142  return fRepository->CreateNewFile(this, type, tmp.Data());
1143 }
1144 
1145 
1146 
1147 
1156 
1157 void KVDataSet::DeleteRunfile(const KVString& type, const run_index_t& run, Bool_t confirm)
1158 {
1159  // Delete the file for the given run/index of data type "type" from the repository.
1160  // By default, confirm=kTRUE, which means that the user will be asked to confirm
1161  // that the file should be deleted. If confirm=kFALSE, no confirmation will be asked
1162  // for and the file will be deleted straight away.
1163  //
1164  // WARNING: this really does DELETE files in the repository, they cannot be
1165  // retrieved once they have been deleted.
1166 
1167  if (!fRepository) return;
1168 
1169  //get name of file to delete
1170  TString filename = GetAvailableRunsFile(type)->GetFileName(run);
1171  if (filename == "") {
1172  KVError::Error(this, "DeleteRunfile", "Run %s of type %s does not exist.",
1173  run.as_string().Data(), (const char*)type);
1174  return;
1175  }
1176  //delete file
1177  //prevent accidental deletion of certain types of runfiles
1178  auto doNotDelete = GetDataSetEnv<KVString>("DataSet.RunFile.DoNotDelete", "all");
1179  if (doNotDelete == "all" || doNotDelete.Contains(type)) {
1180  KVError::Error(this, "DeleteRunFile", "%s files cannot be deleted", (const char*)type);
1181  return;
1182  }
1183  fRepository->DeleteFile(this, type, filename, confirm);
1184  //was file deleted ? if so, remove entry from available runs file
1185  if (!fRepository->CheckFileStatus(this, type, filename.Data()))
1186  GetAvailableRunsFile(type)->Remove(run);
1187 }
1188 
1189 
1190 
1191 
1203 
1204 void KVDataSet::DeleteRunfiles(const Char_t* type, const run_index_list& nl, Bool_t confirm)
1205 {
1206  // Delete files corresponding to a list of runs/index of data type "type" from the repository.
1207  //
1208  // By default, confirm=kTRUE, which means that the user will be asked to confirm
1209  // that each file should be deleted.
1210  //
1211  // If confirm=kFALSE, no confirmation will be asked for and the file will be deleted straight away.
1212  //
1213  // if "nl" is empty (default value) all runs of the dataset corresponding to the given type will be deleted
1214  //
1215  // WARNING: this really does DELETE files in the repository, they cannot be retrieved once they have been deleted.
1216 
1217  auto NL = nl;
1218  if (NL.IsEmpty()) NL = GetRunList(type);
1219  if (NL.IsEmpty()) return;
1220  for (auto& r : NL)
1221  DeleteRunfile(type, r, confirm);
1222 }
1223 
1224 
1225 
1226 
1234 
1235 run_index_list KVDataSet::GetRunList_DateSelection(const TString& type, const KVUnownedList& systems, std::optional<KVDatime> min_date, std::optional<KVDatime> max_date)
1236 {
1237  // Prints out and returns list of runs after date / time selection
1238  //
1239  // Runs generated between ]min;max[ are selected
1240  // - if min=NULL runs with date <max are selected
1241  // - if max=NULL runs with date >min are selected
1242  // - if max and min are NULL returns empty list
1243 
1244  if (!min_date && !max_date) return {};
1245 
1246  if (min_date) printf("date minimum %s\n", min_date.value().AsString());
1247  if (max_date) printf("date maximum %s\n", max_date.value().AsString());
1248 
1249  run_index_list numb;
1250 
1251  for (auto _sys : systems) {
1252  auto sys = (KVDBSystem*)_sys;
1253  auto lrun = GetListOfAvailableRunFilesForSystem(type, sys);
1254 
1255  for (auto _run : lrun) {
1256  auto run = (KVRunFile*)_run;
1257 
1258  if (min_date && max_date) {
1259  if (min_date.value() < run->GetFileWrittenDatime() && run->GetFileWrittenDatime() < max_date.value()) {
1260  numb.Add(run->GetRunIndex());
1261  }
1262  }
1263  else if (min_date) {
1264  if (min_date.value() < run->GetFileWrittenDatime()) {
1265  numb.Add(run->GetRunIndex());
1266  }
1267  }
1268  else if (max_date) {
1269  if (run->GetFileWrittenDatime() < max_date.value()) {
1270  numb.Add(run->GetRunIndex());
1271  }
1272  }
1273  }
1274  }
1275  return numb;
1276 
1277 }
1278 
1279 
1280 
1281 
1288 
1290 {
1291  // Returns list of runs which are present for data type "base_type" but not for "other_type"
1292  //
1293  // If pointer to system is given, only runs for the system are considered.
1294  //
1295  // If OnlyCol=kTRUE (kFALSE default) only systems with KVDBSystem::IsCollision()=kTRUE are considered
1296 
1297  run_index_list manquant;
1298  auto ll = GetListOfAvailableSystems(ref_type);
1299  if (ll.IsEmpty()) {
1300  //numb.Clear();
1301  Info("GetRunList_StageSelection", "No data available of type \"%s\"", ref_type.Data());
1302  return manquant;
1303  }
1304  if (system && !ll.FindObject(system)) {
1305  Info("GetRunList_StageSelection", "No data available of type \"%s\" for system %s", ref_type.Data(), system->GetName());
1306  return manquant;
1307  }
1308 
1309  Info("GetRunList_StageSelection", "Liste des runs presents dans \"%s\" mais absent dans \"%s\"", ref_type.Data(), type.Data());
1310 
1311  KVDBSystem* sys = 0;
1312 
1313  for (Int_t nl = 0; nl < ll.GetEntries(); nl += 1) {
1314 
1315  sys = (KVDBSystem*)ll.At(nl);
1316  if (system && sys != system) continue;
1317  if (OnlyCol && !sys->IsCollision()) continue;
1318  auto nsys = GetRunList(type, sys);
1319  auto nsys_ref = GetRunList(ref_type, sys);
1320  Int_t nref = nsys_ref.GetNValues();
1321 
1322  nsys_ref.Remove(nsys);
1323 
1324  Info("GetRunList_StageSelection", "\nKVDBSystem : %s --> %d runs manquants sur %d : %s",
1325  sys->GetName(),
1326  nsys_ref.GetNValues(),
1327  nref,
1328  nsys_ref.AsString().Data()
1329  );
1330  manquant.Add(nsys_ref);
1331  }
1332  return manquant;
1333 }
1334 
1335 
1336 
1342 
1343 run_index_list KVDataSet::GetRunList_StageSelection(const TString& type, const TString& ref_type, const KVUnownedList& systems, Bool_t OnlyCol)
1344 {
1345  // \returns list of runfiless which are present for data type "base_type" but not for "other_type"
1346  // for the systems (KVDBSystem pointers) in the list.
1347  //
1348  // If OnlyCol=kTRUE (kFALSE default) only systems with KVDBSystem::IsCollision()=kTRUE are considered
1349 
1350  run_index_list manquant;
1351  auto ll = GetListOfAvailableSystems(ref_type);
1352  if (ll.IsEmpty()) {
1353  //numb.Clear();
1354  Info("GetRunList_StageSelection", "No data available of type \"%s\"", ref_type.Data());
1355  return manquant;
1356  }
1357 
1358  Info("GetRunList_StageSelection", "Liste des runs presents dans \"%s\" mais absent dans \"%s\"", ref_type.Data(), type.Data());
1359 
1360  KVDBSystem* sys = 0;
1361 
1362  for (Int_t nl = 0; nl < ll.GetEntries(); nl += 1) {
1363 
1364  sys = (KVDBSystem*)ll.At(nl);
1365  if (!systems.Contains(sys)) continue;
1366  if (OnlyCol && !sys->IsCollision()) continue;
1367  auto nsys = GetRunList(type, sys);
1368  auto nsys_ref = GetRunList(ref_type, sys);
1369  Int_t nref = nsys_ref.GetNValues();
1370 
1371  nsys_ref.Remove(nsys);
1372 
1373  Info("GetRunList_StageSelection", "\nKVDBSystem : %s --> %d runs manquants sur %d : %s",
1374  sys->GetName(),
1375  nsys_ref.GetNValues(),
1376  nref,
1377  nsys_ref.AsString().Data()
1378  );
1379  manquant.Add(nsys_ref);
1380  }
1381  return manquant;
1382 }
1383 
1384 
1385 
1390 
1392 {
1393  // Returns list of runs of given type that were created with the given version of KaliVeda.
1394  //
1395  // If system!="" then only runs for the given system are considered
1396 
1397  run_index_list runs;
1398  if (sys) {
1399  auto lrun = GetListOfAvailableRunFilesForSystem(type, sys);
1400  TIter next(&lrun);
1401  KVRunFile* run;
1402  while ((run = (KVRunFile*)next())) {
1403  if (!strcmp(run->GetVersion(), version)) runs.Add(run->GetRunIndex());
1404  }
1405  return runs;
1406  }
1407  auto ll = GetListOfAvailableSystems(type);
1408  if (ll.IsEmpty()) {
1409  //numb.Clear();
1410  Info("GetRunList_VersionSelection", "No data available of type \"%s\"", type.Data());
1411  return runs;
1412  }
1413  Int_t nsys = ll.GetEntries();
1414  for (Int_t nl = 0; nl < nsys; nl += 1) {
1415  sys = (KVDBSystem*)ll.At(nl);
1416  auto lrun = GetListOfAvailableRunFilesForSystem(type, sys);
1417  TIter next(&lrun);
1418  KVRunFile* run;
1419  while ((run = (KVRunFile*)next())) {
1420  if (!strcmp(run->GetVersion(), version)) runs.Add(run->GetRunIndex());
1421  }
1422  }
1423  return runs;
1424 }
1425 
1426 
1427 
1432 
1433 void KVDataSet::CommitRunfile(const KVString& type, const run_index_t& run, TFile* file)
1434 {
1435  // Commit a runfile previously created with NewRunfile() to the repository.
1436  // Any previous version of the runfile will be deleted.
1437  // The available runs list for this data 'type' is updated.
1438 
1439  if (!fRepository) return;
1440 
1441  //keep name of file for updating available runs list
1442  TString newfile = gSystem->BaseName(file->GetName());
1443 
1444  fRepository->CommitFile(file, type, this);
1445  //update list of available datatypes of dataset,
1446  //in case this addition has created a new subdirectory
1447  CheckAvailable();
1448  //check if previous version of file exists
1449  //get name of file from available runs file
1450  //note that when the file is the first of a new subdirectory, GetAvailableRunsFile->GetFileName
1451  //will cause the available runs file to be created, and it will contain one entry:
1452  //the new file!
1453  TString oldfile = GetAvailableRunsFile(type)->GetFileName(run);
1454  if (oldfile != "" && oldfile != newfile) {
1455  //delete previous version - no confirmation
1456  fRepository->DeleteFile(this, type, oldfile.Data(),
1457  kFALSE);
1458  //was file deleted ? if so, remove entry from available runs file
1459  if (!fRepository->CheckFileStatus(this, type, oldfile.Data()))
1460  GetAvailableRunsFile(type)->Remove(run);
1461  }
1462  if (oldfile != newfile) {
1463  //add entry for new run in available runs file
1464  GetAvailableRunsFile(type)->Add(run, newfile.Data());
1465  }
1466 }
1467 
1468 
1469 
1470 
1473 
1475 {
1476  //Set pointer to data repository in which dataset is stored
1477  fRepository = dr;
1478 }
1479 
1480 
1481 
1482 
1485 
1487 {
1488  //Get pointer to data repository in which dataset is stored
1489  return fRepository;
1490 }
1491 
1492 
1493 
1494 
1499 
1501 {
1502  //Check all runs for a given datatype and make sure that only one version
1503  //exists for each runfile. If not, we print a report on the runfiles which occur
1504  //multiple times, with the associated date and file name.
1505 
1506  auto doubles = GetAvailableRunsFile(data_type)->CheckMultiRunfiles();
1507  if (doubles.empty()) {
1508  cout << "OK. No runs appear more than once." << endl;
1509  }
1510  else {
1511  cout << "Runs which appear more than once: " << endl << endl;
1512  //print dates and filenames for each run
1513 
1514  for (auto& rr : doubles) {
1515  KVList filenames, dates;
1516 
1517  //get infos for current run
1518  GetAvailableRunsFile(data_type)->GetRunInfos(rr, dates, filenames);
1519 
1520  cout << "Run " << rr << " : " << dates.GetEntries() << " files >>>>>>" << endl;
1521  for (int i = 0; i < dates.GetEntries(); i++) {
1522 
1523  cout << "\t" << ((TObjString*) filenames.At(i))->String().
1524  Data() << "\t" << ((TObjString*) dates.At(i))->String().
1525  Data() << endl;
1526 
1527  }
1528  }
1529  }
1530 }
1531 
1532 
1533 
1534 
1545 
1546 void KVDataSet::CleanMultiRunfiles(const Char_t* data_type, Bool_t confirm)
1547 {
1548  // Check all runs for a given datatype and make sure that only one version
1549  // exists for each run. If not, we print a report on the runfiles which occur
1550  // multiple times, with the associated date and file name, and then we
1551  // destroy all but the most recent version of the file in the repository, and
1552  // update the runlist accordingly.
1553  //
1554  // By default, we ask for confirmation before deleting each file.
1555  //
1556  // Call with confirm=kFALSE to delete WITHOUT CONFIRMATION (DANGER!! WARNING!!!)
1557 
1558  if (!fRepository) return;
1559 
1560  KVAvailableRunsFile* ARF = GetAvailableRunsFile(data_type);
1561  auto doubles = ARF->CheckMultiRunfiles();
1562  if (doubles.empty()) {
1563  cout << "OK. No runs appear more than once." << endl;
1564  }
1565  else {
1566  cout << "Runs which appear more than once: " << endl << endl;
1567  //print dates and filenames for each run
1568 
1569  KVList filenames, dates;
1570  for (auto& rr : doubles) {
1571  //get infos for current run
1572  ARF->GetRunInfos(rr, dates, filenames);
1573  TDatime most_recent("1998-12-25 00:00:00");
1574  Int_t i_most_recent = 0;
1575  cout << "Run " << rr << " : " << dates.GetEntries() << " files >>>>>>" << endl;
1576  for (int i = 0; i < dates.GetEntries(); i++) {
1577  //check if run is most recent
1578  TDatime rundate(((TObjString*) dates.At(i))->String().Data());
1579  if (rundate > most_recent) {
1580  most_recent = rundate;
1581  i_most_recent = i;
1582  }
1583  }
1584  //Now, we loop over the list again, this time we destroy all but the most recent
1585  //version of the runfile
1586  for (int i = 0; i < dates.GetEntries(); i++) {
1587  if (i == i_most_recent) {
1588  cout << "KEEP : ";
1589  }
1590  else {
1591  cout << "DELETE : ";
1592  }
1593  cout << "\t" << ((TObjString*) filenames.At(i))->String().
1594  Data() << "\t" << ((TObjString*) dates.At(i))->String().
1595  Data() << endl;
1596  if (i != i_most_recent) {
1597  //delete file from repository forever and ever
1598  fRepository->DeleteFile(this, data_type,
1599  ((TObjString*) filenames.At(i))->
1600  String().Data(), confirm);
1601  //remove file entry from available runlist
1602  ARF->Remove(rr,
1603  ((TObjString*) filenames.At(i))->String());
1604  }
1605  }
1606  }
1607  }
1608 }
1609 
1610 
1611 
1616 
1618 {
1619  // Similar to CleanMultiRunfiles(), but here the aim is only to remove from the
1620  // sqlite database any runfiles which are no longer physically present in the
1621  // repository i.e. they have already been deleted but our database was not updated.
1622 
1623  if (!fRepository) return;
1624 
1625  Info("CleanRunfileDataBase", "Checking for spurious duplicates (non-existent files)...");
1626 
1627  KVAvailableRunsFile* ARF = GetAvailableRunsFile(data_type);
1628 
1629  auto doubles = ARF->CheckMultiRunfiles();
1630  if (!doubles.empty()) {
1631  for (auto& ri : doubles) {
1632  // for each run/index, get full list of available files
1633  KVList dates, files;
1634  ARF->GetRunInfos(ri, dates, files);
1635  // now check that each file is physically present
1636  for (auto f : files) {
1637  TString fname = dynamic_cast<TObjString*>(f)->GetString();
1638  if (!fRepository->CheckFileStatus(this, data_type, fname)) {
1639  Info("CleanRunfileDataBase", "File %s does not exist : remove from database...", fname.Data());
1640  ARF->Remove(ri, fname);
1641  }
1642  }
1643  }
1644  }
1645  else
1646  Info("CleanRunfileDataBase", "Database is apparently consistent");
1647 }
1648 
1649 
1650 
1651 
1658 
1660  KVDataSetRepository* other_repos)
1661 {
1662  //Use this method to check whether the file of type "data_type" for run number "run"
1663  //in the data repository "other_repos" is more recent than the file contained in the data
1664  //repository corresponding to this dataset.
1665  //
1666  //Returns kFALSE if file in other repository is more recent.
1667 
1668  if (!other_repos)
1669  return kTRUE;
1670  //get dataset with same name as this one from dataset manager of other repository
1671  KVDataSet* ds = other_repos->GetDataSetManager()->GetDataSet(GetName());
1672  if (!ds) {
1673  KVError::Error(this, "CheckRunfileUpToDate",
1674  "Dataset \"%s\" not found in repository \"%s\"", GetName(),
1675  other_repos->GetName());
1676  return kFALSE;
1677  }
1678  //compare dates of the two runfiles
1679  if (GetRunfileDate(data_type, run) < ds->GetRunfileDate(data_type, run))
1680  return kFALSE;
1681  return kTRUE;
1682 }
1683 
1684 
1685 
1686 
1693 
1695  const KVString& other_repos)
1696 {
1697  //Use this method to check whether the file of type "data_type" for run number "run"
1698  //in the data repository "other_repos" is more recent than the file contained in the data
1699  //repository corresponding to this dataset.
1700  //Returns kTRUE if no repository with name "other_repos" exists.
1701  //Returns kFALSE if file in other repository is more recent.
1702 
1703  auto _or = gDataRepositoryManager->GetRepository(other_repos);
1704  if (_or)
1705  return CheckRunfileUpToDate(data_type, run, _or);
1706  KVError::Error(this, "CheckRunfileUpToDate",
1707  "No data repository known with this name : %s", (const char*) other_repos);
1708  return kTRUE;
1709 }
1710 
1711 
1712 
1713 
1717 
1718 void KVDataSet::CheckUpToDate(const Char_t* data_type,
1719  const Char_t* other_repos)
1720 {
1721  //Check whether all files of type "data_type" for run number "run" in the data repository
1722  //are up to date (i.e. at least as recent) as compared to the files in data repository "other_repos".
1723 
1724  if (!fRepository) return;
1725 
1726  auto _or =
1727  dynamic_cast<KVDataSetRepository*>(gDataRepositoryManager->GetRepository(other_repos));
1728  if (!_or) {
1729  KVError::Error(this, "CheckUpToDate",
1730  "No data repository known with this name : %s", other_repos);
1731  return;
1732  }
1733  auto runlist = GetAvailableRunsFile(data_type)->GetRunList();
1734  Int_t need_update = 0;
1735  for (auto& rr : runlist) {
1736  //check run
1737  if (!CheckRunfileUpToDate(data_type, rr, _or)) {
1738  cout << " *** run " << rr << " needs update ***" <<
1739  endl;
1740  cout << "\t\tREPOSITORY: " << fRepository->
1741  GetName() << "\tDATE: " << GetRunfileDate(data_type, rr).value().AsString() << endl;
1742  cout << "\t\tREPOSITORY: " << other_repos << "\tDATE: " << _or->
1743  GetDataSetManager()->GetDataSet(GetName())->
1744  GetRunfileDate(data_type, rr).value().AsString() << endl;
1745  need_update++;
1746  }
1747  }
1748  if (!need_update) {
1749  cout << " *** All runfiles are up to date for data type " <<
1750  data_type << endl;
1751  }
1752 }
1753 
1754 
1755 
1756 
1760 
1762  const Char_t* other_repos)
1763 {
1764  //Returns list of all runs of type "data_type" which may be updated
1765  //from the repository named "other_repos". See CheckUpToDate().
1766 
1767  run_index_list updates;
1768  if (!fRepository) return updates;
1769 
1770  auto _or = gDataRepositoryManager->GetRepository(other_repos);
1771  if (!_or) {
1772  KVError::Error(this, "CheckUpToDate",
1773  "No data repository known with this name : %s", other_repos);
1774  return updates;
1775  }
1776  auto runlist = GetAvailableRunsFile(data_type)->GetRunList();
1777  for (auto& rr : runlist) {
1778  //check run
1779  if (!CheckRunfileUpToDate(data_type, rr, _or)) {
1780  //run is out of date
1781  updates.Add(rr);
1782  }
1783  }
1784  return updates;
1785 }
1786 
1787 
1788 
1789 
1794 
1796  const KVDBSystem* system) const
1797 {
1798  //Returns list of all files available for given "data_type"
1799  //
1800  //If a pointer to a reaction system is given, only files for the given system will be included in the list.
1801 
1802  if (!fRepository || !HasDataType(data_type)) {
1803  KVError::Error(this, "GetRunList",
1804  "No data of type %s available. Runlist will be empty.",
1805  data_type);
1806  return {};
1807  }
1808 
1809  return GetAvailableRunsFile(data_type)->GetRunList(system);
1810 }
1811 
1812 
1813 
1814 
1845 
1847 {
1848  //This method returns a pointer to the available analysis task whose description (title) contains
1849  //all of the whitespace-separated keywords (which may be regular expressions)
1850  //given in the string "keywords". The comparison is case-insensitive.
1851  //
1852  //WARNING: this method can only be used to access analysis tasks that are
1853  //available for this dataset, i.e. for which the corresponding prerequisite data type
1854  //is available in the repository.
1855  //For unavailable data/tasks, use GetAnalysisTaskAny(const Char_t*).
1856  //
1857  //EXAMPLES
1858  //Let us suppose that the current dataset has the following list of tasks:
1859  //~~~
1860  // root [2] gDataSet->Print("tasks")
1861  // 1. Event reconstruction from raw data (raw->recon)
1862  // 2. Analysis of raw data
1863  // 3. Identification of reconstructed events (recon->ident)
1864  // 4. Analysis of reconstructed events (recon)
1865  // 5. Analysis of partially identified & calibrated reconstructed events (ident)
1866  // 6. Analysis of fully calibrated physical data (root)
1867  //~~~
1868  //Then the following will occur:
1869  //~~~
1870  // root [14] gDataSet->GetAnalysisTask("raw->recon")->Print()
1871  // KVDataAnalysisTask : Event reconstruction from raw data (raw->recon)
1872  //
1873  // root [10] gDataSet->GetAnalysisTask("analysis root")->Print()
1874  // KVDataAnalysisTask : Analysis of fully calibrated physical data (root)
1875  //~~~
1876 
1877  //case-insensitive search for matches in list based on 'title' attribute
1878  return (KVDataAnalysisTask*)fTasks.FindObjectAny("title", keywords, kTRUE, kFALSE);
1879 }
1880 
1881 
1882 
1883 
1885 
1887 {
1888  if (!dat->WithUserClass()) {
1889  KVError::Error(this, "MakeAnalysisClass",
1890  "No user class required for analysis task \"%s\"", dat->GetTitle());
1891  return false;
1892  }
1893 
1894  //all analysis base classes must define a static Make(const Char_t * classname)
1895  //which generates the skeleton class files.
1896 
1897  TClass* cl = nullptr;
1898  //has the user base class for the task been compiled and loaded ?
1900  else
1901  return false;
1902 
1903  //set up call to static Make method
1904  unique_ptr<TMethodCall> methcall(new TMethodCall(cl, "Make", Form("\"%s\"", classname)));
1905 
1906  if (!methcall->IsValid()) {
1907  KVError::Error(this, "MakeAnalysisClass", "static Make(const Char_t*) method for class %s is not valid",
1908  cl->GetName());
1909  return false;
1910  }
1911 
1912  //generate skeleton class
1913  methcall->Execute();
1914 
1915  return true;
1916 }
1917 
1918 
1919 
1955 
1956 TObject* KVDataSet::file_opener(const TString& type, const TString& fname, Option_t* opt)
1957 {
1958  // For the give datatype 'type', open file using fullpath 'fname' and whatever kind of class is defined
1959  // to be used for opening files of this datatype. Returns file handle as a TObject* pointer.
1960  //
1961  //The default base classes for each type are defined as in this example:
1962  //
1963  // # Default base classes for reading runfiles of different types
1964  // DataSet.RunFileClass.raw: KVRawDataReader
1965  // DataSet.RunFileClass.recon: TFile
1966  // DataSet.RunFileClass.ident: TFile
1967  // DataSet.RunFileClass.root: TFile
1968  //
1969  //A different base class can be defined for a specific dataset/datatype
1970  //by adding a line to your $HOME/.kvrootrc like this:
1971  //
1972  //name_of_dataset.DataSet.RunFileClass.data_type: BaseClassName
1973  //
1974  //The actual class to be used is then defined by plugins, for example
1975  //
1976  //name_of_dataset.DataSet.RunFileClass.data_type: plugin_name
1977  //
1978  //where 'plugin_name' is one of the known plugins for the default base class for the given data_type,
1979  //i.e. if data_type="raw" we could use one of either "GANIL" or "MFM" as plugin_name:
1980  //
1981  //Plugin.KVRawDataReader: GANIL KVGANILDataReader kaliveda-core "KVGANILDataReader()"
1982  //+Plugin.KVRawDataReader: MFM KVMFMDataFileReader kaliveda-core "KVMFMDataFileReader()"
1983  //
1984  //If no plugin is found for the base class defined by DataSet.RunFileClass, the base class is used.
1985  //
1986  //To actually open the file, each base class & plugin must define a method
1987  //~~~{.cpp}
1988  // static BaseClass* Open(const Char_t* path, Option_t* opt="", ...)
1989  //~~~
1990  //which takes the full path to the file as argument (any other arguments taking default options)
1991  //and returns a pointer of the BaseClass type to the created object which can be used to read the file.}
1992 
1993  auto plugin_class = GetDataSetEnv<KVString>(Form("DataSet.RunFileClass.%s", type.Data()));
1994 
1995  TPluginHandler* ph = nullptr;
1996  KVString base_class;
1997  if (IsThisAPlugin(plugin_class, base_class)) {
1998 
1999  //look for plugin specific to dataset & type
2000  ph = LoadPlugin(base_class, plugin_class);
2001 
2002  }
2003  else
2004  base_class = plugin_class;
2005  TClass* cl;
2006  if (!ph) {
2007  //no plugin - use base class
2008  cl = TClass::GetClass(base_class.Data());
2009  }
2010  else {
2011  cl = TClass::GetClass(ph->GetClass());
2012  }
2013 
2014  //set up call to static Open method
2015  std::unique_ptr<TMethodCall> methcall;
2016  if (strcmp(opt, "")) {
2017  //Open with option
2018  methcall = std::make_unique<TMethodCall>(cl, "Open", Form("\"%s\", \"%s\"", fname.Data(), opt));
2019  }
2020  else {
2021  //Open without option
2022  methcall = std::make_unique<TMethodCall>(cl, "Open", Form("\"%s\"", fname.Data()));
2023  }
2024 
2025  if (!methcall->IsValid()) {
2026  if (ph) KVError::Error(this, "OpenDataSetFile", "Open method for class %s is not valid", ph->GetClass());
2027  else KVError::Error(this, "OpenDataSetFile", "Open method for class %s is not valid", base_class.Data());
2028  return nullptr;
2029  }
2030 
2031  //open the file
2032  Long_t retval;
2033  methcall->Execute(retval);
2034  return ((TObject*)(retval));
2035 }
2036 
2037 
2038 
2051 
2052 bool KVDataSet::MakeAnalysisClass(const Char_t* task, const Char_t* classname)
2053 {
2054  //Create a skeleton analysis class to be used for analysis of the data belonging to this dataset.
2055  //
2056  // task = keywords contained in title of analysis task (see GetAnalysisTask(const Char_t*))
2057  // (you do not need to include 'analysis', it is added automatically)
2058  // classname = name of new analysis class
2059  //
2060  //Example:
2061  // MakeAnalysisClass("raw", "MyRawDataAnalysis")
2062  // --> make skeleton raw data analysis class in files MyRawDataAnalysis.cpp & MyRawDataAnalysis.h
2063  // MakeAnalysisClass("fully calibrated", "MyDataAnalysis")
2064  // --> make skeleton data analysis class in files MyDataAnalysis.cpp & MyDataAnalysis.h
2065 
2066  KVString _task = task;
2067  if (!_task.Contains("nalysis")) _task += " analysis";
2068  //We want to be able to write analysis classes even when we don't have any data
2069  //to analyse. Therefore we use GetAnalysisTaskAny.
2070  auto dat = GetAnalysisTaskAny(_task.Data());
2071  if (!dat) {
2072  KVError::Error(this, "MakeAnalysisClass",
2073  "called for unknown or unavailable analysis task : %s", _task.Data());
2074  return false;
2075  }
2076  return make_analysis_class(dat, classname);
2077 }
2078 
2079 
2080 
2087 
2088 bool KVDataSet::MakeAnalysisClass(int task, const Char_t* classname)
2089 {
2090  //Create a skeleton analysis class to be used for analysis of the data belonging to this dataset.
2091  //
2092  // task = index of analysis task as shown in KVDataSet::Print("tasks")
2093  // classname = name of new analysis class
2094  //
2095 
2096  auto dat = GetAnalysisTask(task);
2097  if (!dat) {
2098  KVError::Error(this, "MakeAnalysisClass",
2099  "called for unknown or unavailable analysis task index : %d", task);
2100  return false;
2101  }
2102  return make_analysis_class(dat, classname);
2103 }
2104 
2105 
2106 
2107 
2111 
2112 Bool_t KVDataSet::OpenDataSetFile(const Char_t* filename, ifstream& file)
2113 {
2114  // Look for (and open for reading, if found) the named file in the directory which
2115  // contains the files for this dataset (given by GetDataSetDir())
2116 
2117  return OpenDataSetFile(GetName(), filename, file);
2118 }
2119 
2120 
2121 
2125 
2126 Bool_t KVDataSet::OpenDataSetFile(const TString& dataset, const Char_t* filename, ifstream& file)
2127 {
2128  // Static method to look for (and open for reading, if found) the named file in the directory which
2129  // contains the files for the dataset
2130 
2131  TString datasetdir = KVBase::GetDataSetEnv(dataset, "DataSet.Directory", dataset);
2132  if (gSystem->IsAbsoluteFileName(datasetdir)) {
2133  // dataset directory is outside of standard KV installation directories
2134  // use absolute path to search for file
2135  TString abspath;
2136  abspath.Form("%s/%s", datasetdir.Data(), filename);
2137  return SearchAndOpenKVFile(abspath, file);
2138  }
2139  // dataset directory is a subdirectory of GetDATADIRFilePath()
2140  return SearchAndOpenKVFile(filename, file, datasetdir);
2141 }
2142 
2143 
2144 
2148 
2150 {
2151  // Find a file in the dataset directory (given by GetDataSetDir())
2152  // Returns full path to file if found, empty string if not
2153 
2154  return GetFullPathToDataSetFile(GetName(), filename);
2155 }
2156 
2157 
2158 
2163 
2165 {
2166  // Static method to find a file in the dataset directory (given by GetDataSetDir())
2167  //
2168  // Returns full path to file if found, empty string if not
2169 
2170  TString fullpath;
2171  TString datasetdir = KVBase::GetDataSetEnv(dataset, "DataSet.Directory", dataset);
2172  if (!SearchKVFile(filename, fullpath, datasetdir)) {
2173  KVError::Warning(KVDataSet{}, "GetFullPathToDataSetFile", "File %s not found in dataset subdirectory %s", filename, datasetdir.Data());
2174  fullpath = "";
2175  }
2176  return fullpath;
2177 }
2178 
2179 
2180 
2184 
2185 Bool_t KVDataSet::FindDataSetFile(const TString& dataset, const Char_t* filename)
2186 {
2187  // Static method to find a file in the dataset directory (given by GetDataSetDir())
2188  // Returns kTRUE if found, kFALSE if not
2189 
2190  TString fullpath;
2191  TString datasetdir = KVBase::GetDataSetEnv(dataset, "DataSet.Directory", dataset);
2192  return SearchKVFile(filename, fullpath, datasetdir);
2193 }
2194 
2195 
2196 
2200 
2202 {
2203  // Find a file in the dataset directory (given by GetDataSetDir())
2204  // Returns kTRUE if found, kFALSE if not
2205 
2206  return FindDataSetFile(GetName(), filename);
2207 }
2208 
2209 
2210 
2211 
2220 
2222 {
2223  //This method returns the analysis task whose description (title) contains
2224  //all of the whitespace-separated keywords (which may be regular expressions)
2225  //given in the string "keywords". The comparison is case-insensitive.
2226  //The analysis task does not need to be "available", i.e. the associated prerequisite
2227  //data type does not have to be present in the repository (see GetAnalysisTask).
2228  //
2229  // If no task is found, returns nullptr
2230 
2231  KVDataAnalysisTask* tsk = (KVDataAnalysisTask*)fAllTasks.FindObjectAny("title", keywords, kTRUE, kFALSE);
2232  if (!tsk) {
2233  KVError::Error(this, "GetAnalysisTaskAny", "No task found with the following keywords in its title : %s", keywords);
2234  }
2235  return tsk;
2236 }
2237 
2238 
2239 
2240 
2247 
2249 {
2250  // Returns kTRUE if database needs to be regenerated from source files,
2251  // i.e. if source files are more recent than DataBase.root
2252  //
2253  // In case no directory exists for dataset (dataset added 'on the fly')
2254  // we create the directory and fill it with dummy files (Makefile, Runlist.csv, Systems.dat)
2255 
2256  TString pwd = gSystem->pwd();
2257 
2258  TString path = "";
2259  if (!SearchKVFile(GetDataSetDir(), path)) {
2260  // dataset directory doesn't exist - create it
2261  Info("DataBaseNeedsUpdate", "%s: Creating new dataset directory %s",
2262  GetName(), GetDataSetDir());
2263  if (gSystem->mkdir(GetDataSetDir())) {
2264  // problem creating directory
2265  KVError::Error(this, "DataBaseNeedsUpdate",
2266  "%s: Dataset directory %s does not exist and cannot be created ?",
2267  GetName(), GetDataSetDir());
2268  return kFALSE;
2269  }
2270  // create dummy files
2271  SearchKVFile(GetDataSetDir(), path); // get full path
2272  path += "/";
2273  TString filename = path + "Makefile";
2274  ofstream of1(filename.Data());
2275  of1 << "$(KV_WORK_DIR)/db/" << GetName() << "/DataBase.root : Runlist.csv Systems.dat" << endl;
2276  of1 << "\t@echo Database needs update" << endl;
2277  of1.close();
2278  filename = path + "Runlist.csv";
2279  ofstream of2(filename.Data());
2280  of2 << "# Automatically generated dummy Runlist.csv file" << endl;
2281  of2.close();
2282  filename = path + "Systems.dat";
2283  ofstream of3(filename.Data());
2284  of3 << "# Automatically generated dummy Systems.dat file" << endl;
2285  of3.close();
2286  }
2287  gSystem->cd(GetDataSetDir());
2288  TString cmd = "make -q";
2289  Int_t ret = gSystem->Exec(cmd.Data());
2290  gSystem->cd(pwd.Data());
2291  return (ret != 0);
2292 }
2293 
2294 
2295 
2312 
2314 {
2315  // Returns name of output repository for given task.
2316  // By default it is the name of the repository associated with this dataset,
2317  // but can be changed by the following environment variables:
2318  //
2319  // [repository].DefaultOutputRepository: [other repository]
2320  // - this means that all tasks carried out on data in [repository]
2321  // will have their output files placed in [other repository]
2322  //
2323  // [taskname].DataAnalysisTask.OutputRepository: [other repository]
2324  // - this means that for [taskname], any output files will
2325  // be placed in [other repository]
2326  //
2327  // [dataset].[taskname].DataAnalysisTask.OutputRepository: [other repository]
2328  // - this means that for given [dataset] & [taskname],
2329  // any output files will be placed in [other repository]
2330 
2331  if (gEnv->Defined(Form("%s.DataRepository.DefaultOutputRepository", GetRepository()->GetName())))
2332  return TString(gEnv->GetValue(Form("%s.DataRepository.DefaultOutputRepository", GetRepository()->GetName()), ""));
2333  TString orep = GetDataSetEnv(Form("%s.DataAnalysisTask.OutputRepository", taskname), GetRepository()->GetName());
2334  return orep;
2335 }
2336 
2337 
2338 
2339 
2342 
2343 void KVDataSet::CopyRunfilesFromRepository(const Char_t* type, const run_index_list& runs, const Char_t* destdir)
2344 {
2345  // Copies the runfiles of given "type" into the local directory "destdir".
2346 
2347  auto repo = GetRepository();
2348  for (auto& run : runs) {
2349  TString filename = GetRunfileName(type, run);
2350  TString destpath;
2351  AssignAndDelete(destpath, gSystem->ConcatFileName(destdir, filename));
2352  repo->CopyFileFromRepository(this, type, filename, destpath);
2353  }
2354 }
2355 
2356 
2357 
2358 
2362 
2363 void KVDataSet::CopyRunfilesToRepository(const Char_t* type, const run_index_list& runs, const Char_t* destrepo)
2364 {
2365  // Copies the runfiles of given "type" from the data repository associated
2366  // with this dataset into the local repository "destrepo".
2367 
2368  auto repo = GetRepository();
2369  auto dest_repo = dynamic_cast<KVDataSetRepository*>(gDataRepositoryManager->GetRepository(destrepo));
2370 
2371  if (!dest_repo) {
2372  KVError::Error(this, "CopyRunfilesToRepository", "Unknown destination repository : %s", destrepo);
2373  gDataRepositoryManager->Print();
2374  return;
2375  }
2376 
2377  KVDataSet* dest_ds = dest_repo->GetDataSetManager()->GetDataSet(GetName());
2378  dest_repo->CreateAllNeededSubdirectories(dest_ds, type);
2379  for (auto& run : runs) {
2380  TString filename = GetRunfileName(type, run);
2381  TString destpath = dest_repo->GetFullPathToTransferFile(dest_ds, type, filename);
2382  repo->CopyFileFromRepository(this, type, filename, destpath);
2383  }
2384 }
2385 
2386 
int Int_t
long Long_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:306
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)
void Print(Option_t *opt="") const
KVDataSetRepository * GetRepository(const TString &name) const
KVDataSet * GetDataSet(Int_t) const
Return pointer to DataSet using index in list of all datasets, index>=0.
A repository for experimental datasets.
KVDataSetManager * GetDataSetManager() const
Return pointer to data set manager for this repository.
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:929
TString GetFullPathToRunfile(const KVString &type, const run_index_t &run) const
Definition: KVDataSet.cpp:885
TString GetFullPathToDB() const
Definition: KVDataSet.cpp:153
void ls(Option_t *opt="") const override
Print dataset information.
Definition: KVDataSet.cpp:410
TString GetOutputRepository(const Char_t *taskname) const
Definition: KVDataSet.cpp:2313
void OpenDBFile(const Char_t *full_path_to_dbfile) const
Open the database from a file on disk.
Definition: KVDataSet.cpp:127
void SetRepository(KVDataSetRepository *)
Set pointer to data repository in which dataset is stored.
Definition: KVDataSet.cpp:1474
TString GetDBName() const
Definition: KVDataSet.cpp:112
void CheckMultiRunfiles(const Char_t *data_type)
Definition: KVDataSet.cpp:1500
Bool_t CheckRunfileAvailable(const KVString &type, const run_index_t &run)
Definition: KVDataSet.cpp:1026
void CleanRunfileDataBase(const Char_t *data_type)
Definition: KVDataSet.cpp:1617
void CheckUpToDate(const Char_t *data_type, const Char_t *other_repos)
Definition: KVDataSet.cpp:1718
run_index_list GetRunList(const Char_t *data_type, const KVDBSystem *sys=0) const
Definition: KVDataSet.cpp:1795
void OpenDataBase(const TString &="") const
Definition: KVDataSet.cpp:319
TString GetFullPathToDataSetFile(const Char_t *filename) const
Definition: KVDataSet.cpp:2149
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:2343
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:1235
const Char_t * GetDataSetDir() const
Definition: KVDataSet.cpp:756
void CommitRunfile(const KVString &type, const run_index_t &run, TFile *file)
Definition: KVDataSet.cpp:1433
void AddAvailableDataType(const Char_t *)
Definition: KVDataSet.cpp:518
KVUniqueNameList GetSystemsForRunFiles(const TString &datatype, const run_index_list &) const
Definition: KVDataSet.cpp:683
bool make_analysis_class(const KVDataAnalysisTask *, const Char_t *classname)
Definition: KVDataSet.cpp:1886
KVDataAnalysisTask * GetAnalysisTask(Int_t) const
Definition: KVDataSet.cpp:584
KVAvailableRunsFile * GetAvailableRunsFile(const TString &type) const
Definition: KVDataSet.cpp:49
void SaveDataBase() const
Definition: KVDataSet.cpp:203
KVDataAnalysisTask * GetAnalysisTaskAny(const Char_t *keywords) const
Definition: KVDataSet.cpp:2221
virtual TString GetBaseFileName(const Char_t *type, const run_index_t &run) const
Definition: KVDataSet.cpp:1059
void SetAnalysisTasks(const KVSeqCollection *)
Definition: KVDataSet.cpp:535
TFile * NewRunfile(const KVString &type, const run_index_t &run)
Definition: KVDataSet.cpp:1132
KVList GetListOfAvailableRunFilesForSystem(const TString &datatype, KVDBSystem *systol)
Definition: KVDataSet.cpp:639
void CheckAvailable()
Definition: KVDataSet.cpp:476
void DeleteRunfile(const KVString &type, const run_index_t &run, Bool_t confirm=kTRUE)
Definition: KVDataSet.cpp:1157
Int_t GetNtasks() const
Definition: KVDataSet.cpp:569
TObject * file_opener(const TString &, const TString &, Option_t *="")
Definition: KVDataSet.cpp:1956
run_index_list GetRunList_VersionSelection(const TString &type, const TString &version, KVDBSystem *sys=0)
Definition: KVDataSet.cpp:1391
KVExpDB * GetDataBase(const TString &opt="") const
Definition: KVDataSet.cpp:288
void DeleteRunfiles(const Char_t *type, const run_index_list &lrun={}, Bool_t confirm=kTRUE)
Definition: KVDataSet.cpp:1204
Bool_t CheckRunfileUpToDate(const KVString &data_type, const run_index_t &run, KVDataSetRepository *other_repos)
Definition: KVDataSet.cpp:1659
TObject * open_runfile(const KVString &type, const run_index_t &run)
Definition: KVDataSet.cpp:828
void CopyRunfilesToRepository(const Char_t *type, const run_index_list &runs, const Char_t *destrepo)
Definition: KVDataSet.cpp:2363
KVDataSetRepository * GetRepository() const
Get pointer to data repository in which dataset is stored.
Definition: KVDataSet.cpp:1486
KVString GetRunfileName(const KVString &type, const run_index_t &run) const
Definition: KVDataSet.cpp:905
Bool_t DataBaseNeedsUpdate() const
Definition: KVDataSet.cpp:2248
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:178
run_index_list GetRunList_StageSelection(const TString &other_type, const TString &base_type, KVDBSystem *sys=0, Bool_t OnlyCol=kFALSE)
Definition: KVDataSet.cpp:1289
void cd() const
Definition: KVDataSet.cpp:778
void WriteDBFile(const Char_t *full_path_to_dbfile) const
Write the database to disk.
Definition: KVDataSet.cpp:255
void Print(Option_t *opt="") const override
Definition: KVDataSet.cpp:433
void SetName(const char *name) override
Definition: KVDataSet.cpp:718
void UpdateAvailableRuns(const KVString &type)
Definition: KVDataSet.cpp:1103
run_index_list GetUpdatableRuns(const Char_t *data_type, const Char_t *other_repos)
Definition: KVDataSet.cpp:1761
bool MakeAnalysisClass(const Char_t *task, const Char_t *classname)
Definition: KVDataSet.cpp:2052
KVDataSet()
Default constructor.
Definition: KVDataSet.cpp:35
std::optional< run_index_t > GetRunNumberFromFileName(const TString &datatype, const TString &filename)
Definition: KVDataSet.cpp:978
void CleanMultiRunfiles(const Char_t *data_type, Bool_t confirm=kTRUE)
Definition: KVDataSet.cpp:1546
static Bool_t FindDataSetFile(const TString &dataset, const Char_t *filename)
Definition: KVDataSet.cpp:2185
KVUnownedList GetListOfAvailableSystems(const TString &datatype)
Definition: KVDataSet.cpp:599
TString GetDBFileName() const
Definition: KVDataSet.cpp:82
Extension of TDatime to handle various useful date formats.
Definition: KVDatime.h:35
Base class to describe database of an experiment ,,.
Definition: KVExpDB.h:61
virtual void cd()
Definition: KVExpDB.cpp:762
static KVExpDB * MakeDataBase(const Char_t *name, const Char_t *datasetdir, Bool_t minimal=false)
Definition: KVExpDB.cpp:783
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
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)
const char * GetClass() const
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(UserClass p, const char *location, const char *va_(fmt),...)
Definition: KVError.h:116
void Warning(UserClass p, const char *location, const char *va_(fmt),...)
Definition: KVError.h:125
void Info(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)