]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWGLF/FORWARD/analysis2/AliOADBForward.cxx
Now use gSystem->Exec("gbbox ps -Ax > tmpfile") to work
[u/mrichter/AliRoot.git] / PWGLF / FORWARD / analysis2 / AliOADBForward.cxx
CommitLineData
8449e3e0 1#include "AliOADBForward.h"
2#include <TBrowser.h>
3#include <TROOT.h>
4#include <TKey.h>
5#include <TList.h>
6#include <TDatime.h>
7#include <TTree.h>
8#include <TFile.h>
9#include <TError.h>
10#include <TSystem.h>
11
12#ifndef ALIROOT_SVN_REVISION
13# define ALIROOT_SVN_REVISION 0
14#endif
15
16
17ClassImp(AliOADBForward)
18#if 0
19; // Do not remove - for Emacs
20#endif
21
22//====================================================================
23const char*
24AliOADBForward::Mode2String(ERunSelectMode mode)
25{
26 switch (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";
33 }
34 return "?"; // Should never get here
35}
36AliOADBForward::ERunSelectMode
37AliOADBForward::String2Mode(const TString& str)
38{
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;
45 return kDefault;
46}
47AliOADBForward::ERunSelectMode
48AliOADBForward::Int2Mode(Int_t mode)
49{
50 switch (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;
57 }
58 return kDefault; // Should never get here
59}
60
61
62//====================================================================
63AliOADBForward::Entry::Entry(ULong_t runNo,
64 UShort_t sys,
65 UShort_t sNN,
66 Short_t field,
67 Bool_t mc,
68 Bool_t sat,
69 TObject* o)
70 : fRunNo(runNo),
71 fSys(sys),
72 fSNN(sNN),
73 fField(field),
74 fMC(mc),
75 fSatellite(sat),
76 fData(o),
77 fTimestamp(0),
78 fAliROOTRevision(0),
79 fAuthor("unknown")
80{
81 //
82 // Constructor
83 //
84}
85
86//____________________________________________________________________
87AliOADBForward::Entry::Entry(const Entry& o)
88 : TObject(o),
89 fRunNo(o.fRunNo),
90 fSys(o.fSys),
91 fSNN(o.fSNN),
92 fField(o.fField),
93 fMC(o.fMC),
94 fSatellite(o.fSatellite),
95 fData(o.fData),
96 fTimestamp(0),
97 fAliROOTRevision(0),
98 fAuthor(o.fAuthor)
99{
100 //
101 // Copy constructor
102 //
103}
104//____________________________________________________________________
105AliOADBForward::Entry&
106AliOADBForward::Entry::operator=(const Entry& o)
107{
108 //
109 // Assignment operator
110 //
111 if (this == &o) return *this;
112 fRunNo = o.fRunNo;
113 fSys = o.fSys;
114 fSNN = o.fSNN;
115 fField = o.fField;
116 fMC = o.fMC;
117 fSatellite = o.fSatellite;
118 fData = o.fData;
119 fTimestamp = o.fTimestamp;
120 fAliROOTRevision = o.fAliROOTRevision;
121 fAuthor = o.fAuthor;
122
123 return *this;
124}
125//____________________________________________________________________
126const char*
127AliOADBForward::Entry::GetTitle() const
128{
129 TDatime d(fTimestamp);
130 return Form("%09ld, %4s, %4huGeV, %+2hd, %4s, %3s, %19s: %p (%s) by %s",
131 (fRunNo == 0xFFFFFFFF ? -1 : fRunNo),
132 (fSys == 1 ? "pp" : fSys == 2 ? "PbPb" : fSys == 3 ? "pPb" :"?"),
133 fSNN, fField, (fMC ? "mc" : "real"),
134 (fSatellite ? "sat" : "nom"), d.AsSQLString(), fData,
135 (fData ? fData->GetName() : "?"), fAuthor.Data());
136
137}
138//____________________________________________________________________
139void
140AliOADBForward::Entry::Print(Option_t* /*option*/) const
141{
142 Printf(GetTitle());
143}
144//====================================================================
145AliOADBForward::Table::Table(TTree* tree, Bool_t isNew, ERunSelectMode mode)
146 : fTree(tree), fEntry(0), fVerbose(false), fMode(mode)
147{
148 if (!tree) return;
149
150 if (isNew) {
151 fTree->Branch("e", "AliOADBForward::Entry", &fEntry);
152 fMode = String2Mode(fTree->GetTitle());
153 }
154 else {
155 if (fMode <= kDefault || fMode > kNewer) {
156 fMode = String2Mode(fTree->GetTitle());
157 if (fMode == kDefault) fMode = kNear;
158 }
159 fTree->SetBranchAddress("e", &fEntry);
160 }
161}
162//____________________________________________________________________
163AliOADBForward::Table::Table(const Table& o)
164 : TObject(o),
165 fTree(o.fTree),
166 fEntry(o.fEntry),
167 fVerbose(o.fVerbose),
168 fMode(o.fMode)
169{
170 //
171 // Copy constructor
172 if (!fTree) return;
173 fTree->SetBranchAddress("e", &fEntry);
174}
175
176//____________________________________________________________________
177AliOADBForward::Table::~Table()
178{
179 //
180 // Close this table
181 //
182 Close();
183}
184//____________________________________________________________________
185AliOADBForward::Table&
186AliOADBForward::Table::operator=(const Table& o)
187{
188 //
189 // Assignment operator
190 //
191 if (this == &o) return *this;
192 fTree = o.fTree;
193 fEntry = o.fEntry;
194 fVerbose = o.fVerbose;
195 fMode = o.fMode;
196 if (fTree) fTree->SetBranchAddress("e", &fEntry);
197
198 return *this;
199}
200
201//____________________________________________________________________
202const Char_t*
203AliOADBForward::Table::GetTableName() const
204{
205 //
206 // Get the table name or null
207 if (!fTree) return 0;
208 return fTree->GetName();
209}
210//____________________________________________________________________
211const Char_t*
212AliOADBForward::Table::GetName() const
213{
214 //
215 // Overload of TObject::GetName
216 //
217 if (!fTree) return TObject::GetName();
218 return GetTableName();
219}
220//____________________________________________________________________
221Bool_t
222AliOADBForward::Table::Update()
223{
224 //
225 // Flush to disk
226 //
227 if (!IsOpen()) {
228 Error("Update", "No tree associated");
229 return false;
230 }
231
232 TFile* file = fTree->GetCurrentFile();
233 if (!file) {
234 Error("Update", "No file associated with tree");
235 return false;
236 }
237 if (!file->IsWritable()) {
238 Error("Update", "File %s not writeable", file->GetName());
239 return false;
240 }
241
242 Int_t nBytes = file->Write();
243
244 return (nBytes >= 0);
245}
246//____________________________________________________________________
247Bool_t
248AliOADBForward::Table::Close()
249{
250 //
251 // Close the connection
252 //
253 if (!IsOpen()) {
254 Error("Close", "No tree associated");
255 return false;
256 }
257
258 // if (fTree) delete fTree;
259 // if (fEntry) delete fEntry;
260 fTree = 0;
261 fEntry = 0;
262 return true;
263}
264//____________________________________________________________________
265Int_t
266AliOADBForward::Table::Query(ULong_t runNo,
267 ERunSelectMode mode,
268 UShort_t sys,
269 UShort_t sNN,
270 Short_t fld,
271 Bool_t mc,
272 Bool_t sat) const
273{
274 //
275 // Query the tree
276 //
277 return Query(runNo, mode, Conditions(sys, sNN, fld, mc, sat));
278}
279
280//____________________________________________________________________
281Int_t
282AliOADBForward::Table::Query(ULong_t runNo,
283 ERunSelectMode mode,
284 const TString& q) const
285{
286 //
287 // Run a query against the table
288 //
289
290 // Check the tree
291 if (!IsOpen()) {
292 Error("Close", "No tree associated");
293 return -1;
294 }
295
296 TString query = q;
297 const char* smode = "latest";
298 if (runNo > 0) {
299 if (mode <= kDefault || mode > kNewer) mode = fMode;
300 smode = Mode2String(mode);
301 switch (mode) {
302 case kExact:
303 AppendToQuery(query, Form("fRunNo == %lu", runNo));
304 break;
305 case kNewest:
306 break;
307 case kNear:
308 AppendToQuery(query, Form("abs(fRunNo-%lu)<=%d",
309 runNo,kMaxNearDistance));
310 break;
311 case kOlder:
312 AppendToQuery(query, Form("fRunNo <= %lu", runNo));
313 break;
314 case kNewer:
315 AppendToQuery(query, Form("fRunNo >= %lu", runNo));
316 break;
317 case kDefault:
318 Fatal("Query", "Mode should never be 'default'");
319 break;
320 }
321 }
322
323 if (query.IsNull()) {
324 Warning("Query", "Empty query!");
325 return -1;
326 }
327
328 if (fVerbose)
329 Printf("%s: Query is '%s'", GetName(), query.Data());
330 fTree->Draw("Entry$:fRunNo:fTimestamp", query, "goff");
331 Int_t nRows = fTree->GetSelectedRows();
332 if (nRows <= 0) return -1;
333
334 if (fVerbose)
335 Printf("Query: %s (%s)\n"
336 " Entry | Run | Timestamp \n"
337 "--------+-----------+------------------------",
338 query.Data(), smode);
339
340 ULong_t oldRun = (mode == kNewer ? 0xFFFFFFFF : 0);
341 ULong_t oldTim = 0;
342 ULong_t oldDist = 0xFFFFFFFF;
343 Int_t entry = -1;
344 for (Int_t row = 0; row < nRows; row++) {
345 Int_t ent = fTree->GetV1()[row];
346 ULong_t run = fTree->GetV2()[row];
347 ULong_t tim = fTree->GetV3()[row];
348 ULong_t dist = (run > runNo ? run - runNo : runNo - run);
349
350 if (fVerbose) {
351 TDatime t(tim);
352 Printf(" %6d | %9ld | %19s ", ent, run > 0x7FFFFFFF ? -1 : run,
353 t.AsSQLString());
354 }
355
356 switch (mode) {
357 case kExact: break; // Done in the draw `query'
358 case kNewest: // Fall-through
359 case kOlder:
360 if (run < oldRun) continue;
361 break;
362 case kNewer:
363 if (run > oldRun) continue;
364 break;
365 case kNear:
366 if (runNo > 0 && dist > oldDist) continue;
367 break;
368 case kDefault:
369 break;
370 }
371 // If we get here, then we have the best run according to the
372 // criteria
373
374 // Finally, check the timestamp
375 if (tim < oldTim) continue;
376
377 // Now update last values and set current best entry
378 oldTim = tim;
379 oldDist = dist;
380 oldRun = run;
381 entry = ent;
382 }
383
384 if (fVerbose) {
385 Printf("Returning entry # %d", entry);
386 }
387 return entry;
388}
389
390//____________________________________________________________________
391Bool_t
392AliOADBForward::Table::Insert(TObject* o,
393 ULong_t runNo,
394 UShort_t sys,
395 UShort_t sNN,
396 Short_t field,
397 Bool_t mc,
398 Bool_t sat,
399 ULong_t aliRev,
400 const TString& author)
401{
402 //
403 // Insert a new row in the table
404 //
405
406 // Check if the file is read/write
407 if (fVerbose)
408 Info("Insert", "Inserting object %p for run=%lu, sys=%hu, sNN=%4hu, "
409 "field=%+2hd, mc=%d, sat=%d", o,runNo, sys, sNN, field, mc, sat);
410
411 if (!IsOpen(true)) {
412 Warning("Insert", "No tree, or not write-able");
413 return false;
414 }
415
416 // If the entry doesn't exists
417 if (!fEntry) fEntry = new Entry;
418
419 // Make author
420 TString auth(author);
421 if (auth.IsNull()) {
422 UserGroup_t* u = gSystem->GetUserInfo();
423 TInetAddress i = gSystem->GetHostByName(gSystem->HostName());
424 auth = TString::Format("%s <%s@%s>", u->fRealName.Data(),
425 u->fUser.Data(), i.GetHostName());
426 }
427
428 // Set fields
429 fEntry->fData = o;
430 fEntry->fRunNo = runNo; // (runNo <= 0 ? 0xFFFFFFFF : runNo);
431 fEntry->fSys = sys;
432 fEntry->fSNN = sNN;
433 fEntry->fField = field;
434 fEntry->fMC = mc;
435 fEntry->fSatellite = sat;
436 fEntry->fAliROOTRevision = (aliRev != 0 ? aliRev : ALIROOT_SVN_REVISION);
437 fEntry->fAuthor = auth;
438
439 TDatime now;
440 fEntry->fTimestamp = now.Convert(true);
441
442 // Fill into tree
443 Int_t nBytes = fTree->Fill();
444 if (nBytes <= 0) {
445 Warning("Insert", "Failed to insert new entry");
446 return false;
447 }
448
449 // do an Auto-save and flush-baskets now
450 fTree->AutoSave("FlushBaskets SaveSelf");
451
452 return true;
453}
454
455//____________________________________________________________________
456AliOADBForward::Entry*
457AliOADBForward::Table::Get(ULong_t run,
458 ERunSelectMode mode,
459 UShort_t sys,
460 UShort_t sNN,
461 Short_t fld,
462 Bool_t mc,
463 Bool_t sat) const
464{
465 // Query the tree for an object. The strategy is as follows.
466 //
467 // - First query with all fields
468 // - If this returns a single entry, return that.
469 // - If not, then ignore the run number (if given)
470 // - If this returns a single entry, return that
471 // - Otherwise, give up and return null
472 //
473 // This allow us to specify default objects for a period, and for
474 // collision system, energy, and field setting.
475 //
476 if (fVerbose)
477 Printf("run=%lu mode=%s sys=%hu sNN=%hu fld=%hd mc=%d sat=%d",
478 run, Mode2String(mode), sys, sNN, fld, mc, sat);
479 Int_t entry = Query(run, mode, sys, sNN, fld, mc, sat);
480 if (entry < 0 && run > 0)
481 entry = Query(0, mode, sys, sNN, fld, mc, sat);
482 if (entry < 0) {
483 Warning("Get", "No valid object could be found");
484 return 0;
485 }
486
487 Int_t nBytes = fTree->GetEntry(entry);
488 if (nBytes <= 0) {
489 Warning("Get", "Failed to get entry # %d\n", entry);
490 return 0;
491 }
492 if (fVerbose) fEntry->Print();
493 return fEntry;
494}
495//____________________________________________________________________
496TObject*
497AliOADBForward::Table::GetData(ULong_t run,
498 ERunSelectMode mode,
499 UShort_t sys,
500 UShort_t sNN,
501 Short_t fld,
502 Bool_t mc,
503 Bool_t sat) const
504{
505 //
506 // Get data associated with a row or null.
507 // See also AliOADBForward::Get
508 //
509 Entry* e = Get(run, mode, sys, sNN, fld, mc, sat);
510 if (!e) return 0;
511 return e->fData;
512}
513//____________________________________________________________________
514void
515AliOADBForward::Table::Print(Option_t* option) const
516{
517 //
518 // Print the full table
519 //
520 if (!IsOpen()) return;
521
522 Printf("Table %s (default mode: %s)", GetName(), Mode2String(fMode));
523 Int_t n = fTree->GetEntries();
524 for (Int_t i = 0; i < n; i++) {
525 fTree->GetEntry(i);
526 printf("%4d/%4d: ", i, n);
527 fEntry->Print(option);
528 }
529}
530//____________________________________________________________________
531void
532AliOADBForward::Table::Browse(TBrowser* b)
533{
534 // Browse this table
535 if (fTree) b->Add(fTree);
536}
537//____________________________________________________________________
538Bool_t
539AliOADBForward::Table::IsOpen(Bool_t rw) const
540{
541 if (!fTree) return false;
542 if (!rw) return true;
543
544 return fTree->GetCurrentFile()->IsWritable();
545}
546//====================================================================
547AliOADBForward::AliOADBForward()
548 : TObject(),
549 fTables()
550{
551 //
552 // Constructor
553 //
554}
555#if 0
556//____________________________________________________________________
557AliOADBForward::AliOADBForward(const AliOADBForward& other)
558 : TObject(other),
559 fTables(other.fTables)
560{
561 //
562 // Copy constructor
563 //
564}
565#endif
566//____________________________________________________________________
567AliOADBForward::~AliOADBForward()
568{
569 //
570 // Destructor
571 //
572 Close();
573}
574#if 0
575//____________________________________________________________________
576AliOADBForward&
577AliOADBForward::operator=(const AliOADBForward& other)
578{
579 //
580 // Copy constructor
581 //
582 if (&other == this) return *this;
583
584 fTables = other.fTables;
585
586 return *this;
587}
588#endif
589
590//____________________________________________________________________
591Bool_t
592AliOADBForward::Open(const TString& fileName,
593 const TString& tables,
594 Bool_t rw,
595 Bool_t verb)
596{
597 TString absPath(gSystem->ExpandPathName(fileName));
598 if (absPath.IsNull()) {
599 Error("Open", "Empty path for tables %s", tables.Data());
600 return false;
601 }
602 TObject* previous = gROOT->GetListOfFiles()->FindObject(absPath);
603 TFile* file = 0;
604 if (previous) {
605 file = static_cast<TFile*>(previous);
606 }
607 else {
608 file = TFile::Open(fileName, (rw ? "UPDATE" : "READ"));
609 }
610 if (!file) {
611 Error("Open", "Failed to open %s", GetName());
612 return false;
613 }
614 return Open(file, tables, rw, verb);
615}
616
617//____________________________________________________________________
618Bool_t
619AliOADBForward::Open(TFile* file,
620 const TString& tables,
621 Bool_t rw,
622 Bool_t verb)
623{
624 //
625 // Open database file and find or create listed tables
626 //
627 if (!file) return false;
628 if (rw && !file->IsWritable()) {
629 Warning("Open", "Read+write access requested, but %s opened read-only",
630 file->GetName());
631 if (file->ReOpen("UPDATE") < 0) {
632 Error("Open", "Failed to reopen file in read+write access mode");
633 return false;
634 }
635 }
636
637 if (tables.EqualTo("*")) {
638 if (rw) {
639 Error("Open", "Cannot open with '*' in read/write mode");
640 return false;
641 }
642 TList* l = file->GetListOfKeys();
643 TIter next(l);
644 TKey* key = 0;
645 while ((key = static_cast<TKey*>(next()))) {
646 TClass* cl = gROOT->GetClass(key->GetClassName());
647 if (!cl) continue;
648 if (!cl->InheritsFrom(TTree::Class())) continue;
649
650 Table* t = GetTableFromFile(file, false, key->GetName(), "DEFAULT");
651 if (!t) continue;
652
653 fTables.Add(new TObjString(key->GetName()), t);
654 t->SetVerbose(verb);
655 }
656 // file->Close();
657 return true;
658 }
659 TObjArray* tokens = tables.Tokenize(":,");
660 TObjString* token = 0;
661 TIter nextToken(tokens);
662 while ((token = static_cast<TObjString*>(nextToken()))) {
663 TString& tn = token->String();
664 if (tn.IsNull()) continue;
665
666 TObjArray* parts = tn.Tokenize("/");
667 TObjString* onam = static_cast<TObjString*>(parts->At(0));
668 TString& name = onam->String();
669 TString mode = "DEFAULT";
670 if (parts->GetEntries() > 1)
671 mode = static_cast<TObjString*>(parts->At(1))->String();
672 mode.ToUpper();
673 Table* t = GetTableFromFile(file, rw, name, mode);
674 if (!t) continue;
675
676 t->SetVerbose(verb);
677 fTables.Add(onam->Clone(), t);
678
679 delete parts;
680 }
681 delete tokens;
682
683 return true;
684}
685
686//____________________________________________________________________
687Bool_t
688AliOADBForward::Close()
689{
690 //
691 // Flush all tables and close all files
692 //
693 TList files;
694 Int_t nFiles = GetFiles(files);
695 if (nFiles <= 0) {
696 // Nothing to close
697 return true;
698 }
699
700 TIter nextFile(&files);
701 TFile* file = 0;
702 while ((file = static_cast<TFile*>(nextFile()))) {
703 // if (file->IsWritable()) file->Write();
704
705 file->Close();
706 }
707
708 fTables.DeleteAll();
709
710 return true;
711}
712//____________________________________________________________________
713Bool_t
714AliOADBForward::Update()
715{
716 //
717 // Flush all tables
718 //
719 TList files;
720 Int_t nFiles = GetFiles(files);
721 if (nFiles <= 0) {
722 // Nothing to close
723 return true;
724 }
725
726 TIter nextFile(&files);
727 TFile* file = 0;
728 Int_t nBytes = 0;
729 while ((file = static_cast<TFile*>(nextFile()))) {
730 if (!file->IsWritable()) {
731 Error("Update", "File %s not writeable", file->GetName());
732 continue;
733 }
734
735 nBytes += file->Write();
736 }
737 return (nBytes >= 0);
738}
739//____________________________________________________________________
740AliOADBForward::Entry*
741AliOADBForward::Get(const TString& table,
742 ULong_t run,
743 ERunSelectMode mode,
744 UShort_t sys,
745 UShort_t sNN,
746 Short_t fld,
747 Bool_t mc,
748 Bool_t sat) const
749{
750 //
751 // Get a row from selected table
752 //
753 Table* t = FindTable(table);
754 if (!t) return 0;
755
756 return t->Get(run, mode, sys, sNN, fld, mc, sat);
757}
758//____________________________________________________________________
759TObject*
760AliOADBForward::GetData(const TString& table,
761 ULong_t run,
762 ERunSelectMode mode,
763 UShort_t sys,
764 UShort_t sNN,
765 Short_t fld,
766 Bool_t mc,
767 Bool_t sat) const
768{
769 Table* t = FindTable(table);
770 if (!t) return 0;
771
772 return t->GetData(run, mode, sys, sNN, fld, mc, sat);
773}
774//____________________________________________________________________
775Bool_t
776AliOADBForward::Insert(const TString& table,
777 TObject* o,
778 ULong_t runNo,
779 UShort_t sys,
780 UShort_t sNN,
781 Short_t field,
782 Bool_t mc,
783 Bool_t sat,
784 ULong_t aliRev,
785 const TString& author)
786{
787 //
788 // Insert a row into the selected table
789 //
790 Table* t = FindTable(table);
791 if (!t) return false;
792
793 return t->Insert(o, runNo, sys, sNN, field, mc, sat, aliRev, author);
794}
795//____________________________________________________________________
796void
797AliOADBForward::Print(const Option_t* option) const
798{
799 //
800 // Print everything
801 //
802 TIter nextTable(&fTables);
803 TObjString* key = 0;
804 Table* table = 0;
805 while ((key = static_cast<TObjString*>(nextTable()))) {
806 Printf("Table: %p", key->GetName());
807 table = static_cast<Table*>(fTables.GetValue(key));
808 if (!table) continue;
809 table->Print(option);
810 }
811}
812
813//____________________________________________________________________
814void
815AliOADBForward::Browse(TBrowser* b)
816{
817 //
818 // Browse this object
819 //
820 TIter nextTable(&fTables);
821 TObjString* key = 0;
822 Table* table = 0;
823 while ((key = static_cast<TObjString*>(nextTable()))) {
824 table = static_cast<Table*>(fTables.GetValue(key));
825 if (!table) continue;
826 b->Add(table, key->GetName());
827 }
828}
829//____________________________________________________________________
830AliOADBForward::Table*
831AliOADBForward::FindTable(const TString& name, Bool_t quite) const
832{
833 //
834 // Find a table by name
835 //
836 TPair* p = static_cast<TPair*>(fTables.FindObject(name));
837 if (!p) {
838 if (!quite)
839 Warning("FindTable", "Table %s not registered", name.Data());
840 return 0;
841 }
842 return static_cast<Table*>(p->Value());
843}
844//____________________________________________________________________
845Int_t
846AliOADBForward::GetFiles(TList& files) const
847{
848 //
849 // Get all associated files
850 //
851 Int_t ret = 0;
852 TIter nextTable(&fTables);
853 TObjString* key = 0;
854 Table* table = 0;
855 while ((key = static_cast<TObjString*>(nextTable()))) {
856 table = static_cast<Table*>(fTables.GetValue(key));
857 if (!table->fTree) continue;
858
859 TFile* f = table->fTree->GetCurrentFile();
860 if (!f) continue;
861
862 if (files.FindObject(f)) continue;
863 files.Add(f);
864 ret++;
865 }
866 return ret;
867}
868//____________________________________________________________________
869AliOADBForward::Table*
870AliOADBForward::GetTableFromFile(TFile* file,
871 Bool_t rw,
872 const TString& name,
873 const TString& mode) const
874{
875 //
876 // Get a table from a file, or make a new table
877 //
878 if (!file) return 0;
879 if (FindTable(name, true)) return 0;
880
881 TObject* o = file->Get(name);
882 TTree* t = 0;
883 Bool_t n = false;
884 if (!o) {
885 if (!rw) {
886 // We only fail if in read-only mode
887 Error("Open", "No such object: %s in %s", name.Data(),
888 file->GetName());
889 return 0;
890 }
891 // Create the tree in the file
892 t = new TTree(name, mode);
893 t->SetDirectory(file);
894 n = true;
895 }
896 else {
897 // Get the tree, and set the branch
898 t = static_cast<TTree*>(o);
899 }
900 Table* ret = new Table(t, n, String2Mode(mode));
901 return ret;
902}
903//____________________________________________________________________
904void
905AliOADBForward::AppendToQuery(TString& q, const TString& s, Bool_t andNotOr)
906{
907 //
908 // Helper function
909 //
910 if (!q.IsNull()) q.Append(andNotOr ? " && " : " || ");
911 q.Append(s);
912}
913//____________________________________________________________________
914TString
915AliOADBForward::Conditions(UShort_t sys,
916 UShort_t sNN,
917 Short_t fld,
918 Bool_t mc,
919 Bool_t sat)
920{
921 // Build query string
922 TString q;
923 if (sys > 0) AppendToQuery(q, Form("fSys == %hu", sys));
924 if (sNN > 0) AppendToQuery(q, Form("abs(fSNN - %hu) < 11", sNN));
925 if (TMath::Abs(fld) < 10) AppendToQuery(q, Form("fField == %hd",fld));
926 // Boolean fields always queried. In cases where these do not matter,
927 // we always write down the false value, so we get the correct query
928 // anyways.
929 AppendToQuery(q, Form("%sfMC", (mc ? " " : "!")));
930 AppendToQuery(q, Form("%sfSatellite", (sat ? " " : "!")));
931
932 return q;
933}
934
935//____________________________________________________________________
936void
937AliOADBForward::TestGet(AliOADBForward& t,
938 const TString& table,
939 ULong_t runNo,
940 ERunSelectMode mode,
941 UShort_t sys,
942 UShort_t sNN,
943 Short_t fld,
944 Bool_t mc,
945 Bool_t sat)
946{
947
948 Printf("=== Test query: t=%s r=%ld s=%d t=%d f=%d m=%d v=%d",
949 table.Data(), runNo, sys, sNN, fld, int(mc), int(sat));
950 AliOADBForward::Entry* e = t.Get(table, runNo, mode, sys, sNN,
951 fld, mc, sat);
952 if (!e) return;
953 e->Print();
954}
955//____________________________________________________________________
956void
957AliOADBForward::TestInsert(AliOADBForward& t,
958 const TString& table,
959 ULong_t runNo,
960 UShort_t sys,
961 UShort_t sNN,
962 Short_t fld,
963 Bool_t mc,
964 Bool_t sat)
965{
966 static Int_t cnt = 0;
967 TString what = TString::Format("%s-%03d", table.Data(), cnt++);
968 Printf("=== Insert: t=%s r=%ld s=%d t=%d f=%d m=%d v=%d w=%s",
969 table.Data(), runNo, sys, sNN, fld, int(mc), int(sat), what.Data());
970 t.Insert(table, new TObjString(what), runNo, sys, sNN, fld, mc, sat);
971 gSystem->Sleep(500);
972}
973
974//____________________________________________________________________
975void
976AliOADBForward::Test()
977{
978 AliOADBForward* tt = new AliOADBForward();
979 if (!tt->Open("db.root", "A,B", true, true)) {
980 ::Error("Test", "Failed to open DB");
981 return;
982 }
983 AliOADBForward& t = *tt;
984 TestInsert(t, "A", 137161);
985 TestInsert(t, "A", 137161);
986 TestInsert(t, "A", 0 );
987 TestInsert(t, "A", 999999);
988 TestInsert(t, "A", 137166);
989
990
991 TestInsert(t, "B", 137161);
992 TestInsert(t, "B", 0 );
993 t.Print();
994 t.Close();
995
996 if (!t.Open("db.root", "A,B",false,true)) {
997 ::Error("Test", "Failed to open DB");
998 return;
999 }
1000
1001 TestGet(t, "A", 137161);
1002 TestGet(t, "A", 137160);
1003 TestGet(t, "A", 0 );
1004 TestGet(t, "A", 137160, kNewest);
1005 TestGet(t, "A", 137160, kNewer);
1006 TestGet(t, "A", 137168, kOlder);
1007 TestGet(t, "A", 137161, kExact);
1008
1009 new TBrowser("b", tt);
1010}
1011
1012//
1013// EOF
1014//