1 #include "AliOADBForward.h"
12 #ifndef ALIROOT_SVN_REVISION
13 # define ALIROOT_SVN_REVISION 0
17 ClassImp(AliOADBForward)
19 ; // Do not remove - for Emacs
22 //====================================================================
24 AliOADBForward::Mode2String(ERunSelectMode mode)
27 case kDefault: return "default";
28 case kExact: return "exact";
29 case kNewest: return "newest";
30 case kNear: return "near";
31 case kOlder: return "older";
32 case kNewer: return "newer";
34 return "?"; // Should never get here
36 AliOADBForward::ERunSelectMode
37 AliOADBForward::String2Mode(const TString& str)
39 if (str.EqualTo("default", TString::kIgnoreCase)) return kDefault;
40 else if (str.EqualTo("exact", TString::kIgnoreCase)) return kExact;
41 else if (str.EqualTo("newest", TString::kIgnoreCase)) return kNewest;
42 else if (str.EqualTo("near", TString::kIgnoreCase)) return kNear;
43 else if (str.EqualTo("older", TString::kIgnoreCase)) return kOlder;
44 else if (str.EqualTo("newer", TString::kIgnoreCase)) return kNewer;
47 AliOADBForward::ERunSelectMode
48 AliOADBForward::Int2Mode(Int_t mode)
51 case kDefault: return kDefault;
52 case kExact: return kExact;
53 case kNewest: return kNewest;
54 case kNear: return kNear;
55 case kOlder: return kOlder;
56 case kNewer: return kNewer;
58 return kDefault; // Should never get here
62 //====================================================================
63 AliOADBForward::Entry::Entry(ULong_t runNo,
86 //____________________________________________________________________
87 AliOADBForward::Entry::Entry(const Entry& o)
94 fSatellite(o.fSatellite),
104 //____________________________________________________________________
105 AliOADBForward::Entry&
106 AliOADBForward::Entry::operator=(const Entry& o)
109 // Assignment operator
111 if (this == &o) return *this;
117 fSatellite = o.fSatellite;
119 fTimestamp = o.fTimestamp;
120 fAliROOTRevision = o.fAliROOTRevision;
125 //____________________________________________________________________
127 AliOADBForward::Entry::GetTitle() const
129 TDatime d(fTimestamp);
130 return Form("%09ld, %4s, %4huGeV, %+4hd, %4s, %3s, %19s: %p (%s) by %s",
131 (fRunNo == 0xFFFFFFFF ? -1 : fRunNo),
134 fSys == 3 ? "pPb" : "?"),
135 fSNN, fField, (fMC ? "mc" : "real"),
136 (fSatellite ? "sat" : "nom"), d.AsSQLString(), fData,
137 (fData ? fData->GetName() : "?"), fAuthor.Data());
140 //____________________________________________________________________
142 AliOADBForward::Entry::Print(Option_t* /*option*/) const
144 Printf("%s", GetTitle());
146 //====================================================================
147 AliOADBForward::Table::Table(TTree* tree, Bool_t isNew, ERunSelectMode mode)
148 : fTree(tree), fEntry(0), fVerbose(false), fMode(mode), fFallBack(false)
153 Info("Table", "Making table %s (%s) with mode %s (%s)",
154 tree->GetName(), (isNew ? "new" : "old"), tree->GetTitle(),
158 fTree->Branch("e", "AliOADBForward::Entry", &fEntry);
159 fMode = String2Mode(fTree->GetTitle());
162 if (fMode <= kDefault || fMode > kNewer) {
163 fMode = String2Mode(fTree->GetTitle());
164 if (fMode == kDefault) fMode = kNear;
166 fTree->SetBranchAddress("e", &fEntry);
169 Info("", "Mode set to %d (%s)", fMode, Mode2String(fMode));
172 //____________________________________________________________________
173 AliOADBForward::Table::Table(const Table& o)
177 fVerbose(o.fVerbose),
179 fFallBack(o.fFallBack)
184 fTree->SetBranchAddress("e", &fEntry);
187 //____________________________________________________________________
188 AliOADBForward::Table::~Table()
195 //____________________________________________________________________
196 AliOADBForward::Table&
197 AliOADBForward::Table::operator=(const Table& o)
200 // Assignment operator
202 if (this == &o) return *this;
205 fVerbose = o.fVerbose;
207 if (fTree) fTree->SetBranchAddress("e", &fEntry);
212 //____________________________________________________________________
214 AliOADBForward::Table::GetTableName() const
217 // Get the table name or null
218 if (!fTree) return 0;
219 return fTree->GetName();
221 //____________________________________________________________________
223 AliOADBForward::Table::GetName() const
226 // Overload of TObject::GetName
228 if (!fTree) return TObject::GetName();
229 return GetTableName();
231 //____________________________________________________________________
233 AliOADBForward::Table::Update()
239 Error("Update", "No tree associated");
243 TFile* file = fTree->GetCurrentFile();
245 Error("Update", "No file associated with tree");
248 if (!file->IsWritable()) {
249 Error("Update", "File %s not writeable", file->GetName());
253 Int_t nBytes = file->Write();
255 return (nBytes >= 0);
257 //____________________________________________________________________
259 AliOADBForward::Table::Close()
262 // Close the connection
265 Error("Close", "No tree associated");
269 // if (fTree) delete fTree;
270 // if (fEntry) delete fEntry;
275 //____________________________________________________________________
277 AliOADBForward::Table::Query(ULong_t runNo,
288 return Query(runNo, mode, Conditions(sys, sNN, fld, mc, sat));
291 //____________________________________________________________________
293 AliOADBForward::Table::Query(ULong_t runNo,
295 const TString& q) const
298 // Run a query against the table
303 Error("Close", "No tree associated");
308 const char* smode = "latest";
310 if (mode <= kDefault || mode > kNewer) mode = fMode;
311 smode = Mode2String(mode);
314 AppendToQuery(query, Form("fRunNo == %lu", runNo));
319 AppendToQuery(query, Form("abs(fRunNo-%lu)<=%d",
320 runNo,kMaxNearDistance));
323 AppendToQuery(query, Form("fRunNo <= %lu", runNo));
326 AppendToQuery(query, Form("fRunNo >= %lu", runNo));
329 Fatal("Query", "Mode should never be 'default'");
334 if (query.IsNull()) {
335 Warning("Query", "Empty query!");
340 Printf("%s: Query is '%s'", GetName(), query.Data());
341 fTree->Draw("Entry$:fRunNo:fTimestamp", query, "goff");
342 Int_t nRows = fTree->GetSelectedRows();
343 if (nRows <= 0) return -1;
346 Printf("Query: %s (%s)\n"
347 " Entry | Run | Timestamp \n"
348 "--------+-----------+------------------------",
349 query.Data(), smode);
351 ULong_t oldRun = (mode == kNewer ? 0xFFFFFFFF : 0);
353 ULong_t oldDist = 0xFFFFFFFF;
355 for (Int_t row = 0; row < nRows; row++) {
356 Int_t ent = Int_t(fTree->GetV1()[row]);
357 ULong_t run = ULong_t(fTree->GetV2()[row]);
358 ULong_t tim = ULong_t(fTree->GetV3()[row]);
359 ULong_t dist = (run > runNo ? run - runNo : runNo - run);
363 Printf(" %6d | %9ld | %19s ", ent, run > 0x7FFFFFFF ? -1 : run,
368 case kExact: break; // Done in the draw `query'
369 case kNewest: // Fall-through
371 if (run < oldRun) continue;
374 if (run > oldRun) continue;
377 if (runNo > 0 && dist > oldDist) continue;
382 // If we get here, then we have the best run according to the
385 // Finally, check the timestamp
386 if (tim < oldTim) continue;
388 // Now update last values and set current best entry
396 Printf("Returning entry # %d", entry);
401 //____________________________________________________________________
403 AliOADBForward::Table::Insert(TObject* o,
411 const TString& author)
414 // Insert a new row in the table
417 // Check if the file is read/write
419 Info("Insert", "Inserting object %p for run=%lu, sys=%hu, sNN=%4hu, "
420 "field=%+2hd, mc=%d, sat=%d", o,runNo, sys, sNN, field, mc, sat);
423 Warning("Insert", "No tree, or not write-able");
427 // If the entry doesn't exists
428 if (!fEntry) fEntry = new Entry;
431 TString auth(author);
433 UserGroup_t* u = gSystem->GetUserInfo();
434 TInetAddress i = gSystem->GetHostByName(gSystem->HostName());
435 auth = TString::Format("%s <%s@%s>", u->fRealName.Data(),
436 u->fUser.Data(), i.GetHostName());
441 fEntry->fRunNo = runNo; // (runNo <= 0 ? 0xFFFFFFFF : runNo);
444 fEntry->fField = field;
446 fEntry->fSatellite = sat;
447 fEntry->fAliROOTRevision = (aliRev != 0 ? aliRev : ALIROOT_SVN_REVISION);
448 fEntry->fAuthor = auth;
451 fEntry->fTimestamp = now.Convert(true);
454 Int_t nBytes = fTree->Fill();
456 Warning("Insert", "Failed to insert new entry");
460 // do an Auto-save and flush-baskets now
461 fTree->AutoSave("FlushBaskets SaveSelf");
466 //____________________________________________________________________
468 AliOADBForward::Table::GetEntry(ULong_t run,
476 // Query the tree for an object. The strategy is as follows.
478 // - First query with all fields
479 // - If this returns a single entry, return that.
480 // - If not, then ignore the run number (if given)
481 // - If this returns a single entry, return that
482 // - If not, and fall-back is enabled, then
483 // - Ignore the collision energy (if given)
484 // - If this returns a single entry, return that.
485 // - If not, ignore all passed values
486 // - If this returns a single entry, return that.
487 // - Otherwise, give up and return -1
488 // - Otherwise, give up and return -1
490 // This allow us to specify default objects for a period, and for
491 // collision system, energy, and field setting.
495 Printf("run=%lu mode=%s sys=%hu sNN=%hu fld=%hd mc=%d sat=%d (fall=%d)",
496 run, Mode2String(mode), sys, sNN, fld, mc, sat, fFallBack);
497 Int_t entry = Query(run, mode, sys, sNN, fld, mc, sat);
498 if (entry < 0 && run > 0)
499 entry = Query(0, mode, sys, sNN, fld, mc, sat);
500 if (entry < 0 && fFallBack && fld != kInvalidField) {
502 Printf("Fall-back enabled, trying without field=%d", fld);
503 entry = Query(run, mode, sys, sNN, fld, mc, sat);
505 if (entry < 0 && fFallBack && sNN > 0) {
507 Printf("Fall-back enabled, will try without sNN=%d", sNN);
508 entry = Query(run, mode, sys, 0, fld, mc, sat);
510 if (entry < 0 && fFallBack) {
512 Printf("Fall-back enabled, will try without any fields");
513 entry = Query(0, mode, 0, 0, kInvalidField, false, false);
516 Warning("Get", "No valid object could be found");
522 //____________________________________________________________________
523 AliOADBForward::Entry*
524 AliOADBForward::Table::Get(ULong_t run,
532 // Query the tree for an object. The strategy is as follows.
534 // - First query with all fields
535 // - If this returns a single entry, return that.
536 // - If not, then ignore the run number (if given)
537 // - If this returns a single entry, return that
538 // - If not, and fall-back is enabled, then
539 // - Ignore the collision energy (if given)
540 // - If this returns a single entry, return that.
541 // - If not, ignore all passed values
542 // - If this returns a single entry, return that.
543 // - Otherwise, give up and return null
544 // - Otherwise, give up and return null
546 // This allow us to specify default objects for a period, and for
547 // collision system, energy, and field setting.
549 Int_t entry = GetEntry(run, mode, sys, sNN, fld, mc, sat);
550 if (entry < 0) return 0;
552 Int_t nBytes = fTree->GetEntry(entry);
554 Warning("Get", "Failed to get entry # %d\n", entry);
557 if (fVerbose) fEntry->Print();
560 //____________________________________________________________________
562 AliOADBForward::Table::GetData(ULong_t run,
571 // Get data associated with a row or null.
572 // See also AliOADBForward::Get
574 Entry* e = Get(run, mode, sys, sNN, fld, mc, sat);
578 //____________________________________________________________________
580 AliOADBForward::Table::Print(Option_t* option) const
583 // Print the full table
585 if (!IsOpen()) return;
587 Printf("Table %s (default mode: %s)", GetName(), Mode2String(fMode));
588 Int_t n = fTree->GetEntries();
589 for (Int_t i = 0; i < n; i++) {
591 printf("%4d/%4d: ", i, n);
592 fEntry->Print(option);
595 //____________________________________________________________________
597 AliOADBForward::Table::Browse(TBrowser* b)
600 if (fTree) b->Add(fTree);
602 //____________________________________________________________________
604 AliOADBForward::Table::IsOpen(Bool_t rw) const
606 if (!fTree) return false;
607 if (!rw) return true;
609 return fTree->GetCurrentFile()->IsWritable();
611 //====================================================================
612 AliOADBForward::AliOADBForward()
621 //____________________________________________________________________
622 AliOADBForward::AliOADBForward(const AliOADBForward& other)
624 fTables(other.fTables)
631 //____________________________________________________________________
632 AliOADBForward::~AliOADBForward()
640 //____________________________________________________________________
642 AliOADBForward::operator=(const AliOADBForward& other)
647 if (&other == this) return *this;
649 fTables = other.fTables;
655 //____________________________________________________________________
657 AliOADBForward::Open(const TString& fileName,
658 const TString& tables,
663 TString absPath(gSystem->ExpandPathName(fileName));
664 if (absPath.IsNull()) {
665 Error("Open", "Empty path for tables %s", tables.Data());
668 TObject* previous = gROOT->GetListOfFiles()->FindObject(absPath);
671 file = static_cast<TFile*>(previous);
674 file = TFile::Open(fileName, (rw ? "UPDATE" : "READ"));
677 Error("Open", "Failed to open %s", GetName());
680 return Open(file, tables, rw, verb, fallback);
683 //____________________________________________________________________
685 AliOADBForward::Open(TFile* file,
686 const TString& tables,
692 // Open database file and find or create listed tables
694 if (!file) return false;
695 if (rw && !file->IsWritable()) {
696 Warning("Open", "Read+write access requested, but %s opened read-only",
698 if (file->ReOpen("UPDATE") < 0) {
699 Error("Open", "Failed to reopen file in read+write access mode");
704 if (tables.EqualTo("*")) {
706 Error("Open", "Cannot open with '*' in read/write mode");
709 TList* l = file->GetListOfKeys();
712 while ((key = static_cast<TKey*>(next()))) {
713 TClass* cl = gROOT->GetClass(key->GetClassName());
715 if (!cl->InheritsFrom(TTree::Class())) continue;
717 OpenTable(file, rw, key->GetName(), "DEFAULT", verb, fallback);
722 TObjArray* tokens = tables.Tokenize(":,");
723 TObjString* token = 0;
724 TIter nextToken(tokens);
725 while ((token = static_cast<TObjString*>(nextToken()))) {
726 TString& tn = token->String();
727 if (tn.IsNull()) continue;
729 TObjArray* parts = tn.Tokenize("/");
730 TObjString* onam = static_cast<TObjString*>(parts->At(0));
731 TString& name = onam->String();
732 TString mode = "DEFAULT";
733 if (parts->GetEntries() > 1)
734 mode = static_cast<TObjString*>(parts->At(1))->String();
737 OpenTable(file, rw, name, mode, verb, fallback);
746 //____________________________________________________________________
748 AliOADBForward::Close()
751 // Flush all tables and close all files
754 Int_t nFiles = GetFiles(files);
760 TIter nextFile(&files);
762 while ((file = static_cast<TFile*>(nextFile()))) {
763 // if (file->IsWritable()) file->Write();
772 //____________________________________________________________________
774 AliOADBForward::Update()
780 Int_t nFiles = GetFiles(files);
786 TIter nextFile(&files);
789 while ((file = static_cast<TFile*>(nextFile()))) {
790 if (!file->IsWritable()) {
791 Error("Update", "File %s not writeable", file->GetName());
795 nBytes += file->Write();
797 return (nBytes >= 0);
799 //____________________________________________________________________
800 AliOADBForward::Entry*
801 AliOADBForward::Get(const TString& table,
811 // Get a row from selected table
813 Table* t = FindTable(table);
816 return t->Get(run, mode, sys, sNN, fld, mc, sat);
818 //____________________________________________________________________
820 AliOADBForward::GetData(const TString& table,
829 Table* t = FindTable(table);
832 return t->GetData(run, mode, sys, sNN, fld, mc, sat);
834 //____________________________________________________________________
836 AliOADBForward::Insert(const TString& table,
845 const TString& author)
848 // Insert a row into the selected table
850 Table* t = FindTable(table);
851 if (!t) return false;
853 return t->Insert(o, runNo, sys, sNN, field, mc, sat, aliRev, author);
855 //____________________________________________________________________
857 AliOADBForward::CopyEntry(const TString& table,
869 Table* t = FindTable(table);
870 if (!t) return false;
872 Entry* e = t->Get(oldRunNo, t->fMode, oldSys, oldSNN, oldField, mc, sat);
873 if (!e) return false;
875 return t->Insert(e->fData, newRunNo, newSys, newSNN, newField, mc, sat,
876 e->fAliROOTRevision, e->fAuthor);
879 //____________________________________________________________________
881 AliOADBForward::Print(const Option_t* option) const
886 TIter nextTable(&fTables);
889 while ((key = static_cast<TObjString*>(nextTable()))) {
890 Printf("Table: %p", key->GetName());
891 table = static_cast<Table*>(fTables.GetValue(key));
892 if (!table) continue;
893 table->Print(option);
897 //____________________________________________________________________
899 AliOADBForward::Browse(TBrowser* b)
902 // Browse this object
904 TIter nextTable(&fTables);
907 while ((key = static_cast<TObjString*>(nextTable()))) {
908 table = static_cast<Table*>(fTables.GetValue(key));
909 if (!table) continue;
910 b->Add(table, key->GetName());
913 //____________________________________________________________________
914 AliOADBForward::Table*
915 AliOADBForward::FindTable(const TString& name, Bool_t quite) const
918 // Find a table by name
920 TPair* p = static_cast<TPair*>(fTables.FindObject(name));
923 Warning("FindTable", "Table %s not registered", name.Data());
926 return static_cast<Table*>(p->Value());
928 //____________________________________________________________________
930 AliOADBForward::GetFiles(TList& files) const
933 // Get all associated files
936 TIter nextTable(&fTables);
939 while ((key = static_cast<TObjString*>(nextTable()))) {
940 table = static_cast<Table*>(fTables.GetValue(key));
941 if (!table->fTree) continue;
943 TFile* f = table->fTree->GetCurrentFile();
946 if (files.FindObject(f)) continue;
952 //____________________________________________________________________
953 AliOADBForward::Table*
954 AliOADBForward::GetTableFromFile(TFile* file,
957 const TString& mode) const
960 // Get a table from a file, or make a new table
963 if (FindTable(name, true)) return 0;
965 TObject* o = file->Get(name);
970 // We only fail if in read-only mode
971 Error("Open", "No such object: %s in %s", name.Data(),
975 // Create the tree in the file
976 t = new TTree(name, mode);
977 t->SetDirectory(file);
981 // Get the tree, and set the branch
982 t = static_cast<TTree*>(o);
984 Table* ret = new Table(t, n, String2Mode(mode));
988 //____________________________________________________________________
990 AliOADBForward::OpenTable(TFile* file,
999 Table* t = GetTableFromFile(file, rw, name, mode);
1002 fTables.Add(new TObjString(name), t);
1003 t->SetVerbose(verb);
1004 t->SetEnableFallBack(fallback);
1006 Printf("Found table %s. Opened with verbose=%d, fallback=%d",
1007 name.Data(), verb, fallback);
1010 //____________________________________________________________________
1012 AliOADBForward::AppendToQuery(TString& q, const TString& s, Bool_t andNotOr)
1017 if (!q.IsNull()) q.Append(andNotOr ? " && " : " || ");
1020 //____________________________________________________________________
1022 AliOADBForward::Conditions(UShort_t sys,
1028 // Build query string
1030 if (sys > 0) AppendToQuery(q, Form("fSys == %hu", sys));
1031 if (sNN > 0) AppendToQuery(q, Form("abs(fSNN - %hu) < 11", sNN));
1032 if (TMath::Abs(fld) < 10) AppendToQuery(q, Form("fField == %hd",fld));
1033 // Boolean fields always queried. In cases where these do not matter,
1034 // we always write down the false value, so we get the correct query
1036 AppendToQuery(q, Form("%sfMC", (mc ? " " : "!")));
1037 AppendToQuery(q, Form("%sfSatellite", (sat ? " " : "!")));
1042 //____________________________________________________________________
1044 AliOADBForward::TestGet(AliOADBForward& t,
1045 const TString& table,
1047 ERunSelectMode mode,
1055 Printf("=== Test query: t=%s r=%ld s=%d t=%d f=%d m=%d v=%d",
1056 table.Data(), runNo, sys, sNN, fld, int(mc), int(sat));
1057 AliOADBForward::Entry* e = t.Get(table, runNo, mode, sys, sNN,
1062 //____________________________________________________________________
1064 AliOADBForward::TestInsert(AliOADBForward& t,
1065 const TString& table,
1073 static Int_t cnt = 0;
1074 TString what = TString::Format("%s-%03d", table.Data(), cnt++);
1075 Printf("=== Insert: t=%s r=%ld s=%d t=%d f=%d m=%d v=%d w=%s",
1076 table.Data(), runNo, sys, sNN, fld, int(mc), int(sat), what.Data());
1077 t.Insert(table, new TObjString(what), runNo, sys, sNN, fld, mc, sat);
1078 gSystem->Sleep(500);
1081 //____________________________________________________________________
1083 AliOADBForward::Test()
1085 AliOADBForward* tt = new AliOADBForward();
1086 if (!tt->Open("db.root", "A,B", true, true)) {
1087 ::Error("Test", "Failed to open DB");
1090 AliOADBForward& t = *tt;
1091 TestInsert(t, "A", 137161);
1092 TestInsert(t, "A", 137161);
1093 TestInsert(t, "A", 0 );
1094 TestInsert(t, "A", 999999);
1095 TestInsert(t, "A", 137166);
1098 TestInsert(t, "B", 137161);
1099 TestInsert(t, "B", 0 );
1103 if (!t.Open("db.root", "A,B",false,true)) {
1104 ::Error("Test", "Failed to open DB");
1108 TestGet(t, "A", 137161);
1109 TestGet(t, "A", 137160);
1110 TestGet(t, "A", 0 );
1111 TestGet(t, "A", 137160, kNewest);
1112 TestGet(t, "A", 137160, kNewer);
1113 TestGet(t, "A", 137168, kOlder);
1114 TestGet(t, "A", 137161, kExact);
1116 new TBrowser("b", tt);