KaliVeda
Toolkit for HIC analysis
KVDataSetManager.cpp
1 /*
2 $Id: KVDataSetManager.cpp,v 1.17 2007/10/01 15:03:38 franklan Exp $
3 $Revision: 1.17 $
4 $Date: 2007/10/01 15:03:38 $
5 $Author: franklan $
6 */
7 
8 #include "KVBase.h"
9 #include "KVDataSetManager.h"
10 #include "KVDataRepositoryManager.h"
11 #include "KVDataSetRepository.h"
12 #include "KVString.h"
13 #include "TObjString.h"
14 #include "TObjArray.h"
15 #include "Riostream.h"
16 #include "KVBase.h"
17 #include "TPluginManager.h"
18 #include "TError.h"
19 
20 using namespace std;
21 
23 
24 KVDataSetManager* gDataSetManager;
25 
26 
28 
30  : fEnv(*gEnv)
31 {
32  fNavailable = 0;
33  fRepository = 0;
35  fMaxCacheTime = 0;
36  fCacheFileName = "";
38  fTasks.SetOwner();
39 }
40 
41 
42 
53 
55 {
56  //Initialisation of dataset manager for the repository 'dr'.
57  //
58  //If dr=0x0 (default) then all known datasets are 'available', otherwise
59  //we check availability of datasets based on data present in repository.
60  //
61  //Initialise all possible data analysis tasks,
62  //then set list of possible tasks for each available dataset.
63  //
64  //\returns kTRUE if all goes well.
65 
66  fRepository = dr;
67 
68  if (!ReadDataSetList())
69  return kFALSE;
70 
71  //use caching for dataset availability ?
72  if (dr) {
73  fCacheAvailable = fEnv.GetValueOf(dr->GetName(), "DataRepository.CacheAvailable").Default(kFALSE);
74  fMaxCacheTime = fEnv.GetValueOf(dr->GetName(), "DataRepository.MaxCacheTime").Default(0);
75  }
76  //name of cache file
77  if (dr) fCacheFileName.Form("%s.available.datasets", dr->GetName());
78 
79  //check which datasets are available
81 
82  if (!ReadTaskList())
83  return kFALSE;
84 
85  //set available data analysis tasks for available datasets
86  if (GetNavailable()) {
87  for (Int_t i = 1; i <= GetNavailable(); i++)
89  }
90 
91  // stand-alone dataset manager: make it the default
92  if (!dr) gDataSetManager = this;
93 
94  return kTRUE;
95 }
96 
97 
98 
102 
104 {
105  //Initialise list of all known datasets from informations in .kvrootrc config files
106  //(and user's .kvrootrc)
107 
108  KVString manip_list = fEnv.GetValueOf("DataSet").Default("");
109 
110  fDataSets.Clear();
111 
112  manip_list.Begin(" ");
113 
114  while (!manip_list.End()) {
115 
116  auto manip = manip_list.Next();
117 
118  KVDataSet* ds = NewDataSet();
119  ds->SetName(manip);
120  ds->SetTitle(fEnv.GetValueOf(manip, "DataSet.Title").Default("Experimental dataset"));
121  ds->SetDataPathSubdir(fEnv.GetValueOf(manip, "DataSet.RepositoryDir").Default(manip));
123  fDataSets.Add(ds);
124 
125  }
126 
127  return kTRUE;
128 }
129 
130 
131 
135 
137 {
138  //Initialise list of all known analysis tasks from informations in .kvrootrc config files
139  //(and user's .kvrootrc)
140 
141  KVString task_list = fEnv.GetValueOf("DataAnalysisTask").Default("");
142 
143  fTasks.Clear();
144 
145  task_list.Begin(" ");
146  while (!task_list.End()) {
147 
149  auto name = task_list.Next();
150  dat->SetName(name);
151  dat->SetTitle(fEnv.GetValueOf(name, "DataAnalysisTask.Title").Default(""));
152  dat->SetPrereq(fEnv.GetValueOf(name, "DataAnalysisTask.Prereq").Default(""));
153  dat->SetOutputDataType(fEnv.GetValueOf(name, "DataAnalysisTask.Output").Default(""));
154  dat->SetDataAnalyser(fEnv.GetValueOf(name, "DataAnalysisTask.Analyser").Default("KVDataAnalyser"));
155  dat->SetWithUserClass(fEnv.GetValueOf(name, "DataAnalysisTask.UserClass").Default(kFALSE));
156  dat->SetUserBaseClass(fEnv.GetValueOf(name, "DataAnalysisTask.UserClass.Base").Default(""));
157  dat->SetStatusUpdateInterval(fEnv.GetValueOf(name, "DataAnalysisTask.StatusUpdateInterval").Default(1000));
158  fTasks.Add(dat);
159 
160  }
161 
162  return kTRUE;
163 }
164 
165 
166 
173 
175 {
176  //Print list of datasets:
177  //
178  // + if `opt=""` (default) all datasets are shown with full information
179  // + if `opt="available"` only available datasets are shown, each with a number which can
180  // be used with GetAvailableDataSet() in order to retrieve the corresponding dataset.
181 
182  TString Sopt(opt);
183  Sopt.ToUpper();
184  if (Sopt.BeginsWith("AVAIL")) {
185  if (!fNavailable) {
186  cout << " *** No available datasets ***" <<
187  endl;
188  return;
189  }
190  else {
191  for (int i = 1; i <= fNavailable; i++) {
193  cout << "\t" << i << ". " << ds->GetTitle() << endl;
194  }
195  }
196  return;
197  }
198  if (fDataSets.GetSize()) {
199  TIter next(&fDataSets);
200  KVDataSet* ds;
201  while ((ds = (KVDataSet*) next()))
202  ds->ls();
203  }
204 }
205 
206 
207 
231 
233 {
234  //Check availability of datasets in repository associated to this data set manager
235  //
236  //If caching is activated for the parent repository, i.e. if
237  //~~~
238  // [repository name].DataRepository.CacheAvailable: yes
239  //~~~
240  //then instead of directly checking the existence of the directories for each dataset,
241  //we use the cached information written in the file
242  //`$HOME/.kaliveda/[repository name].available.datasets`
243  //unless
244  // + (1) it doesn't exist, or
245  // + (2) the file is older than the maximum cache time (in seconds) defined by
246  //~~~
247  // [repository name].DataRepository.MaxCacheSeconds:
248  //~~~
249  //
250  //In either of these 2 cases, we check the existence of the directories and update/
251  //create the cache file.
252  //
253  //If the repository appears to be empty (perhaps because we are using a remote access
254  //protocol to check it, and the protocol has some problems...), then as a last resort we
255  //we will use the cache if it exists, whatever its age.
256 
257  if (fCacheAvailable) {
258  //caching of dataset availability is activated
259  if (CheckCacheStatus()) {
260  //cache file exists and is not out of date
261  if (ReadAvailableDatasetsFile()) return;
262  }
263  }
264 
265  // print (repository-dependent) warning/informational message
267 
268  //open temporary file
269  ofstream tmp_file;
270  TString tmp_file_path = fCacheFileName;
271  KVBase::OpenTempFile(tmp_file_path, tmp_file);
272 
273  fNavailable = 0;
274  if (fDataSets.GetSize()) {
275  TIter next(&fDataSets);
276  KVDataSet* ds;
277  while ((ds = (KVDataSet*) next())) {
278  //The results of this check are written in $KVROOT/KVFiles/[repository name].available.datasets
279  //This file may be read by KVRemoteDataSetManager::CheckAvailability when this
280  //data repository is accessed as a remote data repository from a remote machine.
281  //In this case we do not want the identity of the user to influence the contents of the file.
282  //Therefore even for 'unavailable' datasets we write the available datatypes (if any)
283  //in the file.
284  tmp_file << ds->GetName() << " : ";
285  ds->CheckAvailable();
286  tmp_file << ds->GetAvailableDataTypes() << endl;
287  if (ds->IsAvailable()) {
288  fNavailable++;
289  }
290  }
291 
292  //close temp file
293  tmp_file.close();
294  //if datasets are found, then we copy the temporary file to KVFiles directory,
295  //overwriting any previous version. if no datasets were found, we try the cache
296  //file (if it exists)
297  if (fNavailable && fRepository) { //if no repository is associated, no need to keep file
299  gSystem->CopyFile(tmp_file_path, runlist, kTRUE);
300  //set access permissions to 664
301  gSystem->Chmod(runlist.Data(), 0664);
302  }
303 
304  //delete temp file
305  gSystem->Unlink(tmp_file_path);
306 
307  if (!fNavailable) {
308  //no datasets found when checking file system ?
309  //can we rely on the cache file ?
311  }
312  else {
313  //now set up array of available datasets' indices
314  fIndex.clear();
315  next.Reset();
316  Int_t j(0);
317  while ((ds = (KVDataSet*) next())) {
318  if (ds->IsAvailable()) {
319  fIndex.push_back(j);
320  }
321  j++;
322  }
323  }
324  }
325 }
326 
327 
328 
329 
332 
334 {
335  //Return pointer to DataSet using index in list of all datasets, index>=0
336  if (fDataSets.GetSize() && index < fDataSets.GetSize())
337  return (KVDataSet*) fDataSets.At(index);
338  return 0;
339 }
340 
341 
342 
345 
347 {
348  //Return pointer to DataSet using name
350 }
351 
352 
353 
359 
361 {
362  //Return pointer to available DataSet using index of available datasets
363  //
364  //Note this index begins at 1, and corresponds to the number printed next to the dataset
365  //when Print("available") is called
366  if (fNavailable && index && index <= fNavailable)
367  return GetDataSet(fIndex[index - 1]);
368  return 0;
369 }
370 
371 
372 
375 
377 {
378  //Return pointer to named data analysis task
380 }
381 
382 
383 
386 
388 {
389  //Creates and returns pointer to new data set object
390  return (new KVDataSet);
391 }
392 
393 
394 
400 
402 {
403  //Called when the physical state of the repository has changed i.e. a subdirectory for
404  //a new dataset or datatype has been added or removed. We update the available datatsets,
405  //datatypes and analysis tasks.
406 
407  //check which datasets are available
409 
410  //set available data analysis tasks for available datasets
411  if (GetNavailable()) {
412  for (Int_t i = 1; i <= GetNavailable(); i++)
414  }
415 }
416 
417 
418 
425 
427 {
428  //Opens file KVBase::WorkingDirectory()/[repository name].available.datasets
429  //containing cached info on available datasets and
430  //associated subdirectories in data repository.
431  //Opens file for reading, & if all goes well returns kTRUE.
432  //Returns kFALSE in case of problems.
433 
435 }
436 
437 
438 
444 
446 {
447  //Opens and reads file containing cached info on available datasets, and sets
448  //the availability of the concerned datasets.
449  //Returns kTRUE if all goes well.
450  //Returns kFALSE if no cache exists or if file cannot be opened.
452  Info("ReadAvailableDataSetsFile",
453  "Reading cached information in file %s", fCacheFileName.Data());
454  //read file
455  KVString line;
456  line.ReadLine(fDatasets);
457  while (fDatasets.good()) {
458 
459  line.Begin(": ,");
460 
461  //first entry is dataset name
462  TString datasetname = line.Next(kTRUE);
463  KVDataSet* dataset = GetDataSet(datasetname.Data());
464 
465  if (dataset) { //check dataset is known to local version of KaliVeda
466  //in case of remote repository, there may be datasets in the remote repository which are not defined here
467  if (!line.End()) {
468  //AVAILABLE DATASET
469  dataset->SetAvailable();
470  fNavailable++;
471  while (!line.End()) {
472  //each following entry is a subdirectory name
473  dataset->AddAvailableDataType(line.Next(kTRUE));
474  }
475  }
476  else {
477  //UNAVAILABLE DATASET (no subdirs)
478  dataset->SetAvailable(kFALSE);
479  }
480  }
481  line.ReadLine(fDatasets);
482  }
483 
484  //close file
485  fDatasets.close();
486  fDatasets.clear();
487 
488  if (fNavailable) {
489  TIter next(&fDataSets);
490  //now set up array of available datasets' indices
491  fIndex.clear();
492  Int_t j(0);
493  KVDataSet* ds;
494  while ((ds = (KVDataSet*) next())) {
495  if (ds->IsAvailable()) {
496  fIndex.push_back(j);
497  }
498  j++;
499  }
500  }
501  //all is OK
502  return kTRUE;
503  }
504  //we could not find/open the cache file
505  return kFALSE;
506 }
507 
508 
509 
510 
514 
516 {
517  //We check the status of the available datasets cache file.
518  //\return kTRUE if the file exists & was last modified less than fMaxCacheTime seconds ago.
519 
520  TString fullpath;
521  Info("KVDataSetManager::CheckCacheStatus", "Checking for available datasets cache file...");
523 
524  // file exists - how old is it ?
525  FileStat_t file_info;
526  gSystem->GetPathInfo(fullpath.Data(), file_info);
527  TDatime file_date(file_info.fMtime);
528  TDatime now;
529  UInt_t file_age = now.Convert() - file_date.Convert();
530  Info("KVDataSetManager::CheckCacheStatus", "...file found. It is %u seconds old", file_age);
531  if (file_age < fMaxCacheTime) {
532  Info("KVDataSetManager::CheckCacheStatus", "Using cached file");
533  return kTRUE;
534  }
535  else
536  Info("KVDataSetManager::CheckCacheStatus", "File is too old (max time=%u). Update will be performed.", fMaxCacheTime);
537  }
538  else
539  Info("KVDataSetManager::CheckCacheStatus", "...no file found");
540  return kFALSE;
541 }
542 
543 
544 
550 
552 {
553  // This method returns a pointer to the analysis task whose description (title) contains
554  // all of the whitespace-separated keywords (which may be regular expressions)
555  // given in the string "keywords". The comparison is case-insensitive.
556 
557  //case-insensitive search for matches in list of all analysis tasks, based on 'title' attribute
558  return (KVDataAnalysisTask*)GetAnalysisTaskList()->FindObjectAny("title", keywords, kTRUE, kFALSE);
559 }
560 
561 
int Int_t
unsigned int UInt_t
bool Bool_t
char Char_t
constexpr Bool_t kFALSE
constexpr Bool_t kTRUE
const char Option_t
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 index
char name[80]
R__EXTERN TSystem * gSystem
static void OpenTempFile(TString &base, std::ofstream &fp)
Definition: KVBase.cpp:830
static const Char_t * GetWORKDIRFilePath(const Char_t *namefile="")
Definition: KVBase.cpp:121
static Bool_t SearchKVFile(const Char_t *name, TString &fullpath, const Char_t *kvsubdir="")
Definition: KVBase.cpp:541
static Bool_t SearchAndOpenKVFile(const Char_t *name, KVSQLite::database &dbfile, const Char_t *kvsubdir="")
Definition: KVBase.cpp:652
Define and manage data analysis tasks.
virtual void SetDataAnalyser(const Char_t *d)
void SetOutputDataType(const KVString &p)
virtual void SetPrereq(const Char_t *p)
virtual void SetStatusUpdateInterval(Long64_t n)
virtual void SetUserBaseClass(const Char_t *d)
virtual void SetWithUserClass(Bool_t w=kTRUE)
Manage all datasets contained in a given data repository.
TString fCacheFileName
name of cache file ( = [repository name].available.datasets)
Bool_t Init(KVDataSetRepository *=0)
KVUniqueNameList fDataSets
list of datasets handled by manager
void Print(Option_t *opt="") const
Int_t GetNavailable() const
const KVSeqCollection * GetAnalysisTaskList() const
Bool_t fCacheAvailable
kTRUE if caching is activated for parent repository
Int_t fNavailable
number of available datasets
KVDataAnalysisTask * GetAnalysisTaskAny(const Char_t *keywords) const
Bool_t OpenAvailableDatasetsFile()
KVDataSetRepository * fRepository
the repository for which data sets are handled
Bool_t ReadAvailableDatasetsFile()
KVDataAnalysisTask * GetTask(const Char_t *name)
Return pointer to named data analysis task.
KVDataSet * GetDataSet(Int_t) const
Return pointer to DataSet using index in list of all datasets, index>=0.
KVDataSet * NewDataSet()
Creates and returns pointer to new data set object.
KVUniqueNameList fTasks
list of all known analysis tasks
KVDataSet * GetAvailableDataSet(Int_t) const
std::vector< Int_t > fIndex
array of indices of available datasets
std::ifstream fDatasets
for reading cached repository available datasets file
UInt_t fMaxCacheTime
maximum allowed age of cache file in seconds
A repository for experimental datasets.
void PrintAvailableDatasetsUpdateWarning() const
Manage an experimental dataset corresponding to a given experiment or campaign.
Definition: KVDataSet.h:146
Bool_t IsAvailable() const
Definition: KVDataSet.h:224
void ls(Option_t *opt="") const override
Print dataset information.
Definition: KVDataSet.cpp:407
void SetRepository(KVDataSetRepository *)
Set pointer to data repository in which dataset is stored.
Definition: KVDataSet.cpp:1471
void AddAvailableDataType(const Char_t *)
Definition: KVDataSet.cpp:515
void SetAnalysisTasks(const KVSeqCollection *)
Definition: KVDataSet.cpp:532
void CheckAvailable()
Definition: KVDataSet.cpp:473
const Char_t * GetAvailableDataTypes() const
Definition: KVDataSet.h:214
void SetAvailable(Bool_t yes=kTRUE)
Definition: KVDataSet.h:229
void SetName(const char *name) override
Definition: KVDataSet.cpp:715
void SetDataPathSubdir(const TString &s)
Definition: KVDataSet.h:196
ValueType Default(ValueType v=ValueType{}) const
Definition: KVEnv.h:59
Value GetValueOf(Ts... args) const
Definition: KVEnv.h:70
virtual TObject * FindObjectAny(const Char_t *att, const Char_t *keys, Bool_t contains_all=kFALSE, Bool_t case_sensitive=kTRUE) const
Int_t GetSize() const override
void Clear(Option_t *option="") override
void SetOwner(Bool_t enable=kTRUE) override
TObject * At(Int_t idx) const override
virtual TObject * FindObjectByName(const Char_t *name) const
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
void Add(TObject *obj) override
UInt_t Convert(Bool_t toGMT=kFALSE) const
void Reset()
virtual void SetTitle(const char *title="")
const char * GetName() const override
const char * GetTitle() const override
virtual void SetName(const char *name)
const char * Data() const
void ToUpper()
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
void Form(const char *fmt,...)
virtual int Chmod(const char *file, UInt_t mode)
virtual int CopyFile(const char *from, const char *to, Bool_t overwrite=kFALSE)
virtual int GetPathInfo(const char *path, FileStat_t &buf)
virtual int Unlink(const char *name)
TLine * line
void Info(const char *location, const char *fmt,...)
Long_t fMtime
ClassImp(TPyArg)