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 = gEnv->GetValue(Form("%s.DataRepository.CacheAvailable", dr->GetName()),
74  kFALSE);
75  fMaxCacheTime = (UInt_t)gEnv->GetValue(Form("%s.DataRepository.MaxCacheTime", dr->GetName()),
76  -1);
77  }
78  //name of cache file
79  if (dr) fCacheFileName.Form("%s.available.datasets", dr->GetName());
80 
81  //check which datasets are available
83 
84  if (!ReadTaskList())
85  return kFALSE;
86 
87  //set available data analysis tasks for available datasets
88  if (GetNavailable()) {
89  for (Int_t i = 1; i <= GetNavailable(); i++)
91  }
92 
93  // stand-alone dataset manager: make it the default
94  if (!dr) gDataSetManager = this;
95 
96  return kTRUE;
97 }
98 
99 
100 
104 
106 {
107  //Initialise list of all known datasets from informations in .kvrootrc config files
108  //(and user's .kvrootrc)
109 
110  KVString manip_list = fEnv.GetValueOf("DataSet").Default("");
111 
112  fDataSets.Clear();
113 
114  manip_list.Begin(" ");
115 
116  while (!manip_list.End()) {
117 
118  auto manip = manip_list.Next();
119 
120  KVDataSet* ds = NewDataSet();
121  ds->SetName(manip);
122  ds->SetTitle(fEnv.GetValueOf(manip, "DataSet.Title").Default("Experimental dataset"));
123  ds->SetDataPathSubdir(fEnv.GetValueOf(manip, "DataSet.RepositoryDir").Default(manip));
125  fDataSets.Add(ds);
126 
127  }
128 
129  return kTRUE;
130 }
131 
132 
133 
137 
139 {
140  //Initialise list of all known analysis tasks from informations in .kvrootrc config files
141  //(and user's .kvrootrc)
142 
143  KVString task_list = fEnv.GetValueOf("DataAnalysisTask").Default("");
144 
145  fTasks.Clear();
146 
147  task_list.Begin(" ");
148  while (!task_list.End()) {
149 
151  auto name = task_list.Next();
152  dat->SetName(name);
153  dat->SetTitle(fEnv.GetValueOf(name, "DataAnalysisTask.Title").Default(""));
154  dat->SetPrereq(fEnv.GetValueOf(name, "DataAnalysisTask.Prereq").Default(""));
155  dat->SetOutputDataType(fEnv.GetValueOf(name, "DataAnalysisTask.Output").Default(""));
156  dat->SetDataAnalyser(fEnv.GetValueOf(name, "DataAnalysisTask.Analyser").Default("KVDataAnalyser"));
157  dat->SetWithUserClass(fEnv.GetValueOf(name, "DataAnalysisTask.UserClass").Default(kFALSE));
158  dat->SetUserBaseClass(fEnv.GetValueOf(name, "DataAnalysisTask.UserClass.Base").Default(""));
159  dat->SetStatusUpdateInterval(fEnv.GetValueOf(name, "DataAnalysisTask.StatusUpdateInterval").Default(1000));
160  fTasks.Add(dat);
161 
162  }
163 
164  return kTRUE;
165 }
166 
167 
168 
175 
177 {
178  //Print list of datasets:
179  //
180  // + if `opt=""` (default) all datasets are shown with full information
181  // + if `opt="available"` only available datasets are shown, each with a number which can
182  // be used with GetAvailableDataSet() in order to retrieve the corresponding dataset.
183 
184  TString Sopt(opt);
185  Sopt.ToUpper();
186  if (Sopt.BeginsWith("AVAIL")) {
187  if (!fNavailable) {
188  cout << " *** No available datasets ***" <<
189  endl;
190  return;
191  }
192  else {
193  for (int i = 1; i <= fNavailable; i++) {
195  cout << "\t" << i << ". " << ds->GetTitle() << endl;
196  }
197  }
198  return;
199  }
200  if (fDataSets.GetSize()) {
201  TIter next(&fDataSets);
202  KVDataSet* ds;
203  while ((ds = (KVDataSet*) next()))
204  ds->ls();
205  }
206 }
207 
208 
209 
233 
235 {
236  //Check availability of datasets in repository associated to this data set manager
237  //
238  //If caching is activated for the parent repository, i.e. if
239  //~~~
240  // [repository name].DataRepository.CacheAvailable: yes
241  //~~~
242  //then instead of directly checking the existence of the directories for each dataset,
243  //we use the cached information written in the file
244  //`$HOME/.kaliveda/[repository name].available.datasets`
245  //unless
246  // + (1) it doesn't exist, or
247  // + (2) the file is older than the maximum cache time (in seconds) defined by
248  //~~~
249  // [repository name].DataRepository.MaxCacheSeconds:
250  //~~~
251  //
252  //In either of these 2 cases, we check the existence of the directories and update/
253  //create the cache file.
254  //
255  //If the repository appears to be empty (perhaps because we are using a remote access
256  //protocol to check it, and the protocol has some problems...), then as a last resort we
257  //we will use the cache if it exists, whatever its age.
258 
259  if (fCacheAvailable) {
260  //caching of dataset availability is activated
261  if (CheckCacheStatus()) {
262  //cache file exists and is not out of date
263  if (ReadAvailableDatasetsFile()) return;
264  }
265  }
266 
267  // print (repository-dependent) warning/informational message
269 
270  //open temporary file
271  ofstream tmp_file;
272  TString tmp_file_path = fCacheFileName;
273  KVBase::OpenTempFile(tmp_file_path, tmp_file);
274 
275  fNavailable = 0;
276  if (fDataSets.GetSize()) {
277  TIter next(&fDataSets);
278  KVDataSet* ds;
279  while ((ds = (KVDataSet*) next())) {
280  //The results of this check are written in $KVROOT/KVFiles/[repository name].available.datasets
281  //This file may be read by KVRemoteDataSetManager::CheckAvailability when this
282  //data repository is accessed as a remote data repository from a remote machine.
283  //In this case we do not want the identity of the user to influence the contents of the file.
284  //Therefore even for 'unavailable' datasets we write the available datatypes (if any)
285  //in the file.
286  tmp_file << ds->GetName() << " : ";
287  ds->CheckAvailable();
288  tmp_file << ds->GetAvailableDataTypes() << endl;
289  if (ds->IsAvailable()) {
290  fNavailable++;
291  }
292  }
293 
294  //close temp file
295  tmp_file.close();
296  //if datasets are found, then we copy the temporary file to KVFiles directory,
297  //overwriting any previous version. if no datasets were found, we try the cache
298  //file (if it exists)
299  if (fNavailable && fRepository) { //if no repository is associated, no need to keep file
301  gSystem->CopyFile(tmp_file_path, runlist, kTRUE);
302  //set access permissions to 664
303  gSystem->Chmod(runlist.Data(), 0664);
304  }
305 
306  //delete temp file
307  gSystem->Unlink(tmp_file_path);
308 
309  if (!fNavailable) {
310  //no datasets found when checking file system ?
311  //can we rely on the cache file ?
313  }
314  else {
315  //now set up array of available datasets' indices
316  fIndex.clear();
317  next.Reset();
318  Int_t j(0);
319  while ((ds = (KVDataSet*) next())) {
320  if (ds->IsAvailable()) {
321  fIndex.push_back(j);
322  }
323  j++;
324  }
325  }
326  }
327 }
328 
329 
330 
331 
334 
336 {
337  //Return pointer to DataSet using index in list of all datasets, index>=0
338  if (fDataSets.GetSize() && index < fDataSets.GetSize())
339  return (KVDataSet*) fDataSets.At(index);
340  return 0;
341 }
342 
343 
344 
347 
349 {
350  //Return pointer to DataSet using name
352 }
353 
354 
355 
361 
363 {
364  //Return pointer to available DataSet using index of available datasets
365  //
366  //Note this index begins at 1, and corresponds to the number printed next to the dataset
367  //when Print("available") is called
368  if (fNavailable && index && index <= fNavailable)
369  return GetDataSet(fIndex[index - 1]);
370  return 0;
371 }
372 
373 
374 
377 
379 {
380  //Return pointer to named data analysis task
382 }
383 
384 
385 
388 
390 {
391  //Creates and returns pointer to new data set object
392  return (new KVDataSet);
393 }
394 
395 
396 
402 
404 {
405  //Called when the physical state of the repository has changed i.e. a subdirectory for
406  //a new dataset or datatype has been added or removed. We update the available datatsets,
407  //datatypes and analysis tasks.
408 
409  //check which datasets are available
411 
412  //set available data analysis tasks for available datasets
413  if (GetNavailable()) {
414  for (Int_t i = 1; i <= GetNavailable(); i++)
416  }
417 }
418 
419 
420 
427 
429 {
430  //Opens file KVBase::WorkingDirectory()/[repository name].available.datasets
431  //containing cached info on available datasets and
432  //associated subdirectories in data repository.
433  //Opens file for reading, & if all goes well returns kTRUE.
434  //Returns kFALSE in case of problems.
435 
437 }
438 
439 
440 
446 
448 {
449  //Opens and reads file containing cached info on available datasets, and sets
450  //the availability of the concerned datasets.
451  //Returns kTRUE if all goes well.
452  //Returns kFALSE if no cache exists or if file cannot be opened.
454  Info("ReadAvailableDataSetsFile",
455  "Reading cached information in file %s", fCacheFileName.Data());
456  //read file
457  KVString line;
458  line.ReadLine(fDatasets);
459  while (fDatasets.good()) {
460 
461  line.Begin(": ,");
462 
463  //first entry is dataset name
464  TString datasetname = line.Next(kTRUE);
465  KVDataSet* dataset = GetDataSet(datasetname.Data());
466 
467  if (dataset) { //check dataset is known to local version of KaliVeda
468  //in case of remote repository, there may be datasets in the remote repository which are not defined here
469  if (!line.End()) {
470  //AVAILABLE DATASET
471  dataset->SetAvailable();
472  fNavailable++;
473  while (!line.End()) {
474  //each following entry is a subdirectory name
475  dataset->AddAvailableDataType(line.Next(kTRUE));
476  }
477  }
478  else {
479  //UNAVAILABLE DATASET (no subdirs)
480  dataset->SetAvailable(kFALSE);
481  }
482  }
483  line.ReadLine(fDatasets);
484  }
485 
486  //close file
487  fDatasets.close();
488  fDatasets.clear();
489 
490  if (fNavailable) {
491  TIter next(&fDataSets);
492  //now set up array of available datasets' indices
493  fIndex.clear();
494  Int_t j(0);
495  KVDataSet* ds;
496  while ((ds = (KVDataSet*) next())) {
497  if (ds->IsAvailable()) {
498  fIndex.push_back(j);
499  }
500  j++;
501  }
502  }
503  //all is OK
504  return kTRUE;
505  }
506  //we could not find/open the cache file
507  return kFALSE;
508 }
509 
510 
511 
512 
516 
518 {
519  //We check the status of the available datasets cache file.
520  //\return kTRUE if the file exists & was last modified less than fMaxCacheTime seconds ago.
521 
522  TString fullpath;
523  Info("KVDataSetManager::CheckCacheStatus", "Checking for available datasets cache file...");
525 
526  // file exists - how old is it ?
527  FileStat_t file_info;
528  gSystem->GetPathInfo(fullpath.Data(), file_info);
529  TDatime file_date(file_info.fMtime);
530  TDatime now;
531  UInt_t file_age = now.Convert() - file_date.Convert();
532  Info("KVDataSetManager::CheckCacheStatus", "...file found. It is %u seconds old", file_age);
533  if (file_age < fMaxCacheTime) {
534  Info("KVDataSetManager::CheckCacheStatus", "Using cached file");
535  return kTRUE;
536  }
537  else
538  Info("KVDataSetManager::CheckCacheStatus", "File is too old (max time=%u). Update will be performed.", fMaxCacheTime);
539  }
540  else
541  Info("KVDataSetManager::CheckCacheStatus", "...no file found");
542  return kFALSE;
543 }
544 
545 
546 
552 
554 {
555  // This method returns a pointer to the analysis task whose description (title) contains
556  // all of the whitespace-separated keywords (which may be regular expressions)
557  // given in the string "keywords". The comparison is case-insensitive.
558 
559  //case-insensitive search for matches in list of all analysis tasks, based on 'title' attribute
560  return (KVDataAnalysisTask*)GetAnalysisTaskList()->FindObjectAny("title", keywords, kTRUE, kFALSE);
561 }
562 
563 
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]
char * Form(const char *fmt,...)
R__EXTERN TSystem * gSystem
static void OpenTempFile(TString &base, std::ofstream &fp)
Definition: KVBase.cpp:829
static const Char_t * GetWORKDIRFilePath(const Char_t *namefile="")
Definition: KVBase.cpp:120
static Bool_t SearchKVFile(const Char_t *name, TString &fullpath, const Char_t *kvsubdir="")
Definition: KVBase.cpp:540
static Bool_t SearchAndOpenKVFile(const Char_t *name, KVSQLite::database &dbfile, const Char_t *kvsubdir="")
Definition: KVBase.cpp:651
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:410
void SetRepository(KVDataSetRepository *)
Set pointer to data repository in which dataset is stored.
Definition: KVDataSet.cpp:1474
void AddAvailableDataType(const Char_t *)
Definition: KVDataSet.cpp:518
void SetAnalysisTasks(const KVSeqCollection *)
Definition: KVDataSet.cpp:535
void CheckAvailable()
Definition: KVDataSet.cpp:476
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:718
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
virtual const char * GetValue(const char *name, const char *dflt) 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)