10 #include "KVAvailableRunsFile.h"
12 #include "TObjArray.h"
13 #include "TObjString.h"
16 #include "KVDataRepository.h"
17 #include "KVRunFile.h"
21 #define CHMODE(u,g,o) ((u << 6) + (g << 3) + o)
39 runlist_lock.SetTimeout(60);
40 runlist_lock.SetSuspend(5);
41 runlist_lock.SetSleeptime(1);
88 KVAvailableRunsFile::~KVAvailableRunsFile()
113 static TString filename;
115 Error(
"GetFileName",
"Dataset has not been set for this file.");
120 datapath.ReplaceAll(
"/",
"_");
124 return filename.Data();
160 static TString filepath;
162 Error(
"GetFilePath",
"Dataset has not been set for this file.");
166 TString p = gEnv->GetValue(
"KVAvailableRunsFile.RunFileDirectory",
"");
177 gSystem->ExpandPathName(p);
178 AssignAndDelete(filepath, gSystem->ConcatFileName(p.Data(),
fDataSet->GetName()));
181 return filepath.Data();
213 if (gSystem->AccessPathName(
GetFilePath(), kFileExists)) {
215 Error(
"CheckDirectoryForAvailableRunsFile",
"cannot create directory %s - check access permissions",
GetFilePath());
221 if (gSystem->AccessPathName(
GetFilePath(), kWritePermission)) {
222 Error(
"CheckDirectoryForAvailableRunsFile",
"directory %s is not writable - check access permissions",
GetFilePath());
262 Error(
"IsRunFileName",
"No default format set for datatype: %s",
267 if (fmt.Contains(
"%I") && (imult < 0)) {
268 Error(
"IsRunFileName",
"No index multiplier set for datatype: %s with format: %s",
350 KVString _file(gSystem->BaseName(filename));
356 bool with_index = fmt.Contains(
"%I");
357 bool two_part_date =
false;
358 bool got_date =
false;
362 if (np_fmt == np_fn || (with_index && np_fn == np_fmt - 1)) {
363 _file.
Begin(separators);
364 fmt.
Begin(separators);
365 int index(0), run(0);
366 char date1[100], date2[100];
367 if (fmt.Contains(
"%D1") && fmt.Contains(
"%D2")) two_part_date =
true;
369 while (!_file.
End()) {
373 if (fmt_part.Contains(
"%R")) {
374 fmt_part.ReplaceAll(
"%R",
"%d");
375 if (fmt_part.Contains(
"%D")) {
376 fmt_part.ReplaceAll(
"%D",
"%s");
377 sscanf(run_part.Data(), fmt_part.Data(), &run, date1);
381 sscanf(run_part.Data(), fmt_part.Data(), &run);
383 else if (fmt_part.Contains(
"%I")) {
384 fmt_part.ReplaceAll(
"%I",
"%d");
385 sscanf(run_part.Data(), fmt_part.Data(), &index);
387 else if (fmt_part.Contains(
"%D1")) {
388 fmt_part.ReplaceAll(
"%D1",
"%s");
389 sscanf(run_part.Data(), fmt_part.Data(), date1);
392 else if (fmt_part.Contains(
"%D2")) {
393 fmt_part.ReplaceAll(
"%D2",
"%s");
394 sscanf(run_part.Data(), fmt_part.Data(), date2);
397 else if (fmt_part.Contains(
"%D")) {
398 fmt_part.ReplaceAll(
"%D",
"%s");
399 sscanf(run_part.Data(), fmt_part.Data(), date1);
403 if (with_index) run = index_multiplier * run + index;
458 if (!run)
return kFALSE;
516 if (!no_existing_file) {
530 cout << endl <<
"Updating runlist : " << flush;
537 TIter next(dir_list);
540 Int_t ntot = dir_list->
GetSize();
541 Int_t n5pc = TMath::Max(ntot / 20, 1);
543 unique_ptr<KVExpDB> db_garbage;
547 db_garbage.reset(db);
549 while ((objs = (
KVBase*) next())) {
561 objs->GetName(), fs)) {
563 TDatime modt(fs.fMtime);
564 if (!no_existing_file) {
570 tmp_file << run->
GetNumber() <<
'|' << modt.AsSQLString() <<
'|' << objs->GetName();
571 if (prevEntry->
HasParameter(Form(
"KVVersion[%d]", occIdx))) {
572 tmp_file <<
"|" << prevEntry->
GetStringValue(Form(
"KVVersion[%d]", occIdx)) <<
"|" << prevEntry->
GetStringValue(Form(
"Username[%d]", occIdx));
578 tmp_file << run->
GetNumber() <<
'|' << modt.AsSQLString() <<
'|' << objs->GetName() << endl;
583 tmp_file << run->
GetNumber() <<
'|' << modt.AsSQLString() <<
'|' << objs->GetName() << endl;
588 Info(
"Update",
"the current run [%s] is not in database", objs->GetName());
591 TDatime modt(fs.fMtime);
593 tmp_file << run_num <<
'|' << modt.AsSQLString() <<
'|' << objs->GetName() << endl;
596 Warning(
"Update",
"%s GetFileInfo return kFALSE", objs->GetName());
603 cout << '>
' << flush;
606 cout << " DONE" << endl;
611 if (CheckDirectoryForAvailableRunsFile()) {
613 if (no_existing_file) {
614 //use "lockfile" to make sure nobody else tries to modify available_runs file
615 //while we are working on it
616 if (!runlist_lock.Lock(runlist.Data())) return;
619 //copy temporary file to available runs file directory, overwrite previous
620 gSystem->CopyFile(tmp_file_path, runlist, kTRUE);
621 //set access permissions to 664
622 gSystem->Chmod(runlist.Data(), CHMODE(6, 6, 4));
626 runlist_lock.Release();
629 gSystem->Unlink(tmp_file_path);
642 Bool_t KVAvailableRunsFile::GetRunInfo(Int_t run, TDatime& modtime,
645 //Look for a given run number in the file, and read the file's modification date/time and filename
654 if (filenames.GetEntries() == 1) {
655 filename = ((TObjString*) filenames.First())->String();
656 modtime = ((TObjString*) dates.First())->String().Data();
659 else if (filenames.GetEntries() > 1) {
660 Warning(
"GetRunInfo",
661 "Multiple versions of this runfile exist in the repository. Infos for most recent file will be returned.");
662 Warning(
"GetRunInfo",
663 "You should clean the repository using KVDataSet::CleanMultiRunfiles.");
665 TDatime most_recent(
"1998-12-25 00:00:00");
666 Int_t i_most_recent = 0;
667 for (
int i = 0; i < dates.GetEntries(); i++) {
669 TDatime rundate(((TObjString*) dates.At(i))->String().Data());
670 if (rundate > most_recent) {
671 most_recent = rundate;
675 filename = ((TObjString*) filenames.At(i_most_recent))->String();
676 modtime = ((TObjString*) dates.At(i_most_recent))->String().Data();
706 Error(
"GetRunInfos",
"Error opening available runs file");
718 if (line.BeginsWith(Form(
"%d|", run))) {
721 unique_ptr<TObjArray> toks(line.Tokenize(
'|'));
724 TObjString* rundate = (TObjString*)toks->At(1)->Clone();
731 dates->
Add(toks->At(1)->Clone());
733 files->
Add(toks->At(2)->Clone());
757 Error(
"CheckAvailable",
"Error opening available runs file");
762 Bool_t found = kFALSE;
766 if (line.BeginsWith(Form(
"%d|", run))) {
842 static TString fname;
843 static TDatime dtime;
885 Error(
"GetListOfAvailableSystems",
886 "Error opening available runs file");
892 Int_t good_lines = 0;
897 TString kvversion, username, filename;
899 unique_ptr<KVExpDB> garbage_db;
902 garbage_db.reset(db);
907 unique_ptr<TObjArray> toks(fLine.Tokenize(
'|'));
908 if (toks->GetSize()) {
910 KVString kvs(((TObjString*) toks->At(0))->GetString());
916 fRunNumber = kvs.Atoi();
917 kvversion = username =
"";
918 TString tmp = ((TObjString*) toks->At(1))->GetString();
919 fDatime = TDatime(tmp.Data());
920 filename = ((TObjString*) toks->At(2))->String();
922 if (toks->GetEntries() > 3) {
923 kvversion = ((TObjString*) toks->At(3))->GetString();
924 username = ((TObjString*) toks->At(4))->GetString();
936 sys_list =
new TList;
943 if (!sys_list->Contains(sys)) {
958 sys_list =
new TList;
959 sys_list->SetOwner(kTRUE);
964 if (start_date !=
"") fDatime.Set(start_date);
966 sys_list->Add(
new KVRunFile(a_run, filename, fDatime, kvversion, username));
976 if (sys_list && sys_list->GetSize() > 1)
980 Error(
"GetListOfAvailableSystems",
981 "Available runs file is empty or absent");
1004 Error(
"UpdateInfos",
"Error opening available runs file");
1012 TString FileName(filename);
1020 if (line.BeginsWith(Form(
"%d|", run))) {
1022 unique_ptr<TObjArray> toks(line.Tokenize(
'|'));
1023 TString ReadFileName = ((TObjString*) toks->At(2))->String();
1025 if (ReadFileName != FileName) {
1027 tmp_file << line.Data() << endl;
1031 tmp_file << run <<
"|" << ((TObjString*) toks->At(1))->String() <<
"|" << filename <<
"|" << kvversion <<
"|" << username << endl;
1037 tmp_file << line.Data() << endl;
1052 gSystem->CopyFile(tmp_file_path, fRunlist_path, kTRUE);
1054 gSystem->Chmod(fRunlist_path.Data(), CHMODE(6, 6, 4));
1056 gSystem->Unlink(tmp_file_path);
1079 Error(
"Remove",
"Error opening available runs file");
1087 TString FileName(filename);
1088 Bool_t withFileName = (FileName !=
"");
1094 if (!withFileName) {
1097 if (!line.BeginsWith(Form(
"%d|", run))) {
1099 tmp_file << line.Data() << endl;
1105 if (line.BeginsWith(Form(
"%d|", run))) {
1107 unique_ptr<TObjArray> toks(line.Tokenize(
'|'));
1108 TString ReadFileName;
1109 ReadFileName = ((TObjString*) toks->At(2))->String();
1111 if (ReadFileName != FileName) {
1113 tmp_file << line.Data() << endl;
1119 tmp_file << line.Data() << endl;
1135 gSystem->CopyFile(tmp_file_path, fRunlist_path, kTRUE);
1137 gSystem->Chmod(fRunlist_path.Data(), CHMODE(6, 6, 4));
1139 gSystem->Unlink(tmp_file_path);
1161 Error(
"Add",
"Error opening available runs file");
1173 tmp_file << line.Data() << endl;
1191 TDatime modt(fs.fMtime);
1192 UserGroup_t* userinfo = gSystem->GetUserInfo();
1193 tmp_file << run <<
'|' << modt.
1194 AsSQLString() <<
'|' << filename <<
'|' <<
GetKVVersion() <<
'|' << userinfo->fUser << endl;
1201 gSystem->CopyFile(tmp_file_path, runlist_path, kTRUE);
1203 gSystem->Chmod(runlist_path.Data(), CHMODE(6, 6, 4));
1205 gSystem->Unlink(tmp_file_path);
1233 Warning(
"OpenAvailableRunsFile",
"runlist file does not exist...");
1236 Error(
"OpenAvailableRunsFile",
1237 "Something weird: I just made the available runlist file, but I still can't open it!");
1279 if (run->
GetIntValue(
"Occurs") > 1) multiruns.
Add(run->GetName());
1303 Error(
"GetRunList",
"Cannot open available runs file");
1312 unique_ptr<KVExpDB> garbage_db;
1315 garbage_db.reset(db);
1320 TObjArray* toks = fLine.Tokenize(
'|');
1321 KVString kvs(((TObjString*) toks->At(0))->GetString());
1322 fRunNumber = kvs.Atoi();
1330 runs.
Add(fRunNumber);
1335 runs.
Add(fRunNumber);
1380 Error(
"ReadFile",
"Cannot open available runs file");
1389 Int_t line_number = 1;
1398 unique_ptr<TObjArray> toks(fLine.Tokenize(
'|'));
1404 Int_t nfields = toks->GetEntries();
1405 KVString kvs(((TObjString*) toks->At(0))->GetString());
1406 if (kvs.Contains(
"/")) {
1407 Warning(
"ReadFile",
"Strange '/' symbol in run number (line:%d)!!!", line_number);
1413 fRunNumber = kvs.Atoi();
1415 Warning(
"ReadFile",
"Less than 2 fields in entry for run %d (line:%d)???", fRunNumber, line_number);
1421 KVString datestring(((TObjString*) toks->At(1))->GetString());
1425 Int_t Occurs = (NVL ? NVL->
GetIntValue(
"Occurs") : 0);
1433 for (Int_t ii = 0; ii < Occurs; ii++) {
1435 if (olddate == datestring) {
1437 duplicate_lines.
Add(line_number);
1450 NVL->
SetValue(Form(
"Date[%d]", Occurs - 1), datestring.Data());
1452 KVString filename = ((TObjString*) toks->At(2))->GetString();
1453 NVL->
SetValue(Form(
"Filename[%d]", Occurs - 1), filename.Data());
1456 kvversion = ((TObjString*) toks->At(3))->GetString();
1457 username = ((TObjString*) toks->At(4))->GetString();
1458 NVL->
SetValue(Form(
"KVVersion[%d]", Occurs - 1), kvversion.Data());
1459 NVL->
SetValue(Form(
"Username[%d]", Occurs - 1), username.Data());
1469 Info(
"ReadFile",
"There were %d duplicate entries in available runs file, they will be removed", duplicate_lines.
GetNValues());
1495 if (!NVL)
return NULL;
1497 for (OccNum = 0; OccNum < Occurs; OccNum++) {
1498 if (NVL->
IsValue(Form(
"Filename[%d]", OccNum), filename) && NVL->
IsValue(Form(
"Date[%d]", OccNum), modtime.AsSQLString()))
return NVL;
1519 if (!NVL)
return kFALSE;
1521 for (Int_t OccNum = 0; OccNum < Occurs; OccNum++) {
1522 if (NVL->
IsValue(Form(
"Filename[%d]", OccNum), filename)) {
1524 return (!NVL->
HasParameter(Form(
"KVVersion[%d]", OccNum)));
1543 Error(
"Remove",
"Error opening available runs file");
1554 Int_t line_number = 1;
1557 lines_to_be_removed.
Begin();
1558 Int_t next_line_to_remove = 0;
1559 if (!lines_to_be_removed.
End()) next_line_to_remove = lines_to_be_removed.
Next();
1563 if (line_number != next_line_to_remove)
1564 tmp_file << line.Data() << endl;
1566 if (!lines_to_be_removed.
End()) next_line_to_remove = lines_to_be_removed.
Next();
1583 gSystem->CopyFile(tmp_file_path, fRunlist_path, kTRUE);
1585 gSystem->Chmod(fRunlist_path.Data(), CHMODE(6, 6, 4));
1587 gSystem->Unlink(tmp_file_path);
Handles lists of available runs for different datasets and types of data.
virtual void CloseAvailableRunsFile()
Bool_t CheckDirectoryForAvailableRunsFile()
virtual void Add(Int_t run, const Char_t *filename)
virtual Bool_t GetRunInfo(Int_t run, TDatime &modtime, TString &filename)
Bool_t ExtractDateFromFileName(const Char_t *name, KVDatime &date)
const Char_t * GetDataType() const
KVNumberList CheckMultiRunfiles()
Returns a list with all runs which occur more than once in the available runs file.
const KVDataSet * fDataSet
dataset to which this file belongs
virtual Bool_t CheckAvailable(Int_t run)
virtual void Update(Bool_t no_existing_file=kFALSE)
KVHashList * fAvailableRuns
temporary list used to store infos when updating
virtual KVNumberList GetRunList(const KVDBSystem *system=0)
const Char_t * GetFileName() const
KVLockfile runlist_lock
for locking runlist file
KVNameValueList * RunHasFileWithDateAndName(Int_t run, const Char_t *filename, TDatime modtime, Int_t &OccNum)
virtual TList * GetListOfAvailableSystems(const KVDBSystem *systol=0)
virtual Int_t Count(Int_t run)
static KVString date_read_from_filename
virtual void UpdateInfos(Int_t run, const Char_t *filename, const Char_t *kvversion, const Char_t *username)
const Char_t * GetFullPathToAvailableRunsFile() const
virtual void Remove(Int_t run, const Char_t *filename="")
KVAvailableRunsFile()
Default ctor.
virtual void GetRunInfos(Int_t run, KVList *dates, KVList *names)
virtual Bool_t InfosNeedUpdate(Int_t run, const Char_t *filename)
std::ifstream fRunlist
for reading runlist file
Int_t IsRunFileName(const Char_t *filename)
virtual Bool_t OpenAvailableRunsFile()
const Char_t * GetFilePath() const
void RemoveDuplicateLines(KVNumberList lines_to_be_removed)
Base class for KaliVeda framework.
static void OpenTempFile(TString &base, std::ofstream &fp)
static const Char_t * GetWORKDIRFilePath(const Char_t *namefile="")
static bool is_gnuinstall()
static const Char_t * GetDataSetEnv(const Char_t *dataset, const Char_t *type, const Char_t *defval)
virtual Bool_t IsCalled(const Char_t *name) const
static Bool_t SearchAndOpenKVFile(const Char_t *name, KVSQLite::database &dbfile, const Char_t *kvsubdir="")
static const Char_t * GetKVVersion()
Returns KaliVeda version string.
virtual Int_t GetNumber() const
Description of an experimental run in database ,,.
void SetDatime(TDatime &dat)
void SetUserName(const Char_t *U)
void SetKVVersion(const Char_t *V)
KVDBSystem * GetSystem() const
const Char_t * GetStartDate() const
Database class used to store information on different colliding systems studied during an experiment....
void SetNumberRuns(Int_t n)
set number of runs associated to this system
Base class for managing repositories of experimental data.
virtual 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)
Manage an experimental dataset corresponding to a given experiment or campaign.
KVDataRepository * GetRepository() const
Get pointer to data repository in which dataset is stored.
const Char_t * GetDataSetDir() const
const Char_t * GetDataSetEnv(const Char_t *type, const Char_t *defval="") const
virtual const Char_t * GetDataPathSubdir() const
Returns name of top-level directory in data repository used to store data files for this dataset.
KVExpDB * GetDataBase(Option_t *opt="") const
const Char_t * GetDataTypeSubdir(const Char_t *type) const
Extension of TDatime to handle various useful date formats.
static Bool_t IsGANACQFormat(const Char_t *date)
static Bool_t IsSQLFormat(const Char_t *date)
static Bool_t IsGANACQ2010Format(const Char_t *date)
void SetSQLDate(const Char_t *SQLDateString)
void SetGanacqNarvalDate(const Char_t *GanacqDateString)
static Bool_t IsGANACQNarvalFormat(const Char_t *date)
void SetGanacq2010Date(const Char_t *GanacqDateString)
void SetGanacqDate(const Char_t *GanacqDateString)
Base class to describe database of an experiment ,,.
KVDBRun * GetDBRun(Int_t number) const
Extended version of ROOT THashList.
Extended TList class which owns its objects by default.
Bool_t Lock(const Char_t *filename="")
Handles lists of named parameters with different types, a list of KVNamedParameter objects.
Int_t GetIntValue(const Char_t *name) const
void SetValue(const Char_t *name, value_type value)
Bool_t IsValue(const Char_t *name, value_type value) const
const Char_t * GetStringValue(const Char_t *name) const
Bool_t HasParameter(const Char_t *name) const
Strings used to represent a set of ranges of values.
void Add(Int_t)
Add value 'n' to the list.
Description of an individual run file in an experimental dataset.
virtual void SetOwner(Bool_t enable=kTRUE)
virtual Int_t GetSize() const
virtual void Add(TObject *obj)
virtual void Delete(Option_t *option="")
virtual TObject * FindObject(const char *name) const
Extension of ROOT TString class which allows backwards compatibility with ROOT v3....
void Begin(TString delim) const
KVString Next(Bool_t strip_whitespace=kFALSE) const
Int_t GetNValues(TString delim) const
Optimised list in which named objects can only be placed once.