KaliVeda
Toolkit for HIC analysis
KVBase.cpp
1 /***************************************************************************
2 $Id: KVBase.cpp,v 1.57 2009/04/22 09:38:39 franklan Exp $
3  kvbase.cpp - description
4  -------------------
5  begin : Thu May 16 2002
6  copyright : (C) 2002 by J.D. Frankland
7  email : frankland@ganil.fr
8  ***************************************************************************/
9 
10 /***************************************************************************
11  * *
12  * This program is free software; you can redistribute it and/or modify *
13  * it under the terms of the GNU General Public License as published by *
14  * the Free Software Foundation; either version 2 of the License, or *
15  * (at your option) any later version. *
16  * *
17  ***************************************************************************/
18 #include <cassert>
19 #include "KVBase.h"
20 #include "TClass.h"
21 #include "KVString.h"
22 #include "TRandom.h"
23 #include "TSystem.h"
24 #include "TInterpreter.h"
25 #include "TPluginManager.h"
26 #include "KVNameValueList.h"
27 #include "KVSystemDirectory.h"
28 #include "KVVersion.h"
29 #ifdef WITH_GIT_INFOS
30 #include "KVGitInfo.h"
31 #endif
32 #ifdef WITH_RSQLITE
33 #include "SQLiteDB.h"
34 #endif
35 #include "TROOT.h"
36 #include "TDatime.h"
37 #include "THashList.h"
38 #include "TGMimeTypes.h"
39 #include "TGClient.h"
40 #include "TContextMenu.h"
41 #include <TFileMerger.h>
42 #include <TH1.h>
43 #include <TKey.h>
44 #include <fstream>
45 
46 using namespace std;
47 
49 
50 // for multithread safety
51 std::mutex _kvbase_mutex;
52 TString KVBase::fWorkingDirectory = "$(HOME)/.kaliveda";
54 
55 
57 
58 const Char_t* KVBase::GetETCDIRFilePath(const Char_t* namefile)
59 {
60  if (strcmp(namefile, "")) return Form("%s/%s", kaliveda::build_infos::ETCDIR.c_str(), namefile);
61  return kaliveda::build_infos::ETCDIR.c_str();
62 }
63 
64 
66 
67 const Char_t* KVBase::GetDATADIRFilePath(const Char_t* namefile)
68 {
69  if (strcmp(namefile, "")) return Form("%s/%s", kaliveda::build_infos::DATADIR.c_str(), namefile);
70  return kaliveda::build_infos::DATADIR.c_str();
71 }
72 
73 
75 
77 {
78  if (strcmp(namefile, "")) return Form("%s/%s", kaliveda::build_infos::TEMPLATEDIR.c_str(), namefile);
80 }
81 
82 
84 
86 {
87  return Form("%s/db", fWorkingDirectory.Data());
88 }
89 
90 
92 
93 const Char_t* KVBase::GetLIBDIRFilePath(const Char_t* namefile)
94 {
95  if (strcmp(namefile, "")) return Form("%s/%s", kaliveda::build_infos::LIBDIR.c_str(), namefile);
96  return kaliveda::build_infos::LIBDIR.c_str();
97 }
98 
99 
101 
102 const Char_t* KVBase::GetINCDIRFilePath(const Char_t* namefile)
103 {
104  if (strcmp(namefile, "")) return Form("%s/%s", kaliveda::build_infos::INCDIR.c_str(), namefile);
105  return kaliveda::build_infos::INCDIR.c_str();
106 }
107 
108 
110 
111 const Char_t* KVBase::GetBINDIRFilePath(const Char_t* namefile)
112 {
113  if (strcmp(namefile, "")) return Form("%s/%s", kaliveda::build_infos::BINDIR.c_str(), namefile);
114  return kaliveda::build_infos::BINDIR.c_str();
115 }
116 
117 
119 
120 const Char_t* KVBase::GetWORKDIRFilePath(const Char_t* namefile)
121 {
122  if (strcmp(namefile, "")) return Form("%s/%s", fWorkingDirectory.Data(), namefile);
123  return fWorkingDirectory;
124 }
125 
126 
128 
130 {
132 }
133 
134 
136 
138 {
140 }
141 
142 
144 
146 {
148 }
149 
150 
153 
155 {
156  //Default initialisation
157 
158  InitEnvironment();
159  fNumber = 0;
160  fLabel = "";
161  SetBit(kIsKaliVedaObject);
162 }
163 
164 
165 
195 
197 {
198  // STATIC method to Initialise KaliVeda environment
199  // Reads config files in <code>\$(pkgdatadir)/etc</code> and sets up environment
200  // (data repositories, datasets, etc. etc.).
201  // Adds directory where kaliveda shared libs are installed to the dynamic
202  // path - for finding and loading plugins.
203  // Resets the `gRandom` random number sequence using a clock-based seed
204  // (i.e. random sequences do not repeat).
205  //
206  // Normally, the first object created which inherits from KVBase will
207  // perform this initialisation; if you need to set up the environment before
208  // creating a KVBase object, or if you just want to be absolutely sure that
209  // the environment has been initialised, you can call this method.
210  //
211  // #### Note for GNU-style installations
212  // If KaliVeda is built with the cmake option `-Dgnuinstall=yes` then each
213  // user will have a working directory which will be used to store any files
214  // generated by KaliVeda at runtime.
215  //
216  // By default the location of user's working directory is set to
217  //~~~~~~~~~
218  // $(HOME)/.kaliveda
219  //~~~~~~~~~
220  // but can be changed with variable
221  //~~~~~~~~~
222  // KaliVeda.WorkingDirectory: [directory]
223  //~~~~~~~~~
224  // in configuration file `.kvrootrc`.
225  //`[directory]` must be an absolute pathname, but can use shell variables like <code>\$(HOME)</code>.
226 
227  std::lock_guard<std::mutex> lk(_kvbase_mutex); // prevent multiple initialisation in different threads
228 
229  if (!fEnvIsInit) {//test if environment already initialised
230 
231  // enable ROOT thread safety
233 
234  // Add path to kaliveda libraries to dynamic loader path
235  // This is needed to find plugins
236  // and also to be able to compile with kaliveda in the interpreter
237  TString libdir = GetLIBDIRFilePath();
238  gSystem->AddDynamicPath(libdir);
239  // force re-reading of rootmap files in new dynamic path
240  gInterpreter->LoadLibraryMap();
241  // Add path to kaliveda header files
242  // This is needed to be able to compile with kaliveda in the interpreter
243  TString incdir = GetINCDIRFilePath();
244  incdir.Prepend("-I");
245  gSystem->AddIncludePath(incdir);
246 
247  //set up environment using kvrootrc file
248  if (!gEnv->Defined("DataSet.DatabaseFile")) {
249  ReadConfigFiles();
250  }
251 #ifdef WITH_GNU_INSTALL
252  // set working directory & create if needed
253  fWorkingDirectory = gEnv->GetValue("KaliVeda.WorkingDirectory", "$(HOME)/.kaliveda");
254  gSystem->ExpandPathName(fWorkingDirectory);
255  gSystem->mkdir(fWorkingDirectory, kTRUE);
256 #else
257  // set environment variable used in database makefiles
258  fWorkingDirectory = KV_ROOT;
259 #endif
260  // set environment variable used in database makefiles
261  gSystem->Setenv("KV_WORK_DIR", fWorkingDirectory);
262 
263  //generate new seed from system clock
264  gRandom->SetSeed(0);
265 
266  // initialisation has been performed
267  fEnvIsInit = kTRUE;
268  }
269 }
270 
271 
272 
280 
282 {
283  // Read all configuration files
284  // System config files are read first in the order they appear in file
285  // ${ETCDIR}/config.files
286  // Then we read any of the following files if they exist:
287  // ${HOME}/.kvrootrc
288  // ${PWD}/.kvrootrc (if PWD!=HOME)
289 
290  TString tmp = GetETCDIRFilePath("config.files");
291  ifstream conflist;
292  conflist.open(tmp.Data());
293  if (!conflist.good()) {
294  ::Fatal("KVBase::ReadConfigFiles", "Cannot open %s", tmp.Data());
295  return;
296  }
297  KVString file;
298  file.ReadLine(conflist);
299  conflist.close();
300  file.Begin(";");
301  while (!file.End()) {
302  tmp = GetETCDIRFilePath(file.Next().Data());
303  //skip over any missing files - this is needed when installing from
304  //e.g. ubuntu packages if not all packages are installed
305  if (!gSystem->AccessPathName(tmp.Data())) gEnv->ReadFile(tmp.Data(), kEnvChange);
306  }
307 
308  AssignAndDelete(tmp, gSystem->ConcatFileName(gSystem->Getenv("HOME"), ".kvrootrc"));
309  gEnv->ReadFile(tmp.Data(), kEnvChange);
310 
311  if (TString(gSystem->pwd()) != gSystem->HomeDirectory()) {
312  tmp = "./.kvrootrc";
313  gEnv->ReadFile(tmp.Data(), kEnvChange);
314  }
315 
316  // load plugin handlers
317  gROOT->GetPluginManager()->LoadHandlersFromEnv(gEnv);
318 
319  // load mime types/icon definitions when not in batch (i.e. GUI-less) mode
320  if (!gROOT->IsBatch()) ReadGUIMimeTypes();
321 }
322 
323 
324 
327 
329 {
330  //Default constructor.
331  init();
332 }
333 
334 
335 
338 
339 KVBase::KVBase(const Char_t* name, const Char_t* type): TNamed(name, type)
340 {
341  //Ctor for object with given name and type.
342  init();
343 }
344 
345 
346 
349 
350 KVBase::KVBase(const KVBase& obj) : TNamed()
351 {
352  //copy ctor
353  init();
354 #if ROOT_VERSION_CODE >= ROOT_VERSION(3,4,0)
355  obj.Copy(*this);
356 #else
357  ((KVBase&) obj).Copy(*this);
358 #endif
359 }
360 
361 
362 
365 
367 {
368  // copy assignment operator
369 
370  if (&other != this) {
371  other.Copy(*this);
372  }
373  return (*this);
374 }
375 
376 
377 
378 
381 
383 {
384  //Clear object properties : name, type/title, number, label
385  TNamed::Clear(opt);
386  fNumber = 0;
387  fLabel = "";
388 }
389 
390 
391 #if ROOT_VERSION_CODE >= ROOT_VERSION(3,4,0)
392 
395 
396 void KVBase::Copy(TObject& obj) const
397 #else
398 void KVBase::Copy(TObject& obj)
399 #endif
400 {
401  //Make a copy of this object
402 
403  TNamed::Copy(obj);
404  ((KVBase&) obj).SetNumber(fNumber);
405  ((KVBase&) obj).SetLabel(fLabel);
406 }
407 
408 
409 
411 
413 {
414  cout << "KVBase object: Name=" << GetName() << " Type=" << GetType();
415  if (fLabel != "")
416  cout << " Label=" << GetLabel();
417  if (fNumber != 0)
418  cout << " Number=" << GetNumber();
419  cout << endl;
420 }
421 
422 
423 
429 
430 void KVBase::Streamer(TBuffer& R__b)
431 {
432  //Backwards compatible streamer for KVBase objects
433  //Needed to handle 'fLabel' char array in class version 1
434  //Objects written with version < 3 did not have kIsKaliVedaObject bit set,
435  //we set it here when reading object.
436 
437  if (R__b.IsReading()) {
438  UInt_t R__s, R__c;
439  Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
440  if (R__v > 1) {
441  if (R__v < 4) {
442  TNamed::Streamer(R__b);
443  R__b >> fNumber;
444  R__b >> fLabel;
445  if (R__v < 3) SetBit(kIsKaliVedaObject);
446  R__b.CheckByteCount(R__s, R__c, KVBase::IsA());
447  }
448  else {
449  //AUTOMATIC STREAMER EVOLUTION FOR CLASS VERSION > 3
450  KVBase::Class()->ReadBuffer(R__b, this, R__v, R__s, R__c);
451  }
452  return;
453  }
454  //OLD STREAMER FOR CLASS VERSION 1
455  TNamed::Streamer(R__b);
456  R__b >> fNumber;
457  UInt_t LabelLength;
458  R__b >> LabelLength;
459  if (LabelLength) {
460  Char_t* Label = new Char_t[LabelLength];
461  R__b.ReadFastArray(Label, LabelLength);
462  fLabel = Label;
463  delete[]Label;
464  }
466  R__b.CheckByteCount(R__s, R__c, KVBase::IsA());
467  }
468  else {
469  KVBase::Class()->WriteBuffer(R__b, this);
470  }
471 }
472 
473 
474 
475 
487 
488 Bool_t SearchFile(const Char_t* name, TString& fullpath, int ndirs, ...)
489 {
490  //Search for file in an arbitrary number of locations, return kTRUE if file found and put full path to file in 'fullpath"
491  //
492  //'name' is a filename (not an absolute pathname) i.e. "toto.dat"
493  //'fullpath" will contain the full path to the file if it is found (if file not found, fullpath="")
494  //'ndirs" is the number of directories to search in
495  //the remaining arguments are the names of 'ndirs' paths to search in, i.e.
496  //
497  // SearchFile("toto.dat", fullpath, 2, gSystem->pwd(), gSystem->HomeDirectory());
498  //
499  //means: search for a file 'toto.dat' in current working directory, then user's home directory.
500 
501  if (ndirs <= 0)
502  return kFALSE;
503 
504  va_list args;
505  va_start(args, ndirs);
506 
507  for (; ndirs; ndirs--) { //loop over directories
508 
509  AssignAndDelete(fullpath,
510  gSystem->ConcatFileName(va_arg(args, const char*),
511  name));
512  if (!gSystem->AccessPathName(fullpath.Data())) {
513  va_end(args);
514  return kTRUE;
515  }
516 
517  }
518 
519  va_end(args);
520  fullpath = ""; //clear fullpath string to avoid using it by mistake
521  return kFALSE;
522 }
523 
524 
525 
539 
540 Bool_t KVBase::SearchKVFile(const Char_t* name, TString& fullpath,
541  const Char_t* kvsubdir)
542 {
543  //search for files in the following order:
544  // if 'name' = absolute path the function returns kTRUE if the file exists
545  // if name != absolute path:
546  // 1. a. if 'kvsubdir'="" (default) look for file in $(pkgdatadir) directory
547  // 1. b. if 'kvsubdir'!="":
548  // if 'kvsubdir' is an absolute pathname, look in 'kvsubdir'
549  // if 'kvsubdir' is not an absolute pathname,
550  // look in '$(pkdatadir)/kvsubdir'
551  // 2. look for file with this name in user's home directory
552  // 3. look for file with this name in current working directory
553  //in all cases the function returns kTRUE if the file was found.
554  //'fullpath' then contains the absolute path to the file
555 
557  // absolute path
558  fullpath = name;
559  return !gSystem->AccessPathName(name);
560  }
561 
562  TString kvfile_dir;
563  if (strcmp(kvsubdir, "")) {
564  // subdirectory hint given
565  if (!gSystem->IsAbsoluteFileName(kvsubdir))
566  kvfile_dir = GetDATADIRFilePath(kvsubdir); // relative path - assume in $(pkgdatadir)
567  else
568  kvfile_dir = kvsubdir; // absolute path - use as is
569  }
570  else // no subdirectory hint given
571  kvfile_dir = GetDATADIRFilePath();
572 
573  return SearchFile(name, fullpath, 3, kvfile_dir.Data(),
575 }
576 
577 
578 
579 
599 
600 Bool_t KVBase::SearchAndOpenKVFile(const Char_t* name, ifstream& file, const Char_t* kvsubdir, KVLockfile* locks)
601 {
602  //Search and open for READING a file:
603  //
604  //search for ascii file (and open it, if found) in the following order:
605  // if 'name' = absolute path the function returns kTRUE if the file exists
606  // if name != absolute path:
607  // 1. a. if 'kvsubdir'="" (default) look for file in $(pkdatadir) directory
608  // 1. b. if 'kvsubdir'!="" look for file in $(pkdatadir)/'kvsubdir'
609  // if 'kvsubdir' is an absolute pathname, look in 'kvsubdir'
610  // if 'kvsubdir' is not an absolute pathname,
611  // look in '$(pkdatadir)/kvsubdir'
612  // 2. look for file with this name in user's home directory
613  // 3. look for file with this name in working directory
614  //if the file is not found, kFALSE is returned.
615  //if file is found and can be opened, 'file' is then an ifstream connected to the open (ascii) file
616  //
617  //LOCKFILE:
618  //If a KVLockfile pointer is given, we use it to get a lock on the file before opening it.
619  //If this lock is not successful, the file is not opened and we return an error message.
620 
621  TString fullpath;
622  if (SearchKVFile(name, fullpath, kvsubdir)) {
623  //put lock on file if required
624  if (locks && !locks->Lock(fullpath.Data())) return kFALSE;
625  file.open(fullpath.Data());
626  if (file.good()) {
627  //cout << "Opened file : " << fullpath.Data() << endl;
628  return kTRUE;
629  }
630  //unlock file if not opened successfully
631  if (locks) locks->Release();
632  }
633  return kFALSE;
634 }
635 
636 
637 #ifdef WITH_RSQLITE
638 
650 
651 Bool_t KVBase::SearchAndOpenKVFile(const Char_t* name, KVSQLite::database& dbfile, const Char_t* kvsubdir)
652 {
653  //Search and open for reading/writing a sqlite database file:
654  //
655  //search for file (and open it, if found) in the following order:
656  // if 'name' = absolute path the function returns kTRUE if the file exists
657  // if name != absolute path:
658  // 1. a. if 'kvsubdir'="" (default) look for file in $(pkdatadir) directory
659  // 1. b. if 'kvsubdir'!="" look for file in $(pkdatadir)/'kvsubdir'
660  // 2. look for file with this name in user's home directory
661  // 3. look for file with this name in working directory
662  //if the file is not found, kFALSE is returned.
663 
664  TString fullpath;
665  if (SearchKVFile(name, fullpath, kvsubdir)) {
666  dbfile.open(fullpath);
667  if (dbfile.good()) {
668  //cout << "Opened file : " << fullpath.Data() << endl;
669  return kTRUE;
670  }
671  }
672  return kFALSE;
673 }
674 
675 #endif
676 
677 
696 
697 Bool_t KVBase::SearchAndOpenKVFile(const Char_t* name, ofstream& file, const Char_t* kvsubdir, KVLockfile* locks)
698 {
699  //Search and CREATE i.e. open for WRITING a file:
700  //
701  //open for writing an ascii file in the location determined in the following way:
702  // if 'name' = absolute path we use the full path
703  // if name != absolute path:
704  // 1. a. if 'kvsubdir'="" (default) file will be in $(pkdatadir) directory
705  // 1. b. if 'kvsubdir'!="":
706  // if 'kvsubdir' is an absolute pathname, file in 'kvsubdir'
707  // if 'kvsubdir' is not an absolute pathname,
708  // file will be in '$(pkdatadir)/kvsubdir'
709  //if an existing file is found, a warning is printed and the existing file 'toto' is renamed
710  //"toto.date". where 'date' is created with TDatime::AsSQLDate
711  // file' is then an ofstream connected to the opened file
712  //
713  //LOCKFILE:
714  //If a KVLockfile pointer is given, we use it to get a lock on the file before opening it.
715  //If this lock is not successful, the file is not opened and we return an error message.
716 
717  KVString fullpath;
718  if (gSystem->IsAbsoluteFileName(name)) {
719  fullpath = name;
720  }
721  else if (gSystem->IsAbsoluteFileName(kvsubdir)) {
722  AssignAndDelete(fullpath,
723  gSystem->ConcatFileName(kvsubdir, name));
724  }
725  else if (strcmp(kvsubdir, "")) {
726  KVString path = GetDATADIRFilePath(kvsubdir);
727  AssignAndDelete(fullpath,
728  gSystem->ConcatFileName(path.Data(), name));
729  }
730  else {
731  fullpath = GetDATADIRFilePath(name);
732  }
733  //Backup file if necessary
734  BackupFileWithDate(fullpath.Data());
735  //put lock on file if required
736  if (locks && !locks->Lock(fullpath.Data())) return kFALSE;
737  file.open(fullpath.Data());
738  return kTRUE;
739 }
740 
741 
742 
743 
754 
756 {
757  //`path` gives the full path (can include environment variables, special symbols)
758  //to a file which will be renamed with an extension containing the current date and time
759  //(in SQL format).
760  //
761  //Example:
762  //
763  // KVBase::BackupFileWithDate("$(HOME)/toto.txt")
764  //
765  //The file `toto.txt` will be renamed `toto.txt.2007-05-02_16:22:37`
766 
767  KVString fullpath = path;
768  gSystem->ExpandPathName(fullpath);
769  if (!gSystem->AccessPathName(fullpath.Data())) {//does the file exist ?
770  //backup file
771  TDatime now;
772  KVString date(now.AsSQLString());
773  date.ReplaceAll(' ', '_');
774  TString backup = fullpath + "." + date;
775  //lock both files
776  KVLockfile lf1(fullpath.Data()), lf2(backup.Data());
777  if (lf1.Lock() && lf2.Lock()) {
778  gSystem->Rename(fullpath.Data(), backup.Data());
779  printf("Info in <KVBase::BackupFileWithDate(const Char_t *)> : Existing file %s renamed %s\n",
780  fullpath.Data(), backup.Data());
781  }
782  }
783 }
784 
785 
786 
787 
794 
796 {
797  //Load plugin library in order to extend capabilities of base class "base", depending on
798  //the given uri (these arguments are used to call TPluginManager::FindHandler).
799  //Returns pointer to TPluginHandler.
800  //Returns 0 in case of problems.
801 
802  //does plugin exist for given name ?
803  TPluginHandler* ph =
804  (TPluginHandler*) gROOT->GetPluginManager()->FindHandler(base,
805  uri);
806  if (!ph)
807  return 0;
808 
809  //check plugin library/macro is available
810  if (ph->CheckPlugin() != 0)
811  return 0;
812 
813  //load plugin module
814  if (ph->LoadPlugin() != 0)
815  return 0;
816 
817  return ph;
818 }
819 
820 
821 
822 
828 
829 void KVBase::OpenTempFile(TString& base, ofstream& fp)
830 {
831  //Opens a uniquely-named file in system temp directory (gSystem->TempDirectory)
832  //Name of file is "basexxxxxxxxxx" where "xxxxxxxxx" is current time as returned
833  //by gSystem->Now().
834  //After opening file, 'base' contains full path to file.
835 
836  GetTempFileName(base);
837  fp.open(base.Data());
838 }
839 
840 
841 
842 
849 
851 {
852  //When called with base="toto.dat", the returned value of 'base' is
853  //"/full/path/to/temp/dir/toto.dat15930693"
854  //i.e. the full path to a file in the system temp directory (gSystem->TempDirectory)
855  //appended with the current time as returned by gSystem->Now() in order to make
856  //its name unique
857 
858  TString tmp1;
859  AssignAndDelete(tmp1,
861  base.Data()));
862  long lnow = (long) gSystem->Now();
863  base = tmp1 + lnow;
864  //make sure no existing file with same name
865  while (!gSystem->AccessPathName(base)) {
866  base = tmp1 + (++lnow);
867  }
868 }
869 
870 
871 
872 
875 
877 {
878  //Returns KaliVeda version string
879  return kaliveda::build_infos::KV_VERSION.c_str();
880 }
881 
882 
883 
884 
887 
889 {
890  // Returns username of person who performed build
892 }
893 
894 
895 
896 
899 
901 {
902  //Returns KaliVeda build date
904 }
905 
906 
907 
910 
912 {
913  //Returns KaliVeda build time
915 }
916 
917 
918 
919 
922 
924 {
925  //Returns KaliVeda build type (cmake build: Release, Debug, RelWithDebInfo, ...)
927 }
928 
929 
930 
931 
934 
936 {
937  //Returns top-level directory of source tree used for build
939 }
940 
941 
942 
943 
946 
948 {
949  //Returns top-level directory used for build
951 }
952 
953 
954 #ifdef WITH_GIT_INFOS
955 
958 
960 {
961  // Returns git branch of sources
962  return kaliveda::git_infos::KV_GIT_BRANCH.c_str();
963 }
964 
965 
966 
969 
971 {
972  // Returns last git commit of sources
973  return kaliveda::git_infos::KV_GIT_COMMIT.c_str();
974 }
975 
976 #endif
977 
978 
993 
995 {
996  //By default, `FindExecutable(exec)` will look for the executable named by `exec`
997  //in the directories contained in the environment variable `PATH`. You can override
998  //this by giving your own search `path` as second argument (remember to write
999  //environment variables as <code>\$(PATH)</code>, for cross-platform compatibility).
1000  //
1001  //If `exec` is not found, and if it does not end with `.exe`, we look for `exec.exe`
1002  //This is for compatibility with Windows/cygwin environments.
1003  //
1004  //If the executable is found, returns `kTRUE` and `exec` then holds full path to executable.
1005  //Returns `kFALSE` if `exec` not found in paths.
1006  //
1007  //If `exec` is an absolute pathname, we return `kTRUE` if the file exists
1008  //(we do not use `path`).
1009 
1010  TString spath(path), backup(exec), backup2(exec), expandexec(exec);
1011  gSystem->ExpandPathName(expandexec);
1012  if (gSystem->IsAbsoluteFileName(expandexec.Data())) {
1013  //executable given as absolute path
1014  //we check if it exists
1015  if (!gSystem->AccessPathName(expandexec)) {
1016  exec = expandexec;
1017  return kTRUE;
1018  }
1019  else {
1020  //try with ".exe" in case of Windows system
1021  if (!expandexec.EndsWith(".exe")) {
1022  expandexec += ".exe";
1023  if (!gSystem->AccessPathName(expandexec)) {
1024  exec = expandexec;
1025  return kTRUE;
1026  }
1027  }
1028  }
1029  exec = backup;
1030  return kFALSE;
1031  }
1032  gSystem->ExpandPathName(spath);
1033  if (KVBase::FindFile(spath.Data(), exec))
1034  return kTRUE;
1035  if (!backup.EndsWith(".exe")) {
1036  backup += ".exe";
1037  if (KVBase::FindFile(spath.Data(), backup)) {
1038  exec = backup;
1039  return kTRUE;
1040  }
1041  }
1042  exec = backup2;
1043  return kFALSE;
1044 }
1045 
1046 
1047 
1048 
1052 
1053 const Char_t* KVBase::FindFile(const Char_t* search, TString& wfil)
1054 {
1055  //Backwards compatible fix for `TSystem::FindFile` which only exists from ROOT version 5.12/00 onwards.
1056  //Use this method as a replacement for `gSystem->FindFile` (same arguments)
1057 #ifdef __WITHOUT_TSYSTEM_FINDFILE
1058  Char_t* result = gSystem->Which(search, wfil.Data());
1059  if (result) {
1060  wfil = result;
1061  delete[]result;
1062  }
1063  else {
1064  wfil = "";
1065  }
1066  return wfil.Data();
1067 #else
1068  return gSystem->FindFile(search, wfil);
1069 #endif
1070 }
1071 
1072 
1073 
1074 
1094 
1095 Bool_t KVBase::FindClassSourceFiles(const KVString& class_name, KVString& imp_file, KVString& dec_file, const KVString& dir_name)
1096 {
1097  //Look for the source files corresponding to `class_name`
1098  //i.e. taking class_name as a base, we look for one of
1099  //
1100  //~~~~~~~
1101  //class_name.C,class_name.cpp,class_name.cxx
1102  //~~~~~~~
1103  //
1104  //and one of
1105  //
1106  //~~~~~~~
1107  //class_name.h,class_name.hh,class_name.H
1108  //~~~~~~~
1109  //
1110  //By default we look in the current working directory, unless argument `dir_name`
1111  //is given
1112  //
1113  //If found, the names of the two files are written in `imp_file` and
1114  //`dec_file`
1115 
1116  KVNameValueList impl_alt;
1117  int i = 0;
1118  impl_alt.SetValue("%s.C", i);
1119  impl_alt.SetValue("%s.cpp", i);
1120  impl_alt.SetValue("%s.cxx", i);
1121  KVNameValueList decl_alt;
1122  decl_alt.SetValue("%s.h", i);
1123  decl_alt.SetValue("%s.hh", i);
1124  decl_alt.SetValue("%s.H", i);
1125 
1126  TString _dir_name = dir_name;
1127  KVSystemDirectory dir("LocDir", _dir_name);
1128  TList* lf = dir.GetListOfFiles();
1129  Bool_t ok_imp, ok_dec;
1130  ok_imp = ok_dec = kFALSE;
1131 
1132  //look for implementation file
1133  for (i = 0; i < impl_alt.GetNpar(); i++) {
1134  if (lf->FindObject(Form(impl_alt.GetParameter(i)->GetName(), class_name.Data()))) {
1135  imp_file = Form(impl_alt.GetParameter(i)->GetName(), class_name.Data());
1136  ok_imp = kTRUE;
1137  }
1138  }
1139  //look for header file
1140  for (i = 0; i < decl_alt.GetNpar(); i++) {
1141  if (lf->FindObject(Form(decl_alt.GetParameter(i)->GetName(), class_name.Data()))) {
1142  dec_file = Form(decl_alt.GetParameter(i)->GetName(), class_name.Data());
1143  ok_dec = kTRUE;
1144  }
1145  }
1146  return (ok_imp && ok_dec);
1147 }
1148 
1149 
1150 
1151 
1167 
1168 const Char_t* KVBase::GetPluginURI(const Char_t* base, const Char_t* derived)
1169 {
1170  //Inverse of `gPluginMgr->FindHandler(const Char_t* base, const Char_t* uri)`
1171  //
1172  //Given a base class `base` and a derived class `derived`, we search `gEnv` to find the
1173  //URI corresponding to this plugin.
1174  //
1175  //Example: given a plugin such as
1176  //
1177  //~~~~~~~~
1178  //Plugin.KVIDTelescope: ^PHOS$ KVIDPhoswich KVIndra "KVIDPhoswich()"
1179  //~~~~~~~~
1180  //
1181  //then calling `KVBase::GetPluginURI("KVIDTelescope", "KVIDPhoswich")` will return `"PHOS"`.
1182  //
1183  //Most of the code is copied from `TPluginManager::LoadHandlersFromEnv`
1184 
1185  TIter next(gEnv->GetTable());
1186  TEnvRec* er;
1187  static TString tmp;
1188 
1189  while ((er = (TEnvRec*) next())) {
1190  const char* s;
1191  if ((s = strstr(er->GetName(), "Plugin."))) {
1192  // use s, i.e. skip possible OS and application prefix to Plugin.
1193  // so that GetValue() takes properly care of returning the value
1194  // for the specified OS and/or application
1195  const char* val = gEnv->GetValue(s, (const char*)0);
1196  if (val) {
1197  Int_t cnt = 0;
1198  s += 7;
1199  //is it the right base class ?
1200  if (strcmp(s, base)) continue; //skip to next env var if not right base
1201 
1202  char* v = StrDup(val);
1203  while (1) {
1204  TString regexp = strtok(!cnt ? v : 0, "; ");
1205  if (regexp.IsNull()) break;
1206  TString clss = strtok(0, "; ");
1207  if (clss.IsNull()) break;
1208  TString plugin = strtok(0, "; ");
1209  if (plugin.IsNull()) break;
1210  TString ctor = strtok(0, ";\"");
1211  if (!ctor.Contains("("))
1212  ctor = strtok(0, ";\"");
1213  if (clss == derived) {
1214  //found the required plugin
1215  //we remove the 'regexp' operator '^' from the beginning
1216  //and '$' from the end of the URI, if necessary
1217  if (regexp.MaybeRegexp()) {
1218  regexp.Remove(TString::kBoth, '^');
1219  regexp.Remove(TString::kBoth, '$');
1220  }
1221  tmp = regexp;
1222  delete [] v;
1223  return tmp.Data();
1224  }
1225  cnt++;
1226  }
1227  delete [] v;
1228  }
1229  }
1230  }
1231  tmp = "";
1232  return tmp;
1233 }
1234 
1235 
1236 
1237 
1250 
1252 {
1253  // Return whitespace-separated list of all plugin classes defined for
1254  // the given base class.
1255  //
1256  // E.g. if plugins exist for BaseClass:
1257  //
1258  // Plugin.BaseClass: URI PluginClass PluginLibrary "PluginClassConstructor(arguments)"
1259  // +Plugin.BaseClass: URI2 PluginClass2 PluginLibrary2 "PluginClass2Constructor(arguments)"
1260  //
1261  // then KVBase::GetListOfPlugins("BaseClass") will return "PluginClass PluginClass2"
1262  //
1263  // Most of the code is copied from `TPluginManager::LoadHandlersFromEnv`
1264 
1265  TIter next(gEnv->GetTable());
1266  TEnvRec* er;
1267  static TString tmp;
1268  tmp = "";
1269  while ((er = (TEnvRec*) next())) {
1270  const char* s;
1271  if ((s = strstr(er->GetName(), "Plugin."))) {
1272  // use s, i.e. skip possible OS and application prefix to Plugin.
1273  // so that GetValue() takes properly care of returning the value
1274  // for the specified OS and/or application
1275  const char* val = gEnv->GetValue(s, (const char*)0);
1276  if (val) {
1277  Int_t cnt = 0;
1278  s += 7;
1279  //is it the right base class ?
1280  if (strcmp(s, base)) continue; //skip to next env var if not right base
1281 
1282  char* v = StrDup(val);
1283  while (1) {
1284  TString regexp = strtok(!cnt ? v : 0, "; ");
1285  if (regexp.IsNull()) break;
1286  TString clss = strtok(0, "; ");
1287  if (clss.IsNull()) break;
1288  TString plugin = strtok(0, "; ");
1289  if (plugin.IsNull()) break;
1290  TString ctor = strtok(0, ";\"");
1291  if (!ctor.Contains("("))
1292  ctor = strtok(0, ";\"");
1293  tmp += clss;
1294  tmp += " ";
1295  cnt++;
1296  }
1297  delete [] v;
1298  }
1299  }
1300  }
1301  //remove final trailing whitespace
1302  tmp.Remove(TString::kTrailing, ' ');
1303  return tmp;
1304 }
1305 
1306 
1307 
1317 
1319 {
1320  // For a given base class, return a whitespace-separated list of plugin identifiers
1321  // which are known/defined.
1322  // E.g. if plugins exist for BaseClass:
1323  //
1324  // Plugin.BaseClass: URI PluginClass PluginLibrary "PluginClassConstructor(arguments)"
1325  // +Plugin.BaseClass: URI2 PluginClass2 PluginLibrary2 "PluginClass2Constructor(arguments)"
1326  //
1327  // then KVBase::GetListOfPluginURIs("BaseClass") will return "URI URI2"
1328 
1329  static TString tmp;
1330  KVString plugs = KVBase::GetListOfPlugins(base);
1331  plugs.Begin(" ");
1332  tmp = "";
1333  while (!plugs.End()) {
1334  if (tmp != "") tmp += " ";
1335  tmp += KVBase::GetPluginURI(base, plugs.Next());
1336  }
1337  return tmp;
1338 }
1339 
1340 
1341 
1347 
1349 {
1350  // Returns kTRUE if 'uri' is the name of a defined plugin, in which case 'base'
1351  // is the name of the base class extended by this plugin.
1352  //
1353  // Most of the code is copied from `TPluginManager::LoadHandlersFromEnv`
1354 
1355  TIter next(gEnv->GetTable());
1356  TEnvRec* er;
1357  while ((er = (TEnvRec*) next())) {
1358  KVString ername = er->GetName();
1359  if (ername.BeginsWith("Plugin.")) {
1360  base = ername;
1361  base.Remove(0, 7);
1362  KVString erval = gEnv->GetValue(ername, "");
1363  erval.Begin(" ");
1364  while (!erval.End()) {
1365  if (erval.Next() == uri) return kTRUE;
1366  }
1367  }
1368  }
1369  return kFALSE;
1370 }
1371 
1372 
1373 
1374 
1387 
1389 {
1390  // Add to standard ROOT mime types some new ones defined in `.kvrootrc`
1391  // for icons associated with graphs, runs, etc. by lines such as:
1392  //
1393  //~~~~~~~~~
1394  // KaliVeda.GUI.MimeTypes : KVIDMap
1395  // KaliVeda.GUI.MimeTypes.KVIDMap.Icon : rootdb_t.xpm
1396  // +KaliVeda.GUI.MimeTypes : KVIDZAGrid
1397  // KaliVeda.GUI.MimeTypes.KVIDZAGrid.Icon : draw_t.xpm
1398  //~~~~~~~~~
1399  //
1400  // etc.
1401 
1402  KVString mimetypes = gEnv->GetValue("KaliVeda.GUI.MimeTypes", "");
1403  if (mimetypes != "") {
1404 
1405  mimetypes.Begin(" ");
1406  while (!mimetypes.End()) {
1407 
1408  KVString classname = mimetypes.Next(kTRUE);
1409  KVString icon = gEnv->GetValue(Form("KaliVeda.GUI.MimeTypes.%s.Icon", classname.Data()), "draw_t.xpm");
1410  KVString type = classname;
1411  type.ToLower();
1412 
1413  if (gClient) gClient->GetMimeTypeList()->AddType(Form("[kaliveda/%s]", type.Data()),
1414  classname.Data(), icon.Data(), icon.Data(), "");
1415 
1416  }
1417  }
1418 }
1419 
1420 
1421 
1432 
1434 {
1435  // \brief Comparison between two 64-bit floating-point values
1436  //
1437  // Returns `kTRUE` if the integer representations of the two values are within
1438  // `maxdif` of each other. By default `maxdif=1`, which means that we consider that `x==y` if the
1439  // difference between them is no greater than the precision of `Double_t`
1440  // variables, i.e. `4.94065645841246544e-324`
1441  //
1442  // Based on the function `AlmostEqual2sComplement(float, float, int)`
1443  // by Bruce Dawson http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
1444 
1445  union converter {
1446  Double_t f;
1447  Long64_t i;
1448  } zero, val1, val2;
1449 
1450  assert(maxdif > 0);
1451 
1452  if (A == B) return true;
1453 
1454  /* rustine to obtain the (64-bit) constant value 0x8000000000000000
1455  even on 32-bit machines (there is probably an easier way!) */
1456  zero.i = 1;
1457  zero.f = -zero.f;
1458  zero.i -= 1;
1459 
1460  val1.f = A;
1461  val2.f = B;
1462  Long64_t Aint, Bint;
1463  Aint = val1.i;
1464  Bint = val2.i;
1465  if (Aint < 0) Aint = zero.i - Aint;
1466  if (Bint < 0) Bint = zero.i - Bint;
1467 
1468  Long64_t intDiff = abs(val1.i - val2.i);
1469 
1470  if (intDiff <= maxdif) return true;
1471 
1472  return false;
1473 }
1474 
1475 
1476 
1485 
1486 Bool_t KVBase::OpenContextMenu(const char* method, TObject* obj, const char* alt_method_name)
1487 {
1488  // Open context menu for given method of object *obj.
1489  // By default title of menu is 'obj->ClassName()::method'
1490  // You can give an alternative method name in 'alt_method_name'
1491  // Returns kFALSE if the given method is not defined for the class of object in question.
1492  //
1493  // WARNING: even if this method returns kTRUE, this is no guarantee that the method
1494  // has indeed been executed. The user may have pressed the 'Cancel' button...
1495 
1496  TMethod* m = obj->IsA()->GetMethodAllAny(method);
1497  if (!m) {
1498  KVError::Warning(obj, "OpenContextMenu", "%s is not a method of %s", method, obj->ClassName());
1499  return kFALSE;
1500  }
1501  TString Method = alt_method_name;
1502  if (Method == "") Method = method;
1503  TContextMenu* cm = new TContextMenu(Method, Form("%s::%s", obj->ClassName(), Method.Data()));
1504  cm->Action(obj, m);
1505  delete cm;
1506  return kTRUE;
1507 }
1508 
1509 
1510 
1517 
1518 void KVBase::CombineFiles(const Char_t* file1, const Char_t* file2, const Char_t* newfilename, Bool_t keep)
1519 {
1520  // STATIC method which allows to combine the contents of two ROOT files
1521  // (file1 and file2) into a new ROOT file (newfilename).
1522  // All objects from the two files will be written in the new file.
1523  //
1524  // if keep=kFALSE, the two files will be deleted after the operation
1525 
1526  ::Info("KVBase::CombineFiles", "Copying all objects from %s and %s ===> into new file %s", file1, file2, newfilename);
1527 
1528  TFileMerger file_merge;
1529  file_merge.AddFile(file1, kFALSE);
1530  file_merge.AddFile(file2, kFALSE);
1531  file_merge.OutputFile(newfilename);
1532  file_merge.Merge();
1533 
1534  // remove physical files from disk if required
1535  if (!keep) {
1536  gSystem->Unlink(file1);
1537  gSystem->Unlink(file2);
1538  }
1539 }
1540 
1541 
1542 
1550 
1552 {
1553  // Dummy method (returns NULL).
1554  // This method may be used in 'container' classes used with KVListView.
1555  // In order to open the context menu of the 'contained' object,
1556  // GetLabel() should return the real class of the object,
1557  // and this method should return its address.
1558  // Then call KVListView::SetUseObjLabelAsRealClass(kTRUE).
1559  return nullptr;
1560 }
1561 
1562 
1563 
1564 
1567 
1568 const Char_t* KVBase::GetExampleFilePath(const Char_t* library, const Char_t* namefile)
1569 {
1570  // Return full path to example file for given library (="KVMultiDet", "BackTrack", etc.)
1571  static TString path;
1572  path = KVBase::GetDATADIRFilePath("examples/");
1573  path += library;
1574  path += "/";
1575  path += namefile;
1576  return path.Data();
1577 }
1578 
1579 
1580 
1583 
1585 {
1586  // Prints welcome message and infos on version etc.
1587 
1588  cout << "/----------------------------------------------------------------------\\" << endl;
1589  cout << "| Welcome to KaliVeda v" << GetKVVersion() << " gitlab.in2p3.fr/kaliveda-dev/kaliveda |" << endl;
1590  cout << "| (c) 2002-2026, The KaliVeda development team |" << endl;
1591  cout << "| |" << endl;
1592  cout << "| Built with ROOT " << kaliveda::build_infos::KV_ROOT_VERSION << " on " << KVBase::GetKVBuildDate() << ", " << KVBase::GetKVBuildTime() << " |" << endl;
1593 #ifdef WITH_GIT_INFOS
1594  TString gitinfo;
1595  gitinfo.Form("%s@%s", gitBranch(), gitCommit());
1596  printf("| From %-63s |\n", gitinfo.Data());
1597 #endif
1598  cout << "| See https://kaliveda.in2p3.fr for help |" << endl;
1599  cout << "\\----------------------------------------------------------------------/" << endl << endl;
1600 }
1601 
1602 
1603 
1604 
1621 
1622 Double_t KVBase::ProtectedGetX(const TF1* func, Double_t val, GetX_status& status, std::optional<Double_t> xmin, std::optional<Double_t> xmax)
1623 {
1624  // For a given function, \f$f(x)\f$, find a solution for the equation
1625  //
1626  //\f[
1627  //f(x)=y
1628  //\f]
1629  //
1630  // If several solutions exist, the one with the smallest \f$x\f$ value is returned.
1631  //
1632  // \param[in] xmin,xmax if xmin!=xmax, limit to the given range (default: use range of function)
1633  // \param[out] status takes one of the values of enum class KVBase::GetX_status:
1634  // + GetX_status::ok : good solution
1635  // + GetX_status::above_maximum: val is > maximum of function in given range, value returned is func->GetMaximumX(xmin,xmax) [no solution]
1636  // + GetX_status::at_maximum: val is within 1.e-5 of the maximum of function, value returned is func->GetMaximumX() [solution corresponds to maximum]
1637  // + GetX_status::below_minimum: val is < minimum of function, value returned is func->GetMinimumX() [no solution]
1638  // + GetX_status::at_minimum: val is within 1.e-5 of the minimum of function, value returned is func->GetMinimumX() [solution corresponds to minimum]
1639 
1640  auto test_val = [](double x, double y){ return TMath::AreEqualAbs(x,y,1.e-5); };
1641  bool at_min_max = false;
1642  if(xmin || xmax)
1643  {
1644  if(!(xmin && xmax))
1645  {
1646  double _xmin,_xmax;
1647  func->GetRange(_xmin,_xmax);
1648  if(!xmin) xmin = _xmin;
1649  else xmax = _xmax;
1650  }
1651  auto fmax = func->GetMaximum(*xmin,*xmax);
1652  if (std::fdim(val,fmax) || (at_min_max=test_val(val,fmax))) {
1653  status = at_min_max ? GetX_status::at_maximum : GetX_status::above_maximum;
1654  return func->GetMaximumX(*xmin,*xmax);
1655  }
1656  auto fmin = func->GetMinimum(*xmin,*xmax);
1657  if (std::fdim(fmin,val) || (at_min_max=test_val(val,fmin))) {
1658  status = at_min_max ? GetX_status::at_minimum : GetX_status::below_minimum;
1659  return func->GetMinimumX(*xmin,*xmax);
1660  }
1661  status = GetX_status::ok;
1662  return func->GetX(val,*xmin,*xmax);
1663  }
1664  else
1665  {
1666  auto fmax = func->GetMaximum();
1667  if (std::fdim(val,fmax) || (at_min_max=test_val(val,fmax))) {
1668  status = at_min_max ? GetX_status::at_maximum : GetX_status::above_maximum;
1669  return func->GetMaximumX();
1670  }
1671  auto fmin = func->GetMinimum();
1672  if (std::fdim(fmin,val) || (at_min_max=test_val(val,fmin))) {
1673  status = at_min_max ? GetX_status::at_minimum : GetX_status::below_minimum;
1674  return func->GetMinimumX();
1675  }
1676  status = GetX_status::ok;
1677  return func->GetX(val);
1678  }
1679  return 0;
1680 }
1681 
1682 
1683 
1685 
1686 Double_t KVBase::ProtectedGetX(const TF1& func, Double_t val, GetX_status& status, std::optional<Double_t> xmin, std::optional<Double_t> xmax)
1687 {
1688  return ProtectedGetX(&func, val, status, xmin, xmax);
1689 }
1690 
1691 
1692 
1698 
1699 void KVBase::Deprecated(const char* where, const char* advice)
1700 {
1701  // Print a message to indicate when the called method is deprecated and give advice how to do better
1702  //
1703  // Don't call directly: use the macro Deprecate(advice) which will automatically fill in the method name
1704  // (see KVMacros.h)
1705 
1706  printf("Warning in <%s>: Method is deprecated in v%s and will be removed in future.\n%s\n",
1707  where, KVBase::GetKVVersion(), advice);
1708 }
1709 
1710 
1711 
1722 
1723 std::optional<TString> KVBase::AbsoluteUnixPath(const TString& _path)
1724 {
1725  // Turn any arbitrary unix-style path into an absolute path, working around limitations of
1726  // TSystem::ExpandPathName() (which doesn't handle '.' or '..')
1727  //
1728  // - if the path is not absolute but can be accessed, then it is a valid relative path from current working directory:
1729  // we prefix it with the current absolute working directory;
1730  // - if the path contains '.' (just a single dot, not 2!), we replace with the current working directory;
1731  // - if the path contains '..' (possibly more than once), we work out the equivalent absolute path.
1732  //
1733  // \returns std::nullopt if expansion fails
1734 
1735  TString path(_path);
1736  gSystem->ExpandPathName(path);
1737  if (!gSystem->IsAbsoluteFileName(path)) {
1738  if (!gSystem->AccessPathName(path)) {
1739  // path is valid starting from current directory: prefix it
1740  path.Prepend(TString(gSystem->WorkingDirectory()) + "/");
1741  }
1742  else {
1743  KVError::Error(KVBase{}, "AbsoluteUnixPath", "path is not absolute and not reachable from $(PWD)=%s: %s",
1744  gSystem->WorkingDirectory(), path.Data());
1745  return {};
1746  }
1747  }
1748  else if (gSystem->AccessPathName(path)) {
1749  KVError::Error(KVBase{}, "AbsoluteUnixPath", "absolute path is not valid: %s", path.Data());
1750  return {};
1751  }
1752  // if path has a trailing '/', remove it here to avoid losing the last part of the path
1753  // due to gSystem->BaseName() returning "" in this case.
1754  Bool_t trailing_slash = false;
1755  if (path.EndsWith("/")) {
1756  trailing_slash = true;
1757  while (path.EndsWith("/")) {
1758  path.Remove(path.Length() - 1, 1);
1759  }
1760  }
1761  // split into parts in order to deal with '..' and '.'
1762  std::vector<TString> parts;
1763  do {
1764  parts.push_back(gSystem->BaseName(path));
1765  path = gSystem->DirName(path);
1766  }
1767  while (path != "/");
1768  int nparts = parts.size() - 1;
1769  int end_path = 0;
1770  std::vector<TString> new_parts(parts.size());
1771  while (nparts >= 0) {
1772  if (parts[nparts] == "..")
1773  --end_path;
1774  else if (parts[nparts] != ".") {
1775  new_parts[end_path] = parts[nparts];
1776  ++end_path;
1777  }
1778  --nparts;
1779  }
1780  // stick all parts back together
1781  path = "/";
1782  for (int i = 0; i < end_path; ++i) {
1783  path += new_parts[i];
1784  if (i < end_path - 1)
1785  path += "/";
1786  }
1787  if (trailing_slash)
1788  path += "/";
1789  return path;
1790 }
1791 
1792 
int Int_t
unsigned int UInt_t
#define f(i)
bool Bool_t
short Version_t
char Char_t
constexpr Bool_t kFALSE
double Double_t
constexpr Bool_t kTRUE
const char Option_t
R__EXTERN TEnv * gEnv
kEnvChange
#define gClient
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 result
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]
float xmin
float xmax
#define gInterpreter
#define gROOT
R__EXTERN TRandom * gRandom
char * Form(const char *fmt,...)
char * StrDup(const char *str)
void AssignAndDelete(TString &target, char *tobedeleted)
R__EXTERN TSystem * gSystem
Base class for KaliVeda framework.
Definition: KVBase.h:140
static TString fWorkingDirectory
user working directory for e.g. database files
Definition: KVBase.h:149
void Clear(Option_t *opt="") override
Clear object properties : name, type/title, number, label.
Definition: KVBase.cpp:382
UInt_t fNumber
for numbering objects
Definition: KVBase.h:143
virtual const Char_t * GetType() const
Definition: KVBase.h:177
static const Char_t * GetBINDIRFilePath(const Char_t *namefile="")
Definition: KVBase.cpp:111
static void OpenTempFile(TString &base, std::ofstream &fp)
Definition: KVBase.cpp:829
GetX_status
Definition: KVBase.h:321
static const Char_t * GetDATADIRFilePath(const Char_t *namefile="")
Definition: KVBase.cpp:67
static const Char_t * GetDATABASEFilePath()
Definition: KVBase.cpp:85
static const Char_t * GetKVBuildDate()
Returns KaliVeda build date.
Definition: KVBase.cpp:900
static const Char_t * FindFile(const Char_t *search, TString &wfil)
Definition: KVBase.cpp:1053
static const Char_t * GetINCDIRFilePath(const Char_t *namefile="")
Definition: KVBase.cpp:102
static const Char_t * gitCommit()
Returns last git commit of sources.
Definition: KVBase.cpp:970
static const Char_t * GetWORKDIRFilePath(const Char_t *namefile="")
Definition: KVBase.cpp:120
void init()
Default initialisation.
Definition: KVBase.cpp:154
static Bool_t FindExecutable(TString &exec, const Char_t *path="$(PATH)")
Definition: KVBase.cpp:994
static const Char_t * GetKVBuildUser()
Returns username of person who performed build.
Definition: KVBase.cpp:888
static Double_t ProtectedGetX(const TF1 *func, Double_t val, GetX_status &status, std::optional< Double_t > xmin={}, std::optional< Double_t > xmax={})
Definition: KVBase.cpp:1622
static void BackupFileWithDate(const Char_t *path)
Definition: KVBase.cpp:755
static void ReadConfigFiles()
Definition: KVBase.cpp:281
static const Char_t * gitBranch()
Returns git branch of sources.
Definition: KVBase.cpp:959
static const Char_t * GetListOfPluginURIs(const Char_t *base)
Definition: KVBase.cpp:1318
TString fLabel
label for the object
Definition: KVBase.h:145
KVBase()
Default constructor.
Definition: KVBase.cpp:328
static int GetKVMajorVersion()
Definition: KVBase.cpp:129
static const Char_t * GetListOfPlugins(const Char_t *base)
Definition: KVBase.cpp:1251
static Bool_t fEnvIsInit
set when environment is initialised
Definition: KVBase.h:148
static Bool_t AreEqual(Double_t x, Double_t y, Long64_t maxdif=1)
Comparison between two 64-bit floating-point values.
Definition: KVBase.cpp:1433
KVBase & operator=(const KVBase &)
copy assignment operator
Definition: KVBase.cpp:366
static void CombineFiles(const Char_t *file1, const Char_t *file2, const Char_t *newfilename, Bool_t keep=kTRUE)
Definition: KVBase.cpp:1518
const Char_t * GetLabel() const
Definition: KVBase.h:199
static Bool_t FindClassSourceFiles(const KVString &class_name, KVString &imp_file, KVString &dec_file, const KVString &dir_name=".")
Definition: KVBase.cpp:1095
static const Char_t * GetTEMPLATEDIRFilePath(const Char_t *namefile="")
Definition: KVBase.cpp:76
static const Char_t * GetKVSourceDir()
Returns top-level directory of source tree used for build.
Definition: KVBase.cpp:935
void Copy(TObject &) const override
Make a copy of this object.
Definition: KVBase.cpp:396
static void InitEnvironment()
Definition: KVBase.cpp:196
void Print(Option_t *option="") const override
Definition: KVBase.cpp:412
static const Char_t * GetKVBuildTime()
Returns KaliVeda build time.
Definition: KVBase.cpp:911
static int GetKVMinorVersion()
Definition: KVBase.cpp:137
static void PrintSplashScreen()
Prints welcome message and infos on version etc.
Definition: KVBase.cpp:1584
static const Char_t * GetLIBDIRFilePath(const Char_t *namefile="")
Definition: KVBase.cpp:93
static std::optional< TString > AbsoluteUnixPath(const TString &)
Definition: KVBase.cpp:1723
static int GetKVPatchVersion()
Definition: KVBase.cpp:145
static const Char_t * GetExampleFilePath(const Char_t *library, const Char_t *namefile)
Return full path to example file for given library (="KVMultiDet", "BackTrack", etc....
Definition: KVBase.cpp:1568
static const Char_t * GetKVBuildDir()
Returns top-level directory used for build.
Definition: KVBase.cpp:947
static void ReadGUIMimeTypes()
Definition: KVBase.cpp:1388
static Bool_t IsThisAPlugin(const TString &uri, TString &base)
Definition: KVBase.cpp:1348
@ kIsKaliVedaObject
Definition: KVBase.h:160
virtual TObject * GetObject() const
Definition: KVBase.cpp:1551
static void GetTempFileName(TString &base)
Definition: KVBase.cpp:850
static Bool_t SearchKVFile(const Char_t *name, TString &fullpath, const Char_t *kvsubdir="")
Definition: KVBase.cpp:540
static const Char_t * GetKVBuildType()
Returns KaliVeda build type (cmake build: Release, Debug, RelWithDebInfo, ...)
Definition: KVBase.cpp:923
static const Char_t * GetPluginURI(const Char_t *base, const Char_t *plugin)
Definition: KVBase.cpp:1168
static const Char_t * GetETCDIRFilePath(const Char_t *namefile="")
Definition: KVBase.cpp:58
static Bool_t OpenContextMenu(const char *method, TObject *obj, const char *alt_method_name="")
Definition: KVBase.cpp:1486
static Bool_t SearchAndOpenKVFile(const Char_t *name, KVSQLite::database &dbfile, const Char_t *kvsubdir="")
Definition: KVBase.cpp:651
static TPluginHandler * LoadPlugin(const Char_t *base, const Char_t *uri="0")
Definition: KVBase.cpp:795
static const Char_t * GetKVVersion()
Returns KaliVeda version string.
Definition: KVBase.cpp:876
static void Deprecated(const char *method, const char *advice)
Definition: KVBase.cpp:1699
UInt_t GetNumber() const
Definition: KVBase.h:220
Interface to (Linux) system lockfile command.
Definition: KVLockfile.h:70
Bool_t Release()
Definition: KVLockfile.cpp:195
Bool_t Lock(const Char_t *filename="")
Definition: KVLockfile.cpp:165
Handles lists of named parameters with different types, a list of KVNamedParameter objects.
KVNamedParameter * GetParameter(Int_t idx) const
return the parameter object with index idx
void SetValue(const Char_t *name, value_type value)
Int_t GetNpar() const
return the number of stored parameters
Interface to ROOT SQLite database backend.
Definition: SQLiteDB.h:473
bool good() const
Definition: SQLiteDB.h:540
void open(const TString &dbfile)
Definition: SQLiteDB.cpp:125
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
Extension of ROOT TSystemDirectory class, handling browsing directories on disk.
TList * GetListOfFiles() const override
virtual Version_t ReadVersion(UInt_t *start=nullptr, UInt_t *bcnt=nullptr, const TClass *cl=nullptr)=0
virtual Int_t CheckByteCount(UInt_t startpos, UInt_t bcnt, const char *classname)=0
virtual void ReadFastArray(Bool_t *b, Int_t n)=0
Bool_t IsReading() const
Int_t ReadBuffer(TBuffer &b, void *pointer)
TMethod * GetMethodAllAny(const char *method)
Int_t WriteBuffer(TBuffer &b, void *pointer, const char *info="")
const char * AsSQLString() const
const char * GetName() const override
THashList * GetTable() const
virtual const char * GetValue(const char *name, const char *dflt) const
virtual Int_t ReadFile(const char *fname, EEnvLevel level)
Bool_t Defined(const char *name) const
virtual Double_t GetMinimumX(Double_t xmin=0, Double_t xmax=0, Double_t epsilon=1.E-10, Int_t maxiter=100, Bool_t logx=false) const
virtual Double_t GetMinimum(Double_t xmin=0, Double_t xmax=0, Double_t epsilon=1.E-10, Int_t maxiter=100, Bool_t logx=false) const
virtual Double_t GetX(Double_t y, Double_t xmin=0, Double_t xmax=0, Double_t epsilon=1.E-10, Int_t maxiter=100, Bool_t logx=false) const
virtual void GetRange(Double_t &xmin, Double_t &xmax) const
virtual Double_t GetMaximum(Double_t xmin=0, Double_t xmax=0, Double_t epsilon=1.E-10, Int_t maxiter=100, Bool_t logx=false) const
virtual Double_t GetMaximumX(Double_t xmin=0, Double_t xmax=0, Double_t epsilon=1.E-10, Int_t maxiter=100, Bool_t logx=false) const
virtual Bool_t OutputFile(const char *url, Bool_t force)
virtual Bool_t Merge(Bool_t=kTRUE)
virtual Bool_t AddFile(const char *url, Bool_t cpProgress=kTRUE)
TObject * FindObject(const char *name) const override
void Copy(TObject &named) const override
const char * GetName() const override
void Streamer(TBuffer &) override
void Clear(Option_t *option="") override
static TClass * Class()
TClass * IsA() const override
void SetBit(UInt_t f)
virtual const char * ClassName() const
virtual TClass * IsA() const
virtual void Info(const char *method, const char *msgfmt,...) const
Int_t CheckPlugin() const
Int_t LoadPlugin()
virtual void SetSeed(ULong_t seed=0)
Ssiz_t Length() const
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
const char * Data() const
Bool_t MaybeRegexp() const
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Bool_t IsNull() const
TString & Prepend(char c, Ssiz_t rep=1)
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)
const char * pwd()
virtual void AddIncludePath(const char *includePath)
virtual const char * DirName(const char *pathname)
virtual const char * Getenv(const char *env)
virtual char * ConcatFileName(const char *dir, const char *name)
virtual const char * FindFile(const char *search, TString &file, EAccessMode mode=kFileExists)
virtual int mkdir(const char *name, Bool_t recursive=kFALSE)
virtual TTime Now()
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
virtual int Rename(const char *from, const char *to)
virtual const char * BaseName(const char *pathname)
virtual Bool_t IsAbsoluteFileName(const char *dir)
virtual void AddDynamicPath(const char *pathname)
virtual char * ExpandPathName(const char *path)
virtual const char * WorkingDirectory()
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
virtual void Setenv(const char *name, const char *value)
virtual const char * HomeDirectory(const char *userName=nullptr)
virtual int Unlink(const char *name)
virtual const char * TempDirectory() const
long long Long64_t
RooCmdArg Label(const char *str)
RVec< PromoteType< T > > abs(const RVec< T > &v)
RVec< PromoteTypes< T0, T1 > > fdim(const T0 &x, const RVec< T1 > &v)
Double_t y[n]
Double_t x[n]
void Error(UserClass p, const char *location, const char *va_(fmt),...)
Definition: KVError.h:116
void Warning(UserClass p, const char *location, const char *va_(fmt),...)
Definition: KVError.h:125
void EnableThreadSafety()
void init()
Bool_t AreEqualAbs(Double_t af, Double_t bf, Double_t epsilon)
const char * cnt
v
TMarker m
ClassImp(TPyArg)