KaliVeda
Toolkit for HIC analysis
KVAvailableRunsFile.cpp
1 /*
2 $Id: KVAvailableRunsFile.cpp,v 1.18 2009/03/12 14:01:02 franklan Exp $
3 $Revision: 1.18 $
4 $Date: 2009/03/12 14:01:02 $
5 */
6 
7 //Created by KVClassFactory on Fri May 5 10:46:40 2006
8 //Author: franklan
9 
10 #include "KVAvailableRunsFile.h"
11 #include "KVDBRun.h"
12 #include "TObjArray.h"
13 #include "TObjString.h"
14 #include "KVString.h"
15 #include "KVList.h"
16 #include "KVDataRepository.h"
17 #include "KVRunFile.h"
18 
20 
22 
23 
24 
33 std::optional<run_index_t> KVAvailableRunsFile::IsRunFileName(const Char_t* filename)
34 {
35  // This method tests the string given as 'filename' to see if it could be the name of a runfile
36  // of the datatype of this available runs file (GetDataType()), for its parent dataset, fDataSet.
37  // Any protocol and/or path information in the filename is first removed.
38  //
39  // The format for a given dataset is defined by variable
40  //
41  // [dataset].DataSet.RunFileName.[datatype]: [format]
42 
43  TString fmt = fDataSet->GetDataSetEnv(Form("DataSet.RunFileName.%s", GetDataType()), ""); //get format string for current dataset
44  if (fmt == "") {
45  Error("IsRunFileName", "No default format set for datatype: %s",
46  GetDataType());
47  return {};
48  }
49  return IsRunFileName(fmt, filename);
50 }
51 
52 
53 
99 
100 std::optional<run_index_t> KVAvailableRunsFile::IsRunFileName(const KVString& fmt, const KVString& filename, const KVString& separators)
101 {
102  // This method tests the string given as 'filename' to see if it could be the name of a runfile.
103  // Any protocol and/or path information in the filename is first removed.
104  // The decision as to whether the filename is valid or not is based on whether it corresponds
105  // to the given format string, e.g. run_%04d.dat
106  //
107  // If good, we return the run number & eventual index as a std::optional<run_index_t>
108  // (if no index is defined for the file i.e. if %I does not appear in the format,
109  // this part of the run_index_t has no value).
110  //
111  // If not, the std::optional has no value. This can be tested as:
112  //
113  //~~~{.cpp}
114  // if(toto.IsRunFileName(...))
115  // {
116  // ...ok, filename is good & run number was retrieved
117  // }
118  //~~~
119  //
120  // KNOWN CASES:
121  //~~~
122  // dataset example filename format
123  // ======= ================ =====================
124  // INDRA_camp1 run127.raw run%R.raw
125  // INDRA_camp2 run127.raw run%R.raw
126  // INDRA_camp4 run127.raw run%R.raw
127  // INDRA_camp5 run127.raw run%R.raw
128  // INDRA_e416a Run356_06-Oct-05_12_44_12.dat Run%R_%D.dat
129  // INDRA_e475s run_0085.dat.13-Mar-06.12:46:24 run_%R.dat.%D1.%D2
130  // INDRA_e494s run_0026.dat.04-May-07.20:33:00 run_%R.dat.%D1.%D2
131  // INDRA_e503 run_0026.dat.04-May-07.20:33:00 run_%R.dat.%D1.%D2
132  // INDRA_e613 run_0022.dat.08Sep11_00h54m47s run_%R.dat.%D
133  // INDRAFAZIA.E789 run_0017.dat.04-04-19_08h25m57s.1 run_%R.dat.%D.%I
134  // FAZIA* run000345 run%R
135  //
136  // %R : run number
137  // %D : date and time
138  // %D1.%D2 : date and time separated by '.'
139  // %I : file index number. WARNING: the first file has NO index, the
140  // second file has index '1', etc. The index returned for the first
141  // file is zero.
142  //~~~
143  //
144  // The filename will be broken up according to the separators (default: ".")
145  // Then the different parts will be analysed according to the given format string
146  KVString _file(gSystem->BaseName(filename)); //Remove protocol and/or path
147 
148  // the filename should contain the same number of "."-separated parts as the format
149  // string, unless the format contains "%I", in which case it can have one less part
150  // (case of first file for run with no index)
151  int np_fmt = fmt.GetNValues(separators);
152  bool with_index = fmt.Contains("%I");
153  bool two_part_date = false;
154  bool got_date = false;
155  int np_fn = _file.GetNValues(separators);
157  KVString _fmt = fmt;
158  if (np_fn == np_fmt + 1) {
159  // if there is 1 more segment after splitting of the filename than in the format string,
160  // try adding an index at the end
161  _fmt.Append(".%I");
162  with_index = true;
163  ++np_fmt;
164  }
165  if (np_fmt == np_fn || (with_index && np_fn == np_fmt - 1)) {
166  _file.Begin(separators);
167  _fmt.Begin(separators);
168  int index(-1), run(0);
169  char date1[100], date2[100];
170  if (fmt.Contains("%D1") && fmt.Contains("%D2")) two_part_date = true;
171 
172  while (!_file.End()) {
173  KVString run_part = _file.Next();
174  KVString fmt_part = _fmt.Next();
175 
176  if (fmt_part.Contains("%R")) {
177  fmt_part.ReplaceAll("%R", "%d");
178  if (fmt_part.Contains("%D")) {
179  fmt_part.ReplaceAll("%D", "%s");
180  sscanf(run_part.Data(), fmt_part.Data(), &run, date1);
181  got_date = true;
182  }
183  else
184  sscanf(run_part.Data(), fmt_part.Data(), &run);
185  }
186  else if (fmt_part.Contains("%I")) {
187  fmt_part.ReplaceAll("%I", "%d");
188  sscanf(run_part.Data(), fmt_part.Data(), &index);
189  }
190  else if (fmt_part.Contains("%D1")) {
191  fmt_part.ReplaceAll("%D1", "%s");
192  sscanf(run_part.Data(), fmt_part.Data(), date1);
193  got_date = true;
194  }
195  else if (fmt_part.Contains("%D2")) {
196  fmt_part.ReplaceAll("%D2", "%s");
197  sscanf(run_part.Data(), fmt_part.Data(), date2);
198  got_date = true;
199  }
200  else if (fmt_part.Contains("%D")) {
201  fmt_part.ReplaceAll("%D", "%s");
202  sscanf(run_part.Data(), fmt_part.Data(), date1);
203  got_date = true;
204  }
205  }
206  if (got_date) {
207  if (two_part_date) date_read_from_filename.Form("%s.%s", date1, date2);
208  else date_read_from_filename = date1;
209  }
210  if (with_index) return run_index_t{run, index};
211  else return run_index_t{run, std::nullopt};
212  }
213  return {};
214 }
215 
216 
217 
223 
225 {
226  // We assume that 'name' is the name of a runfile according to given format 'fmt'.
227  // (see KVAvailableRunsFile::IsRunFileName for accepted formats for runfile names with dates).
228  // We attempt several methods to try to extract a date from 'name'.
229  // If successful, we return kTRUE and 'date' contains the result.
230 
231  auto run = IsRunFileName(fmt, name);
232  if (!run) return kFALSE;
233  // if runfile name contains a date, it is now in variable date_read_from_filename
234  if (date_read_from_filename == "") return kFALSE;
239  return kTRUE;
240  }
241  else {
245  return kTRUE;
246  }
249  return kTRUE;
250  }
253  return kTRUE;
254  }
255  }
256  return kFALSE;
257 }
258 
259 
260 
262 
264 {
265  FileStat_t fs;
266  if (repository->GetFileInfo(fDataSet, GetDataType(), objs->GetName(), fs)) {
267  //runfile exists in repository
268  modt = KVDatime(fs.fMtime);
269  return kTRUE;
270  }
271  return kFALSE;
272 }
273 
274 
275 
277 
279  const KVBase* objs,
280  KVSQLite::database* RunListTable,
281  const run_index_t& run_num,
282  KVDBRun* run
283  , bool with_version_and_username)
284 {
285  KVString filename = objs->GetName();
286  KVDatime modt;
287  if (get_file_modification_date(repository, objs, modt)) {
288  insert_runfile_into_database(repository, filename, modt, RunListTable, run_num, run, with_version_and_username);
289  return true;
290  }
291  return false;
292 }
293 
294 
295 
297 
298 void KVAvailableRunsFile::insert_runfile_into_database(KVDataRepository* repository, const KVString& filename, const KVDatime& modt, KVSQLite::database* RunListTable,
299  const run_index_t& run_num, KVDBRun* run, bool with_version_and_username)
300 {
301  auto& runs_table = RunListTable->get_table("Available_Runs");
302  runs_table.prepare_insert_single_row();
303  runs_table["run"] = run_num.run();
304  if (run_num.has_index())
305  runs_table["index"] = run_num.index();
306  else
307  runs_table["index"].set_null();
308  runs_table["filename"] = filename;
309  runs_table["date"] = modt.AsSQLString();
310  int sys_id = 1;
311  // is the run associated with a system which is already in the db?
312  if (run && run->GetSystem()) {
313  auto& sys_table = RunListTable->get_table("Systems");
314  if (!RunListTable->count("Systems", "*", Form("system = '%s'", run->GetSystemName()))) {
315  // system not in table; need to add it
316  sys_table.prepare_insert_single_row();
317  sys_table["system"] = run->GetSystemName();
318  sys_table.insert_single_row();
319  }
320  // now retrieve system id for foreign key cross-reference
321  RunListTable->select_data("Systems", "id", Form("system = '%s'", run->GetSystemName()));
322  while (RunListTable->get_next_result())
323  sys_id = sys_table["id"].get_data<int>();
324  }
325  runs_table["sys_id"] = sys_id;
326  if (with_version_and_username) {
327  std::unique_ptr<UserGroup_t> userinfo(gSystem->GetUserInfo());
328  runs_table["username"] = userinfo->fUser;
329  runs_table["version"] = GetKVVersion();
330  }
331  runs_table.insert_single_row();
332 }
333 
334 
335 
345 
346 void KVAvailableRunsFile::Update(const std::unique_ptr<KVSQLite::database>& db_handle)
347 {
348  // Examine the contents of the repository directory corresponding to this datatype
349  // for parent dataset fDataSet.
350  //
351  // For each file found which was not already in the list of available runs and
352  // we add an entry to the available runlist database file.
353  //
354  // This may be called by OpenAvailableRunsFile() in order to initially create
355  // the new db file: in this case db_handle contains the pointer to the (already open) db.
356 
357 
358  KVSQLite::database* RunListTable;
359  std::unique_ptr<KVSQLite::database> _db;
360  if (db_handle) {
361  // we have been called by OpenAvailableRunsFile() to create a new db file
362  RunListTable = db_handle.get();
363  }
364  else {
365  // we have been called to either create or update an existing db file
366  _db = OpenAvailableRunsFile(true);
367  RunListTable = _db.get();
368  }
369 
370  auto& runs_table = RunListTable->get_table("Available_Runs");
371  auto& sys_table = RunListTable->get_table("Systems");
372 
373  KVDataRepository* repository = fDataSet->GetRepository();
374 
375  std::cout << std::endl << "Updating runlist : " << std::flush;
376  //get directory listing from repository
377  auto dir_list = repository->GetDirectoryListing(fDataSet, GetDataType());
378  if (!dir_list)
379  return;
380 
381  TIter next(dir_list.get());
382  KVBase* objs;
383  //progress bar
384  Int_t ntot = dir_list->GetSize();
385  Int_t n5pc = TMath::Max(ntot / 20, 1);
386  Int_t ndone = 0;
387  std::unique_ptr<KVExpDB> db_garbage;
388  KVExpDB* db = fDataSet->GetDataBase();
389  if (!db) {
390  db = new KVExpDB();
391  db_garbage.reset(db);//clean up
392  }
393  while ((objs = (KVBase*) next())) { // loop over all files in directory
394 
395  auto run_num = IsRunFileName(objs->GetName());
396 
397  if (run_num) { // file has correct name format for runfile
398 
399  KVDBRun* run = db->GetDBRun(run_num.value().run());
400 
401  if(!run)
402  {
403  // if dataset has an index multiplier, this may be a recon file with an artificial run number
404  if(db->HasIndexMultiplier())
405  {
406  // try to decompose run number into run + index
407  auto r = run_num.value().run()/db->GetIndexMultiplier();
408  auto i = run_num.value().run()%db->GetIndexMultiplier();
409  run_num->clear();
410  run_num->set_run(r); if(i) run_num->set_index(i);
411  run = db->GetDBRun(r);
412  }
413  }
414 
415  if (run) { // the run number is included in the database of runs
416 
417  bool add_to_db = true;
418  if (!making_new_db) {
419  // is there an entry for the same run/index & filename in the database?
420  int occurences = 0;
421  auto selection = SelectFileName(objs->GetName()) + " AND " + SelectRunAndOrIndex(run_num.value());
422  occurences = RunListTable->count("Available_Runs", "*", selection);
423  add_to_db = (occurences == 0);
424  }
425 
426  if (add_to_db) {
427  insert_runfile_into_database(repository, objs, RunListTable, run_num.value(), run);
428  }
429  }
430  else { // run not included in database of runs
431  Info("Update", "the current run [%s] is not in database", objs->GetName());
432  if (!insert_runfile_into_database(repository, objs, RunListTable, run_num.value(), nullptr))
433  Warning("Update", "%s GetFileInfo return kFALSE", objs->GetName());
434  }
435  }
436 
437  ndone++;
438  if (!(ndone % n5pc))
439  std::cout << '>' << std::flush;
440  }
441 
442  std::cout << " DONE" << std::endl;
443  making_new_db = false;
444 }
445 
446 
447 
448 
455 
456 Bool_t KVAvailableRunsFile::GetRunInfo(const run_index_t& run, TDatime& modtime, TString& filename)
457 {
458  // Look for a given run/index number in the file, and read the file's modification date/time and filename
459  // If run not found, returns kFALSE
460  // If available runs file does not exist, Update() is called to create it.
461  // If there are multiple versions of the same run (abnormal situation),
462  // we print a warning and give info on the most recent file.
463 
464  KVList filenames, dates;
465  //get infos for all versions of run
466  GetRunInfos(run, &dates, &filenames);
467  if (filenames.GetEntries() == 1) { //only one version
468  filename = ((TObjString*) filenames.First())->String();
469  modtime = ((TObjString*) dates.First())->String().Data();
470  return kTRUE;
471  }
472  else if (filenames.GetEntries() > 1) { //several versions
473  Warning("GetRunInfo",
474  "Multiple versions of this runfile exist in the repository. Infos for most recent file will be returned.");
475  Warning("GetRunInfo",
476  "You should clean the repository using KVDataSet::CleanMultiRunfiles.");
477  //find most recent version
478  TDatime most_recent("1998-12-25 00:00:00");
479  Int_t i_most_recent = 0;
480  for (int i = 0; i < dates.GetEntries(); i++) {
481  //check if run is most recent
482  TDatime rundate(((TObjString*) dates.At(i))->String().Data());
483  if (rundate > most_recent) {
484  most_recent = rundate;
485  i_most_recent = i;
486  }
487  }
488  filename = ((TObjString*) filenames.At(i_most_recent))->String();
489  modtime = ((TObjString*) dates.At(i_most_recent))->String().Data();
490  return kTRUE;
491  }
492  return kFALSE;
493 }
494 
495 
496 
497 
507 
509 {
510  //Look for a given run/index in the database, and store the file's modification date/time and filename
511  //in the two KVList as TObjString objects (these objects belong to the
512  //lists and will be deleted by them).
513  //
514  //We do not stop at the first run found, but add informations for every occurence of the run in the database
515  //(however, we do ignore any spurious duplicate entries if they exist)
516  //
517  //If available runs db does not exist, it will be created
518 
519  auto RunDB = OpenAvailableRunsFile();
520 
521  //clear lists - delete objects
522  dates->Delete();
523  files->Delete();
524 
525  auto& runtable = RunDB->get_table("Available_Runs");
526  if (RunDB->select_data("Available_Runs", "filename,date", SelectRunAndOrIndex(run), kTRUE)) {
527  while (RunDB->get_next_result()) {
528  dates->Add(new TObjString(runtable["date"].data().GetString()));
529  files->Add(new TObjString(runtable["filename"].data().GetString()));
530  }
531  }
532  else {
533  Error("GetRunInfos", "DB query failure? selection=%s", SelectRunAndOrIndex(run).Data());
534  }
535 }
536 
537 
538 
547 
548 std::unique_ptr<TList> KVAvailableRunsFile::GetListOfAvailableSystems(const KVDBSystem* systol)
549 {
550  //Create and fill a sorted list of available systems based on the runs in the available runs db.
551  //If systol!=0 then create and fill a list of available files (KVRunFile objects) for the given system.
552  //
553  //For each system in the list we set the number of available runs : this number
554  //can be retrieved with KVDBSystem::GetNumberRuns()
555  //
556  // Note that 'bad' runfiles are excluded
557 
558  auto sys_list = std::make_unique<TList>();
559 
560  KVExpDB* db = fDataSet->GetDataBase();
561  std::unique_ptr<KVExpDB> garbage_db;
562  if (!db) {
563  db = new KVExpDB;
564  garbage_db.reset(db);//clean up
565  }
566 
567  auto runDB = OpenAvailableRunsFile();
568 
569  if (systol) {
570  // list of runfiles for given system
571  sys_list->SetOwner(kTRUE);
572  runDB->select_data("Available_Runs,Systems", "run,index,filename,date,version,username", Form("system = '%s'", systol->GetName()), true);
573  while (runDB->get_next_result()) {
574  auto a_run = db->GetDBRun((*runDB)["Available_Runs"]["run"].get_data<int>());
575  auto run = a_run->GetNumber();
576  std::optional<int> index = ((*runDB)["Available_Runs"]["index"].is_null() ?
577  std::nullopt : std::optional<int>((*runDB)["Available_Runs"]["index"].get_data<int>()));
578  KVDatime fDatime((*runDB)["Available_Runs"]["date"].get_data<TString>(), KVDatime::kSQL);
579  KVString kvversion = (*runDB)["Available_Runs"]["version"].get_data<KVString>();
580  KVString username = (*runDB)["Available_Runs"]["username"].get_data<KVString>();
581  KVString filename = (*runDB)["Available_Runs"]["filename"].get_data<KVString>();
582  if (IsCalled("raw")) {
583  // for raw data files, use the actual date/time of the start of data taking in the database
584  TString start_date = a_run->GetRunFile({run, index}).GetStartDate();
585  if (start_date != "") fDatime.Set(start_date);
586  }
587  if(!db->GetDBRunFile({run, index}).IsBad())
588  sys_list->Add(new KVRunFile(a_run, {run, index}, filename, fDatime, kvversion, username));
589  }
590  }
591  else {
592  // list of systems for available runs
593  sys_list->SetOwner(kFALSE);
594  runDB->select_data("Systems", "system", "id > 1");
595  while (runDB->get_next_result()) {
596  auto sys = db->GetSystem((*runDB)["Systems"]["system"].get_data<TString>());
597  if (sys && sys->GetNGoodRunFiles()) sys_list->Add(sys);
598  }
599  // set number of runs & events associated with each system
600  TIter it_sys(sys_list.get());
601  while (auto sys = (KVDBSystem*)it_sys()) {
602  runDB->select_data("Available_Runs,Systems", "run,index", Form("system = '%s'", sys->GetName()), true);
603  std::map<int, int> nruns;
604  ULong64_t events = 0;
605  while (runDB->get_next_result()) {
606  auto run = (*runDB)["Available_Runs"]["run"].get_data<int>();
607  auto index = (*runDB)["Available_Runs"]["index"].is_null() ? -1 : (*runDB)["Available_Runs"]["index"].get_data<int>();
608  if(!db->GetDBRunFile({run, index}).IsBad()){
609  ++nruns[run];
610  events += db->GetDBRunFile({run, index}).GetEvents();
611  }
612  }
613  sys->SetNumberRuns(nruns.size());
614  sys->SetEvents(events);
615  }
616  }
617 
618  //sort list of systems in order of increasing run number
619  //sort list of runs in order of increasing run number
620  if (sys_list && sys_list->GetSize() > 1)
621  sys_list->Sort();
622 
623  return sys_list;
624 }
625 
626 
627 
632 
633 void KVAvailableRunsFile::UpdateInfos(const run_index_t& run, const KVString& filename, const KVString& kvversion, const KVString& username)
634 {
635  // Call this method to update informations on the file "filename" corresponding to run,
636  // by adding/replacing the KV version and username read from the file itself (not necessarily
637  // corresponding to current KV version and username)
638 
639  auto runDB = OpenAvailableRunsFile();
640 
641  auto selection = SelectRunAndOrIndex(run) + " AND " + SelectFileName(filename);
642 
643  (*runDB)["Available_Runs"]["version"] = kvversion;
644  (*runDB)["Available_Runs"]["username"] = username;
645  runDB->update("Available_Runs", "version,username", selection);
646 }
647 
648 
649 
652 
653 void KVAvailableRunsFile::Remove(const run_index_t& run, const KVString& filename)
654 {
655  //Remove from the db ALL entries corresponding to the given run/index (and filename if given)
656 
657  auto runDB = OpenAvailableRunsFile();
658 
659  auto selection = SelectRunAndOrIndex(run);
660  if (!filename.IsNull()) selection += " AND " + SelectFileName(filename);
661 
662  runDB->delete_data("Available_Runs", selection);
663 }
664 
665 
666 
667 
671 
672 void KVAvailableRunsFile::Add(const run_index_t& run, const KVString& filename)
673 {
674  //Add to the file an entry corresponding to this run, assumed to be present in the repository
675  //with the given filename.
676 
677  auto runDB = OpenAvailableRunsFile();
678 
680 }
681 
682 
683 
686 
687 std::forward_list<run_index_t> KVAvailableRunsFile::CheckMultiRunfiles()
688 {
689  //Returns a list with all run/indexes for which more than one file is in the available runs db
690 
691  std::forward_list<run_index_t> multiruns;
692 
693  auto runDB = OpenAvailableRunsFile();
694 
695  runDB->select_data("Available_Runs", "run,index,COUNT(*)", "", false, "GROUP BY run, index HAVING COUNT(*)>1");
696 
697  while (runDB->get_next_result()) {
698  multiruns.push_front({(*runDB)["Available_Runs"]["run"].get_data<int>(),
699  ((*runDB)["Available_Runs"]["index"].is_null() ?
700  std::nullopt : std::optional<int>((*runDB)["Available_Runs"]["index"].get_data<int>()))});
701  }
702  return multiruns;
703 }
704 
705 
706 
707 
715 
716 run_index_list KVAvailableRunsFile::GetRunList(const KVDBSystem* sys)
717 {
718  //Returns list of available run/indexes for this data type.
719  //
720  //If 'sys' gives the address of a valid database reaction system, only files
721  //corresponding to the system will be included.
722  //
723  //Note that runfiles which are considered to be 'bad' are excluded
724 
725  TString selection, tables("Available_Runs");
726  if (sys) {
727  selection = Form("system = '%s'", sys->GetName());
728  tables += ",Systems";
729  }
730 
731  KVExpDB* db = fDataSet->GetDataBase();
732  std::unique_ptr<KVExpDB> garbage_db;
733  if (!db) {
734  db = new KVExpDB;
735  garbage_db.reset(db);//clean up
736  }
737 
738  auto runDB = OpenAvailableRunsFile();
739 
740  runDB->select_data(tables, "run,index", selection);
741  run_index_list l;
742  while (runDB->get_next_result()) {
743  auto run = (*runDB)["Available_Runs"]["run"].get_data<int>();
744  auto index = (*runDB)["Available_Runs"]["index"].is_null() ? -1 : (*runDB)["Available_Runs"]["index"].get_data<int>();
745  if(!db->GetDBRunFile({run,index}).IsBad())
746  l.Add({run,index});
747  }
748  return l;
749 }
750 
751 
752 
759 
761 {
762  // Filename of file containing information on available runs
763  // i.e. [repository].available_runs.[dataset subdir].[dattype subdir].sqlite
764  //
765  // If [dataset subdir] contains "/" (i.e. if data is grouped into subdirectories)
766  // we replace them by "_"
767 
769  if (!fDataSet) {
770  Error("GetFileName", "Dataset has not been set for this file.");
771  filename = "";
772  }
773  else {
774  KVString datapath = fDataSet->GetDataPathSubdir();
775  datapath.ReplaceAll("/", "_");
776  filename.Form("%s.available_runs.%s.%s.sqlite", fDataSet->GetRepository()->GetName(), datapath.Data(),
778  }
779  return filename;
780 }
781 
782 
783 
798 
800 {
801  // Returns the full path to the directory where the available runs file is stored.
802  // This is by default the same directory where the dataset files are stored.
803  // However, if KaliVeda was installed using a GNU-style directory layout
804  // (possibly in the system directories, e.g. Ubuntu packages)
805  // then the path will be the user's working directory + dataset name
806  //
807  // Alternatively, by setting the config variable
808  // KVAvailableRunsFile.RunFileDirectory: /some/path
809  //
810  // files will be stored/looked for in
811  // /some/path/[dataset]
812  //
813  // You can use environment variables - $(VAR) - in the path
814 
815  KVString filepath;
816  if (!fDataSet) {
817  Error("GetFilePath", "Dataset has not been set for this file.");
818  filepath = "";
819  }
820  else {
821  TString p = gEnv->GetValue("KVAvailableRunsFile.RunFileDirectory", "");
822  if (p == "") {
823  // no user-defined run file directory
824  if (is_gnuinstall()) {
825  // GNU-style install: use working directory
826  filepath = GetWORKDIRFilePath(fDataSet->GetName());
827  }
828  else
829  filepath = fDataSet->GetDataSetDir();
830  }
831  else {
833  AssignAndDelete(filepath, gSystem->ConcatFileName(p.Data(), fDataSet->GetName()));
834  }
835  }
836  return filepath;
837 }
838 
839 
840 
844 
846 {
847  // Return the full path on the local machine to the file
848  // used to store information on available runs
849 
850  KVString path;
852  return path;
853 }
854 
855 
856 
861 
863 {
864  // Check that the directory given by GetFilePath() exists and is writable
865  // If it does not exist, it will be created if possible
866  // If it exists but is not writable, or cannot be created, returns kFALSE.
867 
868  if (gSystem->AccessPathName(GetFilePath(), kFileExists)) { // directory does not exist
869  if (gSystem->mkdir(GetFilePath(), kTRUE) == -1) {
870  Error("CheckDirectoryForAvailableRunsFile", "cannot create directory %s - check access permissions", GetFilePath().Data());
871  return kFALSE;
872  }
873  // set access permissions on created directory
874  gSystem->Chmod(GetFilePath(), 0775);
875  }
876  if (gSystem->AccessPathName(GetFilePath(), kWritePermission)) { // directory is not writable
877  Error("CheckDirectoryForAvailableRunsFile", "directory %s is not writable - check access permissions", GetFilePath().Data());
878  return kFALSE;
879  }
880  return kTRUE;
881 }
882 
883 
884 
886 
887 std::unique_ptr<KVSQLite::database> KVAvailableRunsFile::OpenAvailableRunsFile(bool called_by_update)
888 {
891  auto db = std::make_unique<KVSQLite::database>(GetFullPathToAvailableRunsFile());
892  if(!db->good())
893  {
894  Error("OpenAvailableRunsFile","Failed to open/create sqlite database file %s",GetFullPathToAvailableRunsFile().Data());
895  db.reset(nullptr);
896  return db;
897  }
898  if (making_new_db) {
899  // set access permissions on database file
901 
902  // create systems table
903  KVSQLite::table sys_tab("Systems");
905  sys_tab.primary_key("id");
906  sys_tab.add_column("system", KVSQLite::column_type::TEXT).NOT_NULL().UNIQUE();
907  auto& t = db->add_table(sys_tab);
908  // add default 'unknown' system (which will have id=1)
909  t.prepare_insert_single_row();
910  t["system"] = "unknown";
911  t.insert_single_row();
912 
913  // create runs table
914  KVSQLite::table run_tab("Available_Runs");
916  run_tab.primary_key("id");
918  run_tab.add_column("index", KVSQLite::column_type::INTEGER);
919  run_tab.add_column("filename", KVSQLite::column_type::TEXT).NOT_NULL();
921  run_tab.add_column("version", KVSQLite::column_type::TEXT);
922  run_tab.add_column("username", KVSQLite::column_type::TEXT);
924  run_tab.foreign_key("sys_id", "Systems", "id");
925 
926  db->add_table(run_tab);
927 
928  if (!called_by_update) Update(db);
929  }
930  return db;
931 }
932 
933 
934 
940 
942 {
943  // return kTRUE if the given file for this runfile is lacking some information
944  // e.g. the KV version and username
945  //
946  // N.B.: if no file is known for this run, we return kFALSE
947 
948  auto runDB = OpenAvailableRunsFile();
949  auto selection = SelectRunAndOrIndex(run) + " AND " + SelectFileName(filename);
950  runDB->select_data("Available_Runs", "run,version", selection);
951  while (runDB->get_next_result()) {
952  if ((*runDB)["Available_Runs"]["version"].is_null()) return true;
953  }
954  return false;
955 }
956 
957 
int Int_t
ROOT::R::TRInterface & r
bool Bool_t
char Char_t
constexpr Bool_t kFALSE
constexpr Bool_t kTRUE
R__EXTERN TEnv * gEnv
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
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 index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize fs
char name[80]
char * Form(const char *fmt,...)
void AssignAndDelete(TString &target, char *tobedeleted)
kFileExists
kWritePermission
R__EXTERN TSystem * gSystem
Handles lists of available runs for different datasets and types of data.
Bool_t CheckDirectoryForAvailableRunsFile()
Bool_t InfosNeedUpdate(const run_index_t &run, const KVString &filename)
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)
void UpdateInfos(const run_index_t &run, const KVString &filename, const KVString &kvversion, const KVString &username)
Bool_t ExtractDateFromFileName(const Char_t *name, KVDatime &date)
const Char_t * GetDataType() const
TString SelectRunAndOrIndex(const run_index_t &run)
dataset to which this file belongs
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.
const KVDataSet * fDataSet
void GetRunInfos(const run_index_t &run, KVList *dates, KVList *names)
virtual void Update(const std::unique_ptr< KVSQLite::database > &db_handle={})
KVString GetFileName() const
virtual std::unique_ptr< KVSQLite::database > OpenAvailableRunsFile(bool called_by_update=false)
KVString GetFullPathToAvailableRunsFile() const
run_index_list GetRunList(const KVDBSystem *system=0)
std::optional< run_index_t > IsRunFileName(const Char_t *filename)
TString SelectFileName(const KVString &filename)
bool insert_runfile_into_database(KVDataRepository *repository, const KVBase *objs, KVSQLite::database *RunListTable, const run_index_t &run_num, KVDBRun *run, bool with_version_and_username=false)
KVString GetFilePath() const
static KVString date_read_from_filename
virtual bool get_file_modification_date(KVDataRepository *repository, const KVBase *objs, KVDatime &modt)
virtual void Add(const run_index_t &run, const KVString &filename)
std::unique_ptr< TList > GetListOfAvailableSystems(const KVDBSystem *systol=0)
Base class for KaliVeda framework.
Definition: KVBase.h:139
static const Char_t * GetWORKDIRFilePath(const Char_t *namefile="")
Definition: KVBase.cpp:121
static bool is_gnuinstall()
Definition: KVBase.h:274
virtual Bool_t IsCalled(const Char_t *name) const
Definition: KVBase.h:189
static const Char_t * GetKVVersion()
Returns KaliVeda version string.
Definition: KVBase.cpp:853
virtual Int_t GetNumber() const
Definition: KVDBRecord.h:73
void SetEvents(ULong64_t evt_number)
Definition: KVDBRunFile.h:157
Description of an experimental run in database ,,.
Definition: KVDBRun.h:40
const Char_t * GetSystemName() const
Definition: KVDBRun.h:217
KVDBSystem * GetSystem() const
Definition: KVDBRun.cpp:237
Database class used to store information on different colliding systems studied during an experiment....
Definition: KVDBSystem.h:52
Base class for managing repositories of experimental data.
virtual std::unique_ptr< KVUniqueNameList > GetDirectoryListing(const KVDataSet *dataset, const Char_t *datatype="", const Char_t *subdir="")
virtual Bool_t GetFileInfo(const KVDataSet *dataset, const Char_t *datatype, const Char_t *runfile, FileStat_t &fs) const
KVDataRepository * GetRepository() const
Get pointer to data repository in which dataset is stored.
Definition: KVDataSet.cpp:1459
const Char_t * GetDataSetDir() const
Definition: KVDataSet.cpp:746
virtual const Char_t * GetDataPathSubdir() const
Returns name of top-level directory in data repository used to store data files for this dataset.
Definition: KVDataSet.h:91
KVExpDB * GetDataBase(Option_t *opt="") const
Definition: KVDataSet.cpp:308
const Char_t * GetDataTypeSubdir(const Char_t *type) const
Definition: KVDataSet.h:95
Extension of TDatime to handle various useful date formats.
Definition: KVDatime.h:33
@ kSQL
Definition: KVDatime.h:44
static Bool_t IsGANACQFormat(const Char_t *date)
Definition: KVDatime.cpp:433
static Bool_t IsSQLFormat(const Char_t *date)
Definition: KVDatime.cpp:496
static Bool_t IsGANACQ2010Format(const Char_t *date)
Definition: KVDatime.cpp:455
void SetSQLDate(const Char_t *SQLDateString)
Definition: KVDatime.cpp:204
void SetGanacqNarvalDate(const Char_t *GanacqDateString)
Definition: KVDatime.cpp:297
static Bool_t IsGANACQNarvalFormat(const Char_t *date)
Definition: KVDatime.cpp:476
void SetGanacq2010Date(const Char_t *GanacqDateString)
Definition: KVDatime.cpp:273
void SetGanacqDate(const Char_t *GanacqDateString)
Definition: KVDatime.cpp:323
Base class to describe database of an experiment ,,.
Definition: KVExpDB.h:20
virtual KVDBSystem * GetSystem(const Char_t *system) const
Definition: KVExpDB.h:109
KVDBRun * GetDBRun(Int_t number) const
Definition: KVExpDB.h:89
const KVDBRunFile & GetDBRunFile(const run_index_t &r) const
Definition: KVExpDB.h:93
Int_t GetIndexMultiplier() const
Definition: KVExpDB.h:180
Bool_t HasIndexMultiplier() const
Definition: KVExpDB.h:179
Extended TList class which owns its objects by default.
Definition: KVList.h:28
Description of an individual data file in an experimental dataset.
Definition: KVRunFile.h:19
column & UNIQUE()
Definition: SQLiteDB.h:190
column & NOT_NULL()
Definition: SQLiteDB.h:197
Interface to ROOT SQLite database backend.
Definition: SQLiteDB.h:477
bool select_data(const TString &tables, const TString &columns="*", const TString &selection="", bool distinct=false, const TString &anything_else="") const
Definition: SQLiteDB.cpp:835
bool get_next_result() const
Definition: SQLiteDB.cpp:954
KVSQLite::table & get_table(const TString &name)
Definition: SQLiteDB.h:571
int count(const TString &tables, const TString &column="*", const TString &selection="", bool distinct=false, const TString &anything_else="") const
Definition: SQLiteDB.cpp:1124
void primary_key(const TString &cols)
Definition: SQLiteDB.h:432
void foreign_key(const TString &child_key, const TString &parent_table, const TString &parent_key)
Definition: SQLiteDB.cpp:1674
column & add_column(const KVSQLite::column &c)
Definition: SQLiteDB.cpp:1623
void prepare_insert_single_row()
Definition: SQLiteDB.cpp:1810
void Add(TObject *obj) override
void Delete(Option_t *option="") 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
Int_t GetNValues(TString delim) const
Definition: KVString.cpp:886
const char * AsSQLString() const
void Set()
virtual const char * GetValue(const char *name, const char *dflt) const
virtual void Add(TObject *obj)
const char * GetName() const override
virtual void Warning(const char *method, const char *msgfmt,...) const
virtual void Error(const char *method, const char *msgfmt,...) const
virtual void Info(const char *method, const char *msgfmt,...) const
const char * Data() const
void ToUpper()
TString & Append(char c, Ssiz_t rep=1)
void Form(const char *fmt,...)
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
TString & ReplaceAll(const char *s1, const char *s2)
virtual int Chmod(const char *file, UInt_t mode)
virtual char * ConcatFileName(const char *dir, const char *name)
virtual int mkdir(const char *name, Bool_t recursive=kFALSE)
virtual UserGroup_t * GetUserInfo(const char *user=nullptr)
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
virtual const char * BaseName(const char *pathname)
virtual char * ExpandPathName(const char *path)
Specifies a runfile according to run number and file index ,.
Definition: run_index.h:33
int run() const
Definition: run_index.h:52
int index(int no_index=-1) const
Definition: run_index.h:57
bool has_index() const
Definition: run_index.h:61
unsigned long long ULong64_t
BinData::ErrorType GetDataType(const TGraph *gr, DataOptions &fitOpt)
void Error(const char *location, const char *fmt,...)
Double_t Max(Double_t a, Double_t b)
const char * String
TLine l
ClassImp(TPyArg)