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 
82 
84 {
85  //Returns name of file containing database for dataset.
86  //
87  //This is fixed as `DataBase.root.M.mm` where
88  // - `M` is the current major version number
89  // - `m` is the current minor version 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", GetKVMajorVersion(),
101  GetKVMinorVersion()));
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  Error("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  KVString envar = GetDataSetEnv(Form("%s.DataAnalysisTask.Title", t->GetName()));
183  if (envar != "") t->SetTitle(envar);
184  envar = GetDataSetEnv(Form("%s.DataAnalysisTask.Analyser", t->GetName()));
185  if (envar != "") t->SetDataAnalyser(envar);
186  envar = GetDataSetEnv(Form("%s.DataAnalysisTask.UserClass.Base", t->GetName()));
187  if (envar != "") t->SetUserBaseClass(envar);
188  envar = GetDataSetEnv(Form("%s.DataAnalysisTask.Prereq", t->GetName()));
189  if (envar != "") t->SetPrereq(envar);
190  envar = GetDataSetEnv(Form("%s.DataAnalysisTask.UserClass.ExtraACliCIncludes", t->GetName()));
191  if (envar != "") t->SetExtraAClicIncludes(envar);
192  Int_t nev = (Int_t)GetDataSetEnv(Form("%s.DataAnalysisTask.StatusUpdateInterval", t->GetName()), 0.0);
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  Error("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  Error("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  Error("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  Error("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 
284 
286 {
287  //\returns pointer to database associated with this dataset.
288  //
289  //Opens, updates or creates database file if necessary
290  //(the database is automatically rebuilt if the source files are
291  //more recent than the last database file).
292  //
293  //\param[in] opt if opt="update": force regeneration of the database from source files in dataset directory
294 
295  TString _opt(opt);
296  _opt.ToUpper();
297  if (_opt == "UPDATE") {
298  OpenDataBase(_opt.Data());
299  }
300  else {
301  OpenDataBase();
302  }
303  return fDataBase;
304 }
305 
306 
307 
318 
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 if opt="UPDATE" we force rebuilding of the database
327  //
328  //\warning if the database needs to be (re)built, we set gDataSet to point to this dataset in case it was not already done,
329  //as in order to (re)build the database it may be necessary for gDataSet to point to the current dataset.
330 
331  Bool_t is_glob_db = kFALSE;
332  //if option="update" or database out of date or does not exist, (re)build the database
333  if ((!strcmp(opt, "UPDATE")) || DataBaseNeedsUpdate()) {
334  //check if it is the currently active database (gDataBase),
335  //in which case we must 'cd()' to it after rebuilding
336  Info("OpenDataBase", "Updating database file");
337  fDataBaseUpdateInProgress = true;
338  is_glob_db = (fDataBase == gExpDB);
339  if (fDataBase) {
340  delete fDataBase;
341  fDataBase = 0;
342  }
343  // make sure gDataSet is set & points to us
344  gDataSet = const_cast<KVDataSet*>(this);
345  fDataBase = KVExpDB::MakeDataBase(GetDBName(), GetDataSetDir());
346  if (!fDataBase) {
347  // no database defined for dataset
348  Info("OpenDataBase", "No database defined for dataset");
349  return;
350  }
351  SaveDataBase();
352  if (fDataBase && is_glob_db) fDataBase->cd();
353  fDataBaseUpdateInProgress = false;
354  }
355  else if (!fDataBase) {
356  // if database is not in memory at this point, we need to
357  // open the database file and read in the database
358 
359  //load plugin for database
360  if (!LoadPlugin("KVExpDB", GetDBName())) {
361  Error("GetDataBase", "Cannot load required plugin library");
362  return;
363  }
364  //look for database file in dataset subdirectory
365  TString dbfile_fullpath = GetFullPathToDB();
366  //open database file
367  OpenDBFile(dbfile_fullpath.Data());
368  }
369 }
370 
371 
372 
373 
376 
378 {
379  //Print dataset information
380  cout << "Dataset name=" << GetName() << " (" << GetTitle() << ")";
381  if (IsAvailable()) {
382  cout << " [ AVAILABLE: ";
383  cout << fDatatypes.Data();
384  cout << "]";
385  }
386  else
387  cout << " [UNAVAILABLE]";
388  cout << endl;
389 }
390 
391 
392 
399 
400 void KVDataSet::Print(Option_t* opt) const
401 {
402  //Print dataset information
403  //
404  //param[in] opt select optional output formats:
405  // - if string contains "tasks", print numbered list of tasks that can be performed
406  // - if string contains "data", print list of available data types
407 
408  TString Sopt(opt);
409  Sopt.ToUpper();
410  if (Sopt.Contains("TASK")) {
411  if (!GetNtasks()) {
412  cout << " *** No available analysis tasks ***"
413  << endl;
414  return;
415  }
416  else {
417  for (int i = 1; i <= GetNtasks(); i++) {
418  KVDataAnalysisTask* dat = GetAnalysisTask(i);
419  cout << "\t" << i << ". " << dat->GetTitle() << endl;
420  }
421  }
422  cout << endl;
423  }
424  else if (Sopt.Contains("DATA")) {
425  cout << "Available data types: " << fDatatypes.Data() << endl;
426  }
427  else {
428  ls(opt);
429  }
430 }
431 
432 
433 
442 
444 {
445  //Check if this data set is physically present and available for analysis.
446  //
447  //In other words we check if the value of GetDataPathSubdir() is a subdirectory
448  //of the current data repository.
449  //If so, we proceed to check for the existence of sudirectories corresponding
450  // to any of the datatypes associated with the dataset.
451  //
452 
453  if (!fRepository) // for a stand-alone KVDataSetManager not linked to a KVDataRepository,
454  SetAvailable(); // all known datasets are 'available'
455  else
456  SetAvailable(fRepository->CheckSubdirExists(GetDataPathSubdir()));
457  if (!IsAvailable())
458  return;
459  //check subdirectories
460  KVString data_types = GetDataSetEnv("KVDataSet.DataTypes", "");
461  if (data_types == "") {
462  Warning("CheckAvailable", "No datatypes defined for this dataset: %s\nCheck value of KVDataSet.DataTypes or %s.KVDataSet.DataTypes",
463  GetName(), GetName());
464  SetAvailable(kFALSE);
465  }
466  fDatatypes = "";
467  // loop over data types
468  data_types.Begin(" ");
469  while (!data_types.End()) {
470  KVString type = data_types.Next(kTRUE);
471  if (!fRepository ||
472  (fRepository && fRepository->CheckSubdirExists(GetDataPathSubdir(), GetDataTypeSubdir(type.Data())))
473  ) {
474  AddAvailableDataType(type.Data());
475  }
476  }
477  //check at least one datatype exists
478  SetAvailable(fDatatypes != "");
479  //check user name against allowed groups
480  if (!CheckUserCanAccess()) {
481  SetAvailable(kFALSE);
482  return;
483  }
484 }
485 
486 
487 
489 
491 {
492  if (fDatatypes != "") fDatatypes += " ";
493  KVString _type = type;
494  _type.Remove(TString::kBoth, ' '); //strip whitespace
495  fDatatypes += _type;
496 }
497 
498 
499 
506 
508 {
509  // Add to fAllTasks list any data analysis task in list 'task_list'
510  //
511  // Add to fTasks list any data analysis task in list 'task_list' whose pre-requisite datatype is present for this dataset.
512  //
513  // Any dataset-specific "tweaking" of the task (including the prerequisite datatype) is done here.
514 
515  TString availables = gEnv->GetValue(Form("%s.DataAnalysisTask", GetName()), "");
516  fAllTasks.Clear();
517  fTasks.Clear();
518  TIter nxt(task_list);
519  KVDataAnalysisTask* dat;
520  while ((dat = (KVDataAnalysisTask*) nxt())) {
521  //make new copy of default analysis task
522  if (availables == "" || availables.Contains(dat->GetName())) {
523  KVDataAnalysisTask* new_task = new KVDataAnalysisTask(*dat);
524  //check if any dataset-specific parameters need to be changed
525  SetDataSetSpecificTaskParameters(new_task);
526  fAllTasks.Add(new_task);
527  // add tasks with available prerequisite data to fTasks
528  if (HasDataType(new_task->GetPrereq())) {
529  fTasks.Add(new_task);
530  }
531  }
532  }
533 }
534 
535 
536 
540 
542 {
543  //Returns the number of tasks associated to dataset which are compatible
544  //with the available data
545 
546  return fTasks.GetSize();
547 }
548 
549 
550 
555 
557 {
558  //Return kth analysis task in list of available tasks.
559  //
560  //\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
561  return (KVDataAnalysisTask*) fTasks.At(k - 1);
562 }
563 
564 
565 
570 
572 {
573  //\returns list of available systems for this dataset and the given datatype
574  //
575  //\param[in] datatype type of data
576 
577  if (!GetAvailableRunsFile(datatype)) {
578  Error("GetListOfAvailableSystems(const Char_t*)",
579  "No available runs file for type %s", datatype.Data());
580  return {};
581  }
582  return GetAvailableRunsFile(datatype)->GetListOfAvailableSystems();
583 }
584 
585 
586 
591 
593 {
594  //\returns list of available systems for this dataset and the prerequisite datatype for the given analysis task
595  //
596  //\param[in] datan data analysis task
597 
598  return GetListOfAvailableSystems(datan->GetPrereq());
599 }
600 
601 
602 
610 
612 {
613  //\returns list of available runfiles for this dataset and the given datatype and system.
614  //
615  //\param[in] datatype type of data
616  //\param[in] systol pointer to system
617  //
618  //If no systems are defined for the dataset then we return a list of available runfiles for the given datatype
619 
620  if (!GetAvailableRunsFile(datatype)) {
621  Error("GetListOfAvailableSystems(const Char_t*)",
622  "No available runs file for type %s", datatype.Data());
623  return {};
624  }
625  return GetAvailableRunsFile(datatype)->GetListOfAvailableRunFilesForSystem(systol);
626 }
627 
628 
629 
637 
639 {
640  //\returns list of available runfiles for this dataset, given system, and the prerequisite datatype for the given analysis task
641  //
642  //\param[in] datan data analysis task
643  //\param[in] pointer to system
644  //
645  //If no systems are defined for the dataset then we return a list of available runfiles for the given datatype
646 
647  return GetListOfAvailableRunFilesForSystem(datan->GetPrereq(), systol);
648 }
649 
650 
651 
654 
656 {
657  // \returns the list of systems corresponding to the given list of runfiles & datatype
658 
659  if (!GetAvailableRunsFile(datatype)) {
660  Error("GetSystemsForRunFiles",
661  "No available runs file for type %s", datatype.Data());
662  return {};
663  }
664  return GetAvailableRunsFile(datatype)->GetSystemsForRunFiles(rl);
665 }
666 
667 
668 
689 
690 void KVDataSet::SetName(const char* name)
691 {
692  // Set name of dataset
693  //
694  // Also sets path to directory containing database informations
695  // for this dataset, i.e. list of runs, systems, calibration files etc.
696  //
697  // By default, just the name of the dataset is used, i.e.
698  // `[DATADIR]/name`
699  // (where `DATADIR` = path given by KVBase::GetDATADIRFilePath())
700  //
701  // However, if the variable
702  //~~~
703  // [name].DataSet.Directory: [path]
704  //~~~
705  // has been set, the value of `[path]` will be used:
706  // - if [path] is an absolute path name, it will be used as such
707  // - if [path] is an incomplete or relative path, it will be prepended with `[DATADIR]/`
708  //
709  // This allows to use one dataset as an alias for another, by setting `DataSet.Directory`
710  // to the name of an existing dataset
712  TString path = GetDataSetEnv("DataSet.Directory", name);
713  if (gSystem->IsAbsoluteFileName(path)) fCalibDir = path;
714  else {
715  // in this case (not an absolute path but just the name of another dataset)
716  // this dataset is an alias for another dataset.
717  fCalibDir = GetDATADIRFilePath(path);
718  // the name of the database object is the name of the "true" dataset
719  SetDBName(path);
720  }
721 }
722 
723 
724 
727 
729 {
730  //\returns full path to directory containing database and calibration/identification parameters etc. for this dataset.
731 
732  return fCalibDir.Data();
733 }
734 
735 
736 
749 
750 void KVDataSet::cd() const
751 {
752  // Makes this dataset the "currently active" or default dataset.
753  //
754  //At the same time, the database and data repository associated with
755  //this dataset also become the "currently active" ones:
756  //
757  // | global pointer | represents | base class |
758  // |----------------|------------|------------|
759  // | `gDataSet` | active dataset | KVDataSet |
760  // | `gExpDB` | associated experimental database | KVExpDB |
761  // | `gDataRepository` | repository containing runfiles | KVDataRepository |
762  //
763 
764  gDataSet = const_cast<KVDataSet*>(this);
765  if (fRepository) fRepository->cd();
766  KVExpDB* db = GetDataBase();
767  if (db) db->cd();
768 }
769 
770 
771 
799 
801 {
802  // Open file containing data of given datatype for given run number of this dataset.
803  //
804  // \returns a pointer to the opened file; if the file is not available, we return nullptr.
805  //
806  // The user must cast the returned pointer to the correct class, which will
807  // depend on the data type and the dataset
808  //
809  // **SPECIAL CASE: MFM data with EBYEDAT frames**
810  //
811  // If the variable
812  //
813  //~~~~~~~~~~~~~~~~~~~~~~~~~
814  // [dataset].MFM.WithEbyedat: yes
815  //~~~~~~~~~~~~~~~~~~~~~~~~~
816  //
817  // is set, then we expect to find the necessary `ACTIONS_*` files in the dataset directory
818  // in subdirectory `ebyedat` (they should have the same names as the data files prefixed by
819  // `ACTIONS_[expname].CHC_PAR.`).
820  //
821  // If in addition the variable
822  //
823  //~~~~~~~~~~~~~~~~~~~~~~~~~
824  // [dataset].MFM.EbyedatActionsExpName: [expname]
825  //~~~~~~~~~~~~~~~~~~~~~~~~~
826  //
827  // is set, then we use the same `ACTIONS` file for all runs, with name `ACTIONS_[expname].CHC_PAR`
828 
829 
830  if (!strcmp(type, "raw") && !strcmp(GetDataSetEnv("MFM.WithEbyedat", ""), "yes")) {
831  TString ebydir = GetDataSetDir();
832  ebydir += "/ebyedat";
833  gEnv->SetValue("KVMFMDataFileReader.ActionsDirectory", ebydir);
834  if (strcmp(GetDataSetEnv("MFM.EbyedatActionsExpName", ""), ""))
835  gEnv->SetValue("KVMFMDataFileReader.ActionsExpName", GetDataSetEnv("MFM.EbyedatActionsExpName", ""));
836  TObject* f = GetRepository()->OpenDataSetRunFile(this, type, run, GetName());
837  // reset in case another dataset opens a raw MFM file without EBYEDAT data
838  gEnv->SetValue("KVMFMDataFileReader.ActionsDirectory", "");
839  gEnv->SetValue("KVMFMDataFileReader.ActionsExpName", "");
840  return f;
841  }
842  return GetRepository()->OpenDataSetRunFile(this, type, run, GetName());
843 }
844 
845 
846 
847 
851 
853  const run_index_t& run) const
854 {
855  //\return full path to file containing data of given datatype for given run/index of this dataset
856  // \note only works for available run files, if their is no file in the repository for this run, the returned path will be empty
857 
858  TString file("");
859  if (fRepository) file = GetRunfileName(type, run);
860  if (file == "")
861  return file.Data();
862  return fRepository->GetFullPathToOpenFile(this, type, file.Data());
863 }
864 
865 
866 
867 
871 
873 {
874  //\return name of file containing data of given datatype for given run/index of this dataset
875  //\note only works for available run files, if there is no file in the repository for this run, the returned path will be empty
876 
877  if (!HasDataType(type)) {
878  Error("GetRunfileName",
879  "No data of type \"%s\" available for dataset %s", (const char*)type,
880  GetName());
881  return 0;
882  }
883  //get name of file from available runs file
884  return GetAvailableRunsFile(type)->GetFileName(run);
885 }
886 
887 
888 
889 
895 
896 std::optional<TDatime> KVDataSet::GetRunfileDate(const KVString& type, const run_index_t& run)
897 {
898  //\return date of file containing data of given datatype for given run/index of this dataset
899  //
900  //\note only works for available runfiles, if there is no file in the repository for this run/index,
901  //an error will be printed and std::optional will not contain a value
902 
903  if (!HasDataType(type)) {
904  Error("GetRunfileDate",
905  "No data of type \"%s\" available for dataset %s", (const char*)type,
906  GetName());
907  return std::nullopt;
908  }
909  //get date of file from available runs file
910  TDatime date;
912  if (!GetAvailableRunsFile(type)->GetRunInfo(run, date, filename)) {
913  Error("GetRunfileDate",
914  "Runfile not found for run %d index %d (data type: %s)", run.run(), run.index(), (const char*)type);
915  return std::nullopt;
916  }
917  return date;
918 }
919 
920 
921 
944 
945 std::optional<run_index_t> KVDataSet::GetRunNumberFromFileName(const TString& datatype, const TString& filename)
946 {
947  // \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
948  //
949  // If the runfile in question was generated using an index multiplier, e.g. if it contains the number
950  // '17001' when the index multiplier defined for the dataset is 1000, we return '17' as the
951  // run number and '1' as the index.
952  //
953  // Usage examples (using global pointer gDataSet to currently 'active' dataset):
954  //~~~{.cpp}
955  //auto run = gDataSet->GetRunNumberFromFileName(filename);
956  //
957  //if(!run) // no value (std::nullopt) returned
958  //{
959  // std::cerr << "Filename " << filename << " is not right format\n";
960  //}
961  //else
962  //{
963  // std::cout << "Filename " << filename << " corresponds to run number " << run.value().run();
964  // if(run.has_index()) std::cout << ", file index = " << run.index();
965  // std::cout << std::endl;
966  //}
967  //~~~
968 
969  auto arf = GetAvailableRunsFile(datatype);
970  auto v = arf->IsRunFileName(filename);
971  if (!v) return v;
972  // if the returned value has a non-null index, there is nothing more to do
973  if (v.value().has_index()) return v;
974  int r = v.value().run();
975  // check if returned run number actually consists of run*multiplier+index
976  if (GetDataBase()->HasIndexMultiplier() && r > GetDataBase()->GetIndexMultiplier()) {
977  r /= GetDataBase()->GetIndexMultiplier();
978  int i = v.value().run() % GetDataBase()->GetIndexMultiplier();
979  return run_index_t{r, i};
980  }
981  return v;
982 }
983 
984 
985 
986 
991 
993 {
994  //We check the availability of the run by looking in the available runs file associated
995  //with the given datatype.
996 
997  //check data type is available
998  if (!HasDataType(type)) {
999  Error("CheckRunfileAvailable",
1000  "No data of type \"%s\" available for dataset %s", (const char*)type,
1001  GetName());
1002  return 0;
1003  }
1004  return GetAvailableRunsFile(type)->CheckAvailable(run);
1005 }
1006 
1007 
1008 
1009 
1024 
1025 const Char_t* KVDataSet::GetBaseFileName(const Char_t* type, const run_index_t& run) const
1026 {
1027  //PRIVATE METHOD: Returns base name of data file containing data for the run of given datatype.
1028  //The filename corresponds to one of the formats defined in $KVROOT/KVFiles/.kvrootrc
1029  //by variables like:
1030  //
1031  //~~~
1032  //[dataset].DataSet.RunFileName.[type]: run%R.dat
1033  //~~~
1034  //
1035  //%R will be replaced with the run number
1036  //
1037  //IF the format contains '%D' it will be replaced with the current date and time
1038  //
1039  // Any index will be appended at the end: ".index"
1040 
1041  static TString tmp;
1042  //get format string
1043  TString fmt = GetDataSetEnv(Form("DataSet.RunFileName.%s", type));
1044  TString run_num(Form("%d", run.run()));
1045  KVDatime now;
1046  TString date(now.AsSQLString());
1047  tmp = fmt;
1048  tmp.ReplaceAll("%R", run_num);
1049  if (fmt.Contains("%D")) {
1050  tmp.ReplaceAll("%D", date);
1051  }
1052  if (run.has_index()) tmp += Form(".%d", run.index());
1053  return tmp.Data();
1054 }
1055 
1056 
1057 
1058 
1068 
1070 {
1071  //Update list of available runs for given data 'type'
1072  //
1073  //As we never clear the sqlite database of any previously existing runfiles
1074  //beforehand, it is possible that newer versions of said files have been
1075  //added and that we will therefore end up with multiple copies of files in the
1076  //database. Therefore we perform an automatic 'CleanRunfileDataBase' afterwards,
1077  //but only to remove runfiles which no longer physically exist
1078 
1079  //check data type is available
1080  if (!HasDataType(type)) {
1081  Error("UpdateAvailableRuns",
1082  "No data of type \"%s\" available for dataset %s", (const char*)type,
1083  GetName());
1084  }
1085  KVAvailableRunsFile* a = GetAvailableRunsFile(type);
1086  a->Update();
1087  CleanRunfileDataBase(type);
1088 }
1089 
1090 
1091 
1092 
1097 
1099 {
1100  // Create a new runfile for the dataset of given datatype.
1101  // (only if this dataset is associated with a data repository)
1102  // Once the file has been filled, use CommitRunfile to submit it to the repository.
1103 
1104  if (!fRepository) return nullptr;
1105  TString tmp = GetBaseFileName(type, run);
1106  //turn any spaces into "_"
1107  tmp.ReplaceAll(" ", "_");
1108  return fRepository->CreateNewFile(this, type, tmp.Data());
1109 }
1110 
1111 
1112 
1113 
1122 
1123 void KVDataSet::DeleteRunfile(const KVString& type, const run_index_t& run, Bool_t confirm)
1124 {
1125  // Delete the file for the given run/index of data type "type" from the repository.
1126  // By default, confirm=kTRUE, which means that the user will be asked to confirm
1127  // that the file should be deleted. If confirm=kFALSE, no confirmation will be asked
1128  // for and the file will be deleted straight away.
1129  //
1130  // WARNING: this really does DELETE files in the repository, they cannot be
1131  // retrieved once they have been deleted.
1132 
1133  if (!fRepository) return;
1134 
1135  //get name of file to delete
1136  TString filename = GetAvailableRunsFile(type)->GetFileName(run);
1137  if (filename == "") {
1138  Error("DeleteRunfile", "Run %s of type %s does not exist.",
1139  run.as_string().Data(), (const char*)type);
1140  return;
1141  }
1142  //delete file
1143  //prevent accidental deletion of certain types of runfiles
1144  KVString doNotDelete = GetDataSetEnv("DataSet.RunFile.DoNotDelete", "all");
1145  if (doNotDelete == "all" || doNotDelete.Contains(type)) {
1146  Error("DeleteRunFile", "%s files cannot be deleted", (const char*)type);
1147  return;
1148  }
1149  fRepository->DeleteFile(this, type, filename.Data(), confirm);
1150  //was file deleted ? if so, remove entry from available runs file
1151  if (!fRepository->CheckFileStatus(this, type, filename.Data()))
1152  GetAvailableRunsFile(type)->Remove(run);
1153 }
1154 
1155 
1156 
1157 
1169 
1170 void KVDataSet::DeleteRunfiles(const Char_t* type, const run_index_list& nl, Bool_t confirm)
1171 {
1172  // Delete files corresponding to a list of runs/index of data type "type" from the repository.
1173  //
1174  // By default, confirm=kTRUE, which means that the user will be asked to confirm
1175  // that each file should be deleted.
1176  //
1177  // If confirm=kFALSE, no confirmation will be asked for and the file will be deleted straight away.
1178  //
1179  // if "nl" is empty (default value) all runs of the dataset corresponding to the given type will be deleted
1180  //
1181  // WARNING: this really does DELETE files in the repository, they cannot be retrieved once they have been deleted.
1182 
1183  auto NL = nl;
1184  if (NL.IsEmpty()) NL = GetRunList(type);
1185  if (NL.IsEmpty()) return;
1186  for (auto& r : NL)
1187  DeleteRunfile(type, r, confirm);
1188 }
1189 
1190 
1191 
1192 
1200 
1201 run_index_list KVDataSet::GetRunList_DateSelection(const TString& type, const KVUnownedList& systems, std::optional<KVDatime> min_date, std::optional<KVDatime> max_date)
1202 {
1203  // Prints out and returns list of runs after date / time selection
1204  //
1205  // Runs generated between ]min;max[ are selected
1206  // - if min=NULL runs with date <max are selected
1207  // - if max=NULL runs with date >min are selected
1208  // - if max and min are NULL returns empty list
1209 
1210  if (!min_date && !max_date) return {};
1211 
1212  if (min_date) printf("date minimum %s\n", min_date.value().AsString());
1213  if (max_date) printf("date maximum %s\n", max_date.value().AsString());
1214 
1215  run_index_list numb;
1216 
1217  for (auto _sys : systems) {
1218  auto sys = (KVDBSystem*)_sys;
1219  auto lrun = GetListOfAvailableRunFilesForSystem(type, sys);
1220 
1221  for (auto _run : lrun) {
1222  auto run = (KVRunFile*)_run;
1223 
1224  if (min_date && max_date) {
1225  if (min_date.value() < run->GetFileWrittenDatime() && run->GetFileWrittenDatime() < max_date.value()) {
1226  numb.Add(run->GetRunIndex());
1227  }
1228  }
1229  else if (min_date) {
1230  if (min_date.value() < run->GetFileWrittenDatime()) {
1231  numb.Add(run->GetRunIndex());
1232  }
1233  }
1234  else if (max_date) {
1235  if (run->GetFileWrittenDatime() < max_date.value()) {
1236  numb.Add(run->GetRunIndex());
1237  }
1238  }
1239  }
1240  }
1241  return numb;
1242 
1243 }
1244 
1245 
1246 
1247 
1254 
1256 {
1257  // Returns list of runs which are present for data type "base_type" but not for "other_type"
1258  //
1259  // If pointer to system is given, only runs for the system are considered.
1260  //
1261  // If OnlyCol=kTRUE (kFALSE default) only systems with KVDBSystem::IsCollision()=kTRUE are considered
1262 
1263  run_index_list manquant;
1264  auto ll = GetListOfAvailableSystems(ref_type);
1265  if (ll.IsEmpty()) {
1266  //numb.Clear();
1267  Info("GetRunList_StageSelection", "No data available of type \"%s\"", ref_type.Data());
1268  return manquant;
1269  }
1270  if (system && !ll.FindObject(system)) {
1271  Info("GetRunList_StageSelection", "No data available of type \"%s\" for system %s", ref_type.Data(), system->GetName());
1272  return manquant;
1273  }
1274 
1275  Info("GetRunList_StageSelection", "Liste des runs presents dans \"%s\" mais absent dans \"%s\"", ref_type.Data(), type.Data());
1276 
1277  KVDBSystem* sys = 0;
1278 
1279  for (Int_t nl = 0; nl < ll.GetEntries(); nl += 1) {
1280 
1281  sys = (KVDBSystem*)ll.At(nl);
1282  if (system && sys != system) continue;
1283  if (OnlyCol && !sys->IsCollision()) continue;
1284  auto nsys = GetRunList(type, sys);
1285  auto nsys_ref = GetRunList(ref_type, sys);
1286  Int_t nref = nsys_ref.GetNValues();
1287 
1288  nsys_ref.Remove(nsys);
1289 
1290  Info("GetRunList_StageSelection", "\nKVDBSystem : %s --> %d runs manquants sur %d : %s",
1291  sys->GetName(),
1292  nsys_ref.GetNValues(),
1293  nref,
1294  nsys_ref.AsString().Data()
1295  );
1296  manquant.Add(nsys_ref);
1297  }
1298  return manquant;
1299 }
1300 
1301 
1302 
1308 
1309 run_index_list KVDataSet::GetRunList_StageSelection(const TString& type, const TString& ref_type, const KVUnownedList& systems, Bool_t OnlyCol)
1310 {
1311  // \returns list of runfiless which are present for data type "base_type" but not for "other_type"
1312  // for the systems (KVDBSystem pointers) in the list.
1313  //
1314  // If OnlyCol=kTRUE (kFALSE default) only systems with KVDBSystem::IsCollision()=kTRUE are considered
1315 
1316  run_index_list manquant;
1317  auto ll = GetListOfAvailableSystems(ref_type);
1318  if (ll.IsEmpty()) {
1319  //numb.Clear();
1320  Info("GetRunList_StageSelection", "No data available of type \"%s\"", ref_type.Data());
1321  return manquant;
1322  }
1323 
1324  Info("GetRunList_StageSelection", "Liste des runs presents dans \"%s\" mais absent dans \"%s\"", ref_type.Data(), type.Data());
1325 
1326  KVDBSystem* sys = 0;
1327 
1328  for (Int_t nl = 0; nl < ll.GetEntries(); nl += 1) {
1329 
1330  sys = (KVDBSystem*)ll.At(nl);
1331  if (!systems.Contains(sys)) continue;
1332  if (OnlyCol && !sys->IsCollision()) continue;
1333  auto nsys = GetRunList(type, sys);
1334  auto nsys_ref = GetRunList(ref_type, sys);
1335  Int_t nref = nsys_ref.GetNValues();
1336 
1337  nsys_ref.Remove(nsys);
1338 
1339  Info("GetRunList_StageSelection", "\nKVDBSystem : %s --> %d runs manquants sur %d : %s",
1340  sys->GetName(),
1341  nsys_ref.GetNValues(),
1342  nref,
1343  nsys_ref.AsString().Data()
1344  );
1345  manquant.Add(nsys_ref);
1346  }
1347  return manquant;
1348 }
1349 
1350 
1351 
1356 
1358 {
1359  // Returns list of runs of given type that were created with the given version of KaliVeda.
1360  //
1361  // If system!="" then only runs for the given system are considered
1362 
1363  run_index_list runs;
1364  if (sys) {
1365  auto lrun = GetListOfAvailableRunFilesForSystem(type, sys);
1366  TIter next(&lrun);
1367  KVRunFile* run;
1368  while ((run = (KVRunFile*)next())) {
1369  if (!strcmp(run->GetVersion(), version)) runs.Add(run->GetRunIndex());
1370  }
1371  return runs;
1372  }
1373  auto ll = GetListOfAvailableSystems(type);
1374  if (ll.IsEmpty()) {
1375  //numb.Clear();
1376  Info("GetRunList_VersionSelection", "No data available of type \"%s\"", type.Data());
1377  return runs;
1378  }
1379  Int_t nsys = ll.GetEntries();
1380  for (Int_t nl = 0; nl < nsys; nl += 1) {
1381  sys = (KVDBSystem*)ll.At(nl);
1382  auto lrun = GetListOfAvailableRunFilesForSystem(type, sys);
1383  TIter next(&lrun);
1384  KVRunFile* run;
1385  while ((run = (KVRunFile*)next())) {
1386  if (!strcmp(run->GetVersion(), version)) runs.Add(run->GetRunIndex());
1387  }
1388  }
1389  return runs;
1390 }
1391 
1392 
1393 
1398 
1399 void KVDataSet::CommitRunfile(const KVString& type, const run_index_t& run, TFile* file)
1400 {
1401  // Commit a runfile previously created with NewRunfile() to the repository.
1402  // Any previous version of the runfile will be deleted.
1403  // The available runs list for this data 'type' is updated.
1404 
1405  if (!fRepository) return;
1406 
1407  //keep name of file for updating available runs list
1408  TString newfile = gSystem->BaseName(file->GetName());
1409 
1410  fRepository->CommitFile(file, type, this);
1411  //update list of available datatypes of dataset,
1412  //in case this addition has created a new subdirectory
1413  CheckAvailable();
1414  //check if previous version of file exists
1415  //get name of file from available runs file
1416  //note that when the file is the first of a new subdirectory, GetAvailableRunsFile->GetFileName
1417  //will cause the available runs file to be created, and it will contain one entry:
1418  //the new file!
1419  TString oldfile = GetAvailableRunsFile(type)->GetFileName(run);
1420  if (oldfile != "" && oldfile != newfile) {
1421  //delete previous version - no confirmation
1422  fRepository->DeleteFile(this, type, oldfile.Data(),
1423  kFALSE);
1424  //was file deleted ? if so, remove entry from available runs file
1425  if (!fRepository->CheckFileStatus(this, type, oldfile.Data()))
1426  GetAvailableRunsFile(type)->Remove(run);
1427  }
1428  if (oldfile != newfile) {
1429  //add entry for new run in available runs file
1430  GetAvailableRunsFile(type)->Add(run, newfile.Data());
1431  }
1432 }
1433 
1434 
1435 
1436 
1442 
1444 {
1445  //if fUserGroups has been set with SetUserGroups(), we check that the current user's name
1446  //(gSystem->GetUserInfo()->fUser) appears in at least one of the groups in the list.
1447  //Returns kFALSE if user's name is not found in any of the groups.
1448  //if fUserGroups="" (default), we return kTRUE for all users.
1449 
1450  if (fUserGroups == "")
1451  return kTRUE; /* no groups set, all users have access */
1452 
1453  //split into array of group names
1454  unique_ptr<TObjArray> toks(fUserGroups.Tokenize(' '));
1455  TObjString* group_name;
1456  TIter next_name(toks.get());
1457  while ((group_name = (TObjString*) next_name())) {
1458  //for each group_name, we check if the user's name appears in the group
1459  if (!fRepository || (fRepository && fRepository->GetDataSetManager()->
1460  CheckUser(group_name->String().Data()))
1461  ) {
1462  return kTRUE;
1463  }
1464  }
1465  return kFALSE;
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  KVDataRepository* 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  Error("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  KVDataRepository* _or =
1704  gDataRepositoryManager->GetRepository(other_repos);
1705  if (_or)
1706  return CheckRunfileUpToDate(data_type, run, _or);
1707  Error("CheckRunfileUpToDate",
1708  "No data repository known with this name : %s", (const char*) other_repos);
1709  return kTRUE;
1710 }
1711 
1712 
1713 
1714 
1718 
1719 void KVDataSet::CheckUpToDate(const Char_t* data_type,
1720  const Char_t* other_repos)
1721 {
1722  //Check whether all files of type "data_type" for run number "run" in the data repository
1723  //are up to date (i.e. at least as recent) as compared to the files in data repository "other_repos".
1724 
1725  if (!fRepository) return;
1726 
1727  KVDataRepository* _or =
1728  gDataRepositoryManager->GetRepository(other_repos);
1729  if (!_or) {
1730  Error("CheckUpToDate",
1731  "No data repository known with this name : %s", other_repos);
1732  return;
1733  }
1734  auto runlist = GetAvailableRunsFile(data_type)->GetRunList();
1735  Int_t need_update = 0;
1736  for (auto& rr : runlist) {
1737  //check run
1738  if (!CheckRunfileUpToDate(data_type, rr, _or)) {
1739  cout << " *** run " << rr << " needs update ***" <<
1740  endl;
1741  cout << "\t\tREPOSITORY: " << fRepository->
1742  GetName() << "\tDATE: " << GetRunfileDate(data_type, rr).value().AsString() << endl;
1743  cout << "\t\tREPOSITORY: " << other_repos << "\tDATE: " << _or->
1744  GetDataSetManager()->GetDataSet(GetName())->
1745  GetRunfileDate(data_type, rr).value().AsString() << endl;
1746  need_update++;
1747  }
1748  }
1749  if (!need_update) {
1750  cout << " *** All runfiles are up to date for data type " <<
1751  data_type << endl;
1752  }
1753 }
1754 
1755 
1756 
1757 
1761 
1763  const Char_t* other_repos)
1764 {
1765  //Returns list of all runs of type "data_type" which may be updated
1766  //from the repository named "other_repos". See CheckUpToDate().
1767 
1768  run_index_list updates;
1769  if (!fRepository) return updates;
1770 
1771  KVDataRepository* _or =
1772  gDataRepositoryManager->GetRepository(other_repos);
1773  if (!_or) {
1774  Error("CheckUpToDate",
1775  "No data repository known with this name : %s", other_repos);
1776  return updates;
1777  }
1778  auto runlist = GetAvailableRunsFile(data_type)->GetRunList();
1779  for (auto& rr : runlist) {
1780  //check run
1781  if (!CheckRunfileUpToDate(data_type, rr, _or)) {
1782  //run is out of date
1783  updates.Add(rr);
1784  }
1785  }
1786  return updates;
1787 }
1788 
1789 
1790 
1791 
1796 
1798  const KVDBSystem* system) const
1799 {
1800  //Returns list of all files available for given "data_type"
1801  //
1802  //If a pointer to a reaction system is given, only files for the given system will be included in the list.
1803 
1804  if (!fRepository || !HasDataType(data_type)) {
1805  Error("GetRunList",
1806  "No data of type %s available. Runlist will be empty.",
1807  data_type);
1808  return {};
1809  }
1810 
1811  return GetAvailableRunsFile(data_type)->GetRunList(system);
1812 }
1813 
1814 
1815 
1816 
1847 
1849 {
1850  //This method returns a pointer to the available analysis task whose description (title) contains
1851  //all of the whitespace-separated keywords (which may be regular expressions)
1852  //given in the string "keywords". The comparison is case-insensitive.
1853  //
1854  //WARNING: this method can only be used to access analysis tasks that are
1855  //available for this dataset, i.e. for which the corresponding prerequisite data type
1856  //is available in the repository.
1857  //For unavailable data/tasks, use GetAnalysisTaskAny(const Char_t*).
1858  //
1859  //EXAMPLES
1860  //Let us suppose that the current dataset has the following list of tasks:
1861  //~~~
1862  // root [2] gDataSet->Print("tasks")
1863  // 1. Event reconstruction from raw data (raw->recon)
1864  // 2. Analysis of raw data
1865  // 3. Identification of reconstructed events (recon->ident)
1866  // 4. Analysis of reconstructed events (recon)
1867  // 5. Analysis of partially identified & calibrated reconstructed events (ident)
1868  // 6. Analysis of fully calibrated physical data (root)
1869  //~~~
1870  //Then the following will occur:
1871  //~~~
1872  // root [14] gDataSet->GetAnalysisTask("raw->recon")->Print()
1873  // KVDataAnalysisTask : Event reconstruction from raw data (raw->recon)
1874  //
1875  // root [10] gDataSet->GetAnalysisTask("analysis root")->Print()
1876  // KVDataAnalysisTask : Analysis of fully calibrated physical data (root)
1877  //~~~
1878 
1879  //case-insensitive search for matches in list based on 'title' attribute
1880  return (KVDataAnalysisTask*)fTasks.FindObjectAny("title", keywords, kTRUE, kFALSE);
1881 }
1882 
1883 
1884 
1885 
1887 
1889 {
1890  if (!dat->WithUserClass()) {
1891  Error("MakeAnalysisClass",
1892  "No user class required for analysis task \"%s\"", dat->GetTitle());
1893  return false;
1894  }
1895 
1896  //all analysis base classes must define a static Make(const Char_t * classname)
1897  //which generates the skeleton class files.
1898 
1899  TClass* cl = nullptr;
1900  //has the user base class for the task been compiled and loaded ?
1902  else
1903  return false;
1904 
1905  //set up call to static Make method
1906  unique_ptr<TMethodCall> methcall(new TMethodCall(cl, "Make", Form("\"%s\"", classname)));
1907 
1908  if (!methcall->IsValid()) {
1909  Error("MakeAnalysisClass", "static Make(const Char_t*) method for class %s is not valid",
1910  cl->GetName());
1911  return false;
1912  }
1913 
1914  //generate skeleton class
1915  methcall->Execute();
1916 
1917  return true;
1918 }
1919 
1920 
1921 
1934 
1935 bool KVDataSet::MakeAnalysisClass(const Char_t* task, const Char_t* classname)
1936 {
1937  //Create a skeleton analysis class to be used for analysis of the data belonging to this dataset.
1938  //
1939  // task = keywords contained in title of analysis task (see GetAnalysisTask(const Char_t*))
1940  // (you do not need to include 'analysis', it is added automatically)
1941  // classname = name of new analysis class
1942  //
1943  //Example:
1944  // MakeAnalysisClass("raw", "MyRawDataAnalysis")
1945  // --> make skeleton raw data analysis class in files MyRawDataAnalysis.cpp & MyRawDataAnalysis.h
1946  // MakeAnalysisClass("fully calibrated", "MyDataAnalysis")
1947  // --> make skeleton data analysis class in files MyDataAnalysis.cpp & MyDataAnalysis.h
1948 
1949  KVString _task = task;
1950  if (!_task.Contains("nalysis")) _task += " analysis";
1951  //We want to be able to write analysis classes even when we don't have any data
1952  //to analyse. Therefore we use GetAnalysisTaskAny.
1953  auto dat = GetAnalysisTaskAny(_task.Data());
1954  if (!dat) {
1955  Error("MakeAnalysisClass",
1956  "called for unknown or unavailable analysis task : %s", _task.Data());
1957  return false;
1958  }
1959  return make_analysis_class(dat, classname);
1960 }
1961 
1962 
1963 
1970 
1971 bool KVDataSet::MakeAnalysisClass(int task, const Char_t* classname)
1972 {
1973  //Create a skeleton analysis class to be used for analysis of the data belonging to this dataset.
1974  //
1975  // task = index of analysis task as shown in KVDataSet::Print("tasks")
1976  // classname = name of new analysis class
1977  //
1978 
1979  auto dat = GetAnalysisTask(task);
1980  if (!dat) {
1981  Error("MakeAnalysisClass",
1982  "called for unknown or unavailable analysis task index : %d", task);
1983  return false;
1984  }
1985  return make_analysis_class(dat, classname);
1986 }
1987 
1988 
1989 
1990 
1994 
1995 Bool_t KVDataSet::OpenDataSetFile(const Char_t* filename, ifstream& file)
1996 {
1997  // Look for (and open for reading, if found) the named file in the directory which
1998  // contains the files for this dataset (given by GetDataSetDir())
1999 
2000  return OpenDataSetFile(GetName(), filename, file);
2001 }
2002 
2003 
2004 
2008 
2009 Bool_t KVDataSet::OpenDataSetFile(const TString& dataset, const Char_t* filename, ifstream& file)
2010 {
2011  // Static method to look for (and open for reading, if found) the named file in the directory which
2012  // contains the files for the dataset
2013 
2014  TString datasetdir = KVBase::GetDataSetEnv(dataset, "DataSet.Directory", dataset);
2015  if (gSystem->IsAbsoluteFileName(datasetdir)) {
2016  // dataset directory is outside of standard KV installation directories
2017  // use absolute path to search for file
2018  TString abspath;
2019  abspath.Form("%s/%s", datasetdir.Data(), filename);
2020  return SearchAndOpenKVFile(abspath, file);
2021  }
2022  // dataset directory is a subdirectory of GetDATADIRFilePath()
2023  return SearchAndOpenKVFile(filename, file, datasetdir);
2024 }
2025 
2026 
2027 
2031 
2033 {
2034  // Find a file in the dataset directory (given by GetDataSetDir())
2035  // Returns full path to file if found, empty string if not
2036 
2037  return GetFullPathToDataSetFile(GetName(), filename);
2038 }
2039 
2040 
2041 
2045 
2047 {
2048  // Static method to find a file in the dataset directory (given by GetDataSetDir())
2049  // Returns full path to file if found, empty string if not
2050 
2051  TString fullpath;
2052  TString datasetdir = KVBase::GetDataSetEnv(dataset, "DataSet.Directory", dataset);
2053  if (!SearchKVFile(filename, fullpath, datasetdir)) {
2054  ::Warning("KVDataSet::GetFullPathToDataSetFile", "File %s not found in dataset subdirectory %s", filename, datasetdir.Data());
2055  fullpath = "";
2056  }
2057  return fullpath;
2058 }
2059 
2060 
2061 
2065 
2066 Bool_t KVDataSet::FindDataSetFile(const TString& dataset, const Char_t* filename)
2067 {
2068  // Static method to find a file in the dataset directory (given by GetDataSetDir())
2069  // Returns kTRUE if found, kFALSE if not
2070 
2071  TString fullpath;
2072  TString datasetdir = KVBase::GetDataSetEnv(dataset, "DataSet.Directory", dataset);
2073  return SearchKVFile(filename, fullpath, datasetdir);
2074 }
2075 
2076 
2077 
2081 
2083 {
2084  // Find a file in the dataset directory (given by GetDataSetDir())
2085  // Returns kTRUE if found, kFALSE if not
2086 
2087  return FindDataSetFile(GetName(), filename);
2088 }
2089 
2090 
2091 
2092 
2101 
2103 {
2104  //This method returns the analysis task whose description (title) contains
2105  //all of the whitespace-separated keywords (which may be regular expressions)
2106  //given in the string "keywords". The comparison is case-insensitive.
2107  //The analysis task does not need to be "available", i.e. the associated prerequisite
2108  //data type does not have to be present in the repository (see GetAnalysisTask).
2109  //
2110  // If no task is found, returns nullptr
2111 
2112  KVDataAnalysisTask* tsk = (KVDataAnalysisTask*)fAllTasks.FindObjectAny("title", keywords, kTRUE, kFALSE);
2113  if (!tsk) {
2114  Error("GetAnalysisTaskAny", "No task found with the following keywords in its title : %s", keywords);
2115  }
2116  return tsk;
2117 }
2118 
2119 
2120 
2121 
2127 
2129 {
2130  // Returns kTRUE if database needs to be regenerated from source files,
2131  // i.e. if source files are more recent than DataBase.root
2132  // In case no directory exists for dataset (dataset added 'on the fly')
2133  // we create the directory and fill it with dummy files (Makefile, Runlist.csv, Systems.dat)
2134 
2135  TString pwd = gSystem->pwd();
2136 
2137  TString path = "";
2138  if (!SearchKVFile(GetDataSetDir(), path)) {
2139  // dataset directory doesn't exist - create it
2140  Info("DataBaseNeedsUpdate", "%s: Creating new dataset directory %s",
2141  GetName(), GetDataSetDir());
2142  if (gSystem->mkdir(GetDataSetDir())) {
2143  // problem creating directory
2144  Error("DataBaseNeedsUpdate",
2145  "%s: Dataset directory %s does not exist and cannot be created ?",
2146  GetName(), GetDataSetDir());
2147  return kFALSE;
2148  }
2149  // create dummy files
2150  SearchKVFile(GetDataSetDir(), path); // get full path
2151  path += "/";
2152  TString filename = path + "Makefile";
2153  ofstream of1(filename.Data());
2154  of1 << "$(KV_WORK_DIR)/db/" << GetName() << "/DataBase.root : Runlist.csv Systems.dat" << endl;
2155  of1 << "\t@echo Database needs update" << endl;
2156  of1.close();
2157  filename = path + "Runlist.csv";
2158  ofstream of2(filename.Data());
2159  of2 << "# Automatically generated dummy Runlist.csv file" << endl;
2160  of2.close();
2161  filename = path + "Systems.dat";
2162  ofstream of3(filename.Data());
2163  of3 << "# Automatically generated dummy Systems.dat file" << endl;
2164  of3.close();
2165  }
2166  gSystem->cd(GetDataSetDir());
2167  TString cmd = "make -q";
2168  Int_t ret = gSystem->Exec(cmd.Data());
2169  gSystem->cd(pwd.Data());
2170  return (ret != 0);
2171 }
2172 
2173 
2174 
2191 
2193 {
2194  // Returns name of output repository for given task.
2195  // By default it is the name of the repository associated with this dataset,
2196  // but can be changed by the following environment variables:
2197  //
2198  // [repository].DefaultOutputRepository: [other repository]
2199  // - this means that all tasks carried out on data in [repository]
2200  // will have their output files placed in [other repository]
2201  //
2202  // [taskname].DataAnalysisTask.OutputRepository: [other repository]
2203  // - this means that for [taskname], any output files will
2204  // be placed in [other repository]
2205  //
2206  // [dataset].[taskname].DataAnalysisTask.OutputRepository: [other repository]
2207  // - this means that for given [dataset] & [taskname],
2208  // any output files will be placed in [other repository]
2209 
2210  if (gEnv->Defined(Form("%s.DataRepository.DefaultOutputRepository", GetRepository()->GetName())))
2211  return TString(gEnv->GetValue(Form("%s.DataRepository.DefaultOutputRepository", GetRepository()->GetName()), ""));
2212  TString orep = GetDataSetEnv(Form("%s.DataAnalysisTask.OutputRepository", taskname), GetRepository()->GetName());
2213  return orep;
2214 }
2215 
2216 
2217 
2218 
2221 
2222 void KVDataSet::CopyRunfilesFromRepository(const Char_t* type, const run_index_list& runs, const Char_t* destdir)
2223 {
2224  // Copies the runfiles of given "type" into the local directory "destdir".
2225 
2226  KVDataRepository* repo = GetRepository();
2227  for (auto& run : runs) {
2228  TString filename = GetRunfileName(type, run);
2229  TString destpath;
2230  AssignAndDelete(destpath, gSystem->ConcatFileName(destdir, filename));
2231  repo->CopyFileFromRepository(this, type, filename, destpath);
2232  }
2233 }
2234 
2235 
2236 
2237 
2241 
2242 void KVDataSet::CopyRunfilesToRepository(const Char_t* type, const run_index_list& runs, const Char_t* destrepo)
2243 {
2244  // Copies the runfiles of given "type" from the data repository associated
2245  // with this dataset into the local repository "destrepo".
2246 
2247  KVDataRepository* repo = GetRepository();
2248  KVDataRepository* dest_repo = gDataRepositoryManager->GetRepository(destrepo);
2249 
2250  if (!dest_repo) {
2251  Error("CopyRunfilesToRepository", "Unknown destination repository : %s", destrepo);
2252  gDataRepositoryManager->Print();
2253  return;
2254  }
2255 
2256  KVDataSet* dest_ds = dest_repo->GetDataSetManager()->GetDataSet(GetName());
2257  dest_repo->CreateAllNeededSubdirectories(dest_ds, type);
2258  for (auto& run : runs) {
2259  TString filename = GetRunfileName(type, run);
2260  TString destpath = dest_repo->GetFullPathToTransferFile(dest_ds, type, filename);
2261  repo->CopyFileFromRepository(this, type, filename, destpath);
2262  }
2263 }
2264 
2265 
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:304
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:101
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:896
TString GetFullPathToRunfile(const KVString &type, const run_index_t &run) const
Definition: KVDataSet.cpp:852
TString GetFullPathToDB() const
Definition: KVDataSet.cpp:153
void ls(Option_t *opt="") const override
Print dataset information.
Definition: KVDataSet.cpp:377
TString GetOutputRepository(const Char_t *taskname) const
Definition: KVDataSet.cpp:2192
virtual void OpenDBFile(const Char_t *full_path_to_dbfile) const
Open the database from a file on disk.
Definition: KVDataSet.cpp:127
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:992
virtual const Char_t * GetBaseFileName(const Char_t *type, const run_index_t &run) const
Definition: KVDataSet.cpp:1025
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:1719
run_index_list GetRunList(const Char_t *data_type, const KVDBSystem *sys=0) const
Definition: KVDataSet.cpp:1797
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:2222
KVDataRepository * GetRepository() const
Get pointer to data repository in which dataset is stored.
Definition: KVDataSet.cpp:1486
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:1201
const Char_t * GetDataSetDir() const
Definition: KVDataSet.cpp:728
void CommitRunfile(const KVString &type, const run_index_t &run, TFile *file)
Definition: KVDataSet.cpp:1399
virtual void AddAvailableDataType(const Char_t *)
Definition: KVDataSet.cpp:490
KVUniqueNameList GetSystemsForRunFiles(const TString &datatype, const run_index_list &) const
Definition: KVDataSet.cpp:655
bool make_analysis_class(const KVDataAnalysisTask *, const Char_t *classname)
Definition: KVDataSet.cpp:1888
KVDataAnalysisTask * GetAnalysisTask(Int_t) const
Definition: KVDataSet.cpp:556
KVAvailableRunsFile * GetAvailableRunsFile(const TString &type) const
Definition: KVDataSet.cpp:51
virtual void SaveDataBase() const
Definition: KVDataSet.cpp:203
virtual KVDataAnalysisTask * GetAnalysisTaskAny(const Char_t *keywords) const
Definition: KVDataSet.cpp:2102
virtual void SetAnalysisTasks(const KVSeqCollection *)
Definition: KVDataSet.cpp:507
TFile * NewRunfile(const KVString &type, const run_index_t &run)
Definition: KVDataSet.cpp:1098
KVList GetListOfAvailableRunFilesForSystem(const TString &datatype, KVDBSystem *systol)
Definition: KVDataSet.cpp:611
Bool_t CheckRunfileUpToDate(const KVString &data_type, const run_index_t &run, KVDataRepository *other_repos)
Definition: KVDataSet.cpp:1659
virtual void CheckAvailable()
Definition: KVDataSet.cpp:443
void DeleteRunfile(const KVString &type, const run_index_t &run, Bool_t confirm=kTRUE)
Definition: KVDataSet.cpp:1123
virtual Int_t GetNtasks() const
Definition: KVDataSet.cpp:541
TString GetFullPathToDataSetFile(const Char_t *filename)
Definition: KVDataSet.cpp:2032
run_index_list GetRunList_VersionSelection(const TString &type, const TString &version, KVDBSystem *sys=0)
Definition: KVDataSet.cpp:1357
void DeleteRunfiles(const Char_t *type, const run_index_list &lrun={}, Bool_t confirm=kTRUE)
Definition: KVDataSet.cpp:1170
TObject * open_runfile(const KVString &type, const run_index_t &run)
Definition: KVDataSet.cpp:800
void CopyRunfilesToRepository(const Char_t *type, const run_index_list &runs, const Char_t *destrepo)
Definition: KVDataSet.cpp:2242
KVString GetRunfileName(const KVString &type, const run_index_t &run) const
Definition: KVDataSet.cpp:872
KVExpDB * GetDataBase(Option_t *opt="") const
Definition: KVDataSet.cpp:285
virtual Bool_t DataBaseNeedsUpdate() const
Definition: KVDataSet.cpp:2128
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:1255
void cd() const
Definition: KVDataSet.cpp:750
virtual 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:400
void SetName(const char *name) override
Definition: KVDataSet.cpp:690
virtual Bool_t CheckUserCanAccess()
Definition: KVDataSet.cpp:1443
void UpdateAvailableRuns(const KVString &type)
Definition: KVDataSet.cpp:1069
run_index_list GetUpdatableRuns(const Char_t *data_type, const Char_t *other_repos)
Definition: KVDataSet.cpp:1762
void SetRepository(KVDataRepository *)
Set pointer to data repository in which dataset is stored.
Definition: KVDataSet.cpp:1474
bool MakeAnalysisClass(const Char_t *task, const Char_t *classname)
Definition: KVDataSet.cpp:1935
KVDataSet()
Default constructor.
Definition: KVDataSet.cpp:35
std::optional< run_index_t > GetRunNumberFromFileName(const TString &datatype, const TString &filename)
Definition: KVDataSet.cpp:945
void CleanMultiRunfiles(const Char_t *data_type, Bool_t confirm=kTRUE)
Definition: KVDataSet.cpp:1546
virtual void OpenDataBase(Option_t *opt="") const
Definition: KVDataSet.cpp:319
static Bool_t FindDataSetFile(const TString &dataset, const Char_t *filename)
Definition: KVDataSet.cpp:2066
KVUnownedList GetListOfAvailableSystems(const TString &datatype)
Definition: KVDataSet.cpp:571
TString GetDBFileName() const
Definition: KVDataSet.cpp:83
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:576
static KVExpDB * MakeDataBase(const Char_t *name, const Char_t *datasetdir)
Definition: KVExpDB.cpp:598
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,...)
const char * String
v
TArc a
ClassImp(TPyArg)