EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
FairRuntimeDb.cxx
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file FairRuntimeDb.cxx
1 //*-- AUTHOR : Ilse Koenig
2 //*-- Created : 20/10/2004
3 
5 // FairRuntimeDb
6 //
7 // Administration class for parameter input/output
9 
10 #include "FairRuntimeDb.h"
11 
12 #include "FairContFact.h"
13 #include "FairParSet.h"
14 #include "FairRtdbRun.h"
15 #include "FairParIo.h"
16 #include "FairParRootFileIo.h"
17 #include "FairParAsciiFileIo.h"
20 
21 #include "FairParTSQLIo.h"
22 #include "FairDetParTSQLIo.h"
23 #include "FairGenericParTSQLIo.h"
24 
25 //#include "TKey.h"
26 #include "TClass.h"
27 
28 
29 #include <iostream>
30 #include <iomanip>
31 
32 using std::cout;
33 using std::endl;
34 using std::ios;
35 using std::setw;
36 
38 // 0 = use original code; 1 = use new code
39 #define USE_DB_METHOD 0
40 
41 
43 
45 
46 FairRuntimeDb* FairRuntimeDb::instance(void)
47 {
48  // Singleton instance
49  if (gRtdb==0) { gRtdb=new FairRuntimeDb; }
50  return gRtdb;
51 }
52 
54  :TObject(),
55  containerList(new TList()),
56  runs(new TList()),
57  firstInput(NULL),
58  secondInput(NULL),
59  output(NULL),
60  currentRun(NULL),
61  currentFileName(""),
62  versionsChanged(kFALSE),
63  isRootFileOutput(kFALSE),
64  fLogger(FairLogger::GetLogger()),
65  ioType(UNKNOWN_Type)
66 {
67  gRtdb=this;
68 }
69 
71 {
72  // destructor
73  // deletes the list of runs and all containers
76  closeOutput();
77  if (containerList) {
78  /*
79  TIter next(containerList);
80  FairParSet* cont;
81  while ((cont=(FairParSet*)next())) {
82  Text_t* name=(char*)cont->GetName();
83  cout<<"Remove Container: "<<name<<endl;
84  removeContainer(name);
85  }
86  */
87  containerList->Delete();
88  delete containerList;
89  }
90  if (runs) {
91  runs->Delete();
92  delete runs;
93  }
94  gRtdb=0;
95 }
96 
98 {
99  // Adds a container factory to the list of factories
100  if (!(contFactories.FindObject(fact->GetName()))) {
101  fLogger->Debug( MESSAGE_ORIGIN,"- RTDB container factory %s \n",fact->GetName() );
102  contFactories.Add(fact);
103  }
104 }
105 
107 {
108  return ((FairContFact*)contFactories.FindObject(FactName));
109 }
110 
111 Bool_t FairRuntimeDb::addParamContext(const char* context)
112 {
113  // Sets via the container factories the context of all parameter containers,
114  // which accept this context
115  Bool_t found=kFALSE;
116  TIter next(&contFactories);
117  FairContFact* fact;
118  while((fact=(FairContFact*)next())) {
119  if (fact->addContext(context)) { found=kTRUE; }
120  }
121  Error("addParamContext(const char*)","Unknown context");
122  return found;
123 }
124 
126 {
127  // Prints the context of all parameter containers, which can be created by
128  // the container factories
129  TIter next(&contFactories);
130  FairContFact* fact;
131  while((fact=(FairContFact*)next())) { fact->print(); }
132 }
133 
135 {
136  // adds a container to the list of containers
137  Text_t* name=(char*)container->GetName();
138  if (!containerList->FindObject(name)) {
139  containerList->Add(container);
140  TIter next(runs);
141  FairRtdbRun* run;
142  FairParVersion* vers;
143  while ((run=(FairRtdbRun*)next())) {
144  if (!run->getParVersion(name)) {
145  vers=new FairParVersion(name);
146  run->addParVersion(vers);
147  }
148  }
149  return kTRUE;
150  }
151  Warning("addContainer(FairParSet*)","Container %s already exists!",name);
152  return kFALSE;
153 }
154 
156 {
157  // The function loops over the container factories to find the corresponding container
158  // with the give name and its context.
159  // The name is the original name of the parameter container without the concatination
160  // with the context.
161  // The factory checks, if the container exists already in the runtime database. Otherwise
162  // it will be created and added by the factory.
163  // The function returns a pointer to the container or NULL, if not created.
164  TIter next(&contFactories);
165  FairContFact* fact;
166  FairParSet* c=0;
167  while(!c && (fact=(FairContFact*)next())) {
168  c=fact->getContainer(name);
169  }
170  if (!c) { Error("getContainer(Text_t*)","Container %s not created!",name); }
171  return c;
172 }
173 
175 {
176  // returns a pointer to the container called by name
177  // The name is the original name of the parameter container eventually concatinated with
178  // a non-default context.
179  return (FairParSet*)(containerList->FindObject(name));
180 }
181 
183 {
184  // removes the container from the list and deletes it
185  TObject* c=containerList->FindObject(name);
186  if (c) {
187  containerList->Remove(c);
188  delete c;
189  }
190 }
191 
193 {
194  // removes all containers from the list and deletes them
195  containerList->Delete();
196 }
197 
198 FairRtdbRun* FairRuntimeDb::addRun(Int_t runId,Int_t refId)
199 {
200  // adds a run at the end of the list of runs
201  // returns a pointer to the run newly added
202  FairRtdbRun* run;
203  if (refId!=-1) {
204  run=getRun(refId);
205  if (!run) { addRun(refId); }
206  }
207  run=getRun(runId);
208  if (!run) {
209  run=new FairRtdbRun(runId,refId);
210  TIter next(containerList);
211  FairParSet* cont;
212  FairParVersion* vers;
213  while ((cont=(FairParSet*)next())) {
214  vers=new FairParVersion(((char*)cont->GetName()));
215  run->addParVersion(vers);
216  }
217  runs->Add(run);
218  currentRun=run;
219  } else { Warning("addRun(Int_t,Int_t)","Run already exists"); }
220  return run;
221 }
222 
224 {
225  // returns a pointer to the run called by the run id
226  char name[255];
227  sprintf(name,"%i",id);
228  return (FairRtdbRun*)(runs->FindObject(name));
229 }
230 
232 {
233  // returns a pointer to the run called by name
234  return (FairRtdbRun*)(runs->FindObject(name));
235 }
236 
238 {
239  // removes the run from the list and deletes it
240  TObject* c=runs->FindObject(name);
241  if (c) {
242  runs->Remove(c);
243  delete c;
244  if(c==currentRun) { currentRun=0; }
245  }
246 }
247 
249 {
250  runs->Delete();
251 }
252 
254 {
255  // writes the parameter versions for all runs to the output
256  if (getOutput() && output->check()) {
258  output->cd();
259  if (gFile->IsWritable()) { runs->Write(); }
260  versionsChanged=kFALSE;
261  }
262  }
263 }
264 
266 {
267  // writes all containers to the output
268  // loops over the list of containers and calls for each the
269  // function writeContainer(...)
270  TIter next(containerList);
271  FairParSet* cont;
272  Bool_t rc=kTRUE;
273  FairRtdbRun* refRun=0;
274  if (currentRun) {
275  const char* refRunName=currentRun->getRefRun();
276  if (strlen(refRunName)>0) {
277  refRun=(FairRtdbRun*)(runs->FindObject(refRunName));
278  }
279  while ((cont=(FairParSet*)next())) {
280  rc=writeContainer(cont,currentRun,refRun) && rc;
281  }
282  }
283  if (!rc) { Error("writeContainers()","Error in write of containers to output"); }
284  return rc;
285 }
286 
288 {
289  Int_t in1=cont->getInputVersion(1);
290  Int_t in2=cont->getInputVersion(2);
291  FairRtdbRun* run;
292  FairParVersion* vers;
293  Text_t* name=(char*)cont->GetName();
294  Int_t v=0;
295  if (in1==-1 && in2==-1) {
296  if (cont->hasChanged()) { return 0; }
297  else {
298  Int_t i=runs->IndexOf(currentRun); //FIXME: This can be optimized with a backwards iter.
299  while (i>=0) {
300  run=(FairRtdbRun*)runs->At(i);
301  vers=run->getParVersion(name);
302  if (vers->getInputVersion(1)==in1 && vers->getInputVersion(2)==in2) {
303  if ((v=vers->getRootVersion())!=0) { return v; }
304  }
305  --i;
306  }
307  return 0;
308  }
309  }
310  if ((firstInput==output) && (in1>0 && in2==-1)) { return in1; }
311  TIter next(runs);
312  v=0;
313  while ((run=(FairRtdbRun*)next())) {
314  vers=run->getParVersion(name);
315  if (vers->getInputVersion(1)==in1 && vers->getInputVersion(2)==in2) {
316  if ((v=vers->getRootVersion())!=0) { return v; }
317  }
318  }
319  return 0;
320 }
321 
323 #if (USE_DB_METHOD == 0)
325 {
326  // writes a container to the output if the containers has changed
327  // The output might be suppressed if the changes is due an initialisation from a
328  // ROOT file which serves also as output or if it was already written
329  Text_t* c=(char*)cont->GetName();
330  fLogger->Debug( MESSAGE_ORIGIN,"RuntimeDb: write container : %s ", cont->GetName());
331  FairParVersion* vers=run->getParVersion(c);
332  Bool_t rc=kTRUE;
333  Int_t cv=0;
334  if (getOutput() && output->check() && output->isAutoWritable()) {
335  if (isRootFileOutput) {
336  if (cont->hasChanged()) {
337  cv=findOutputVersion(cont);
338  if (cv==0) {
339  cv=cont->write(output);
340  if (cv>0) {
341  fLogger->Info(MESSAGE_ORIGIN,"*** %s written to ROOT file version: %i ", c, cv);
342  } else if (cv==-1) { return kFALSE; }
343  // -1 indicates and error during write
344  // 0 is allowed for all containers which have no write function
345  }
346  vers->setRootVersion(cv);
347  } else {
348  if (vers->getRootVersion()==0) {
349  cv=findOutputVersion(cont);
350  vers->setRootVersion(cv);
351  }
352  }
353  } else { // might be Ascii I/O
354  if (cont->hasChanged()) {
355  cv=cont->write(output);
356  if (cv<0) { return kFALSE; }
357  cout<<"*** "<<c<<" written to output"<<'\n';
358  vers->setRootVersion(cv);
359  }
360  }
361  }
362  vers->setInputVersion(cont->getInputVersion(1),1);
363  vers->setInputVersion(cont->getInputVersion(2),2);
364  cont->setChanged(kFALSE);
365  if (refRun) {
366  FairParVersion* refVers=refRun->getParVersion(c);
367  if (refVers) {
368  refVers->setInputVersion(cont->getInputVersion(1),1);
369  refVers->setInputVersion(cont->getInputVersion(2),2);
370  refVers->setRootVersion(cv);
371  }
372  }
373  return rc;
374 }
375 #endif
376 
378 #if (USE_DB_METHOD > 0)
380 {
381  std::cout << "\n\t+++++++<DEBUG> Using modified code.+++++++\n";
382  // writes a container to the output if the containers has changed
383  // The output might be suppressed if the changes is due an initialisation from a
384  // ROOT file which serves also as output or if it was already written
385  Text_t* c = (char*)cont->GetName();
386  fLogger->Debug( MESSAGE_ORIGIN,"RuntimeDb: write container : %s ", cont->GetName());
387  FairParVersion* vers = run->getParVersion(c);
388  Bool_t rc = kTRUE;
389  Int_t cv = 0;
390  if (getOutput() && output->check() && output->isAutoWritable()) {
391  switch (ioType) {
392  case RootFileOutput: // RootFile
393  if (cont->hasChanged()) {
394  cv = findOutputVersion(cont);
395  if (cv == 0) {
396  cv = cont->write(output);
397  if (cv>0) {
398  fLogger->Info(MESSAGE_ORIGIN,"*** %s written to ROOT file version: %i ", c, cv);
399  } else if (cv==-1) {
400  return kFALSE;
401  }
402  // -1 indicates and error during write
403  // 0 is allowed for all containers which have no write function
404  }
405  vers->setRootVersion(cv);
406  } else {
407  if (vers->getRootVersion() == 0) {
408  cv = findOutputVersion(cont);
409  vers->setRootVersion(cv);
410  }
411  }
412  break;// End of rootfile IO
413  case RootTSQLOutput://TSQL
414  if (cont->hasChanged()) {
415  cv = findOutputVersion(cont);
416  if(cv == 0) {
417  std::cout << "<DEBUG> Write TSQL here cv = "<< cv << "_ <++++++>\n";
418  cont->print();
419  cont->write();
420  }
421  }
422  break;//End of TSQL IO
423  case AsciiFileOutput:// might be Ascii I/O
424  if(cont->hasChanged()) {
425  cv = cont->write(output);
426  if(cv <0) {
427  return kFALSE;
428  }
429  cout << "*** " << c << " written to output" << '\n';
430  vers->setRootVersion(cv);
431  }
432  break;// End of Ascii IO
433  default: // Unknown IO
434  Error("writeContainer()","Unknown output file type.");
435  break;
436  }
437  }
438  vers->setInputVersion(cont->getInputVersion(1),1);
439  vers->setInputVersion(cont->getInputVersion(2),2);
440  cont->setChanged(kFALSE);
441  if (refRun) {
442  FairParVersion* refVers=refRun->getParVersion(c);
443  if (refVers) {
444  refVers->setInputVersion(cont->getInputVersion(1),1);
445  refVers->setInputVersion(cont->getInputVersion(2),2);
446  refVers->setRootVersion(cv);
447  }
448  }
449  return rc;
450 }
451 #endif
452 
453 
454 Bool_t FairRuntimeDb::initContainers(Int_t runId,Int_t refId,
455  const Text_t* fileName)
456 {
457  // loops over the list of containers and calls the init() function of each
458  // container if it is not static
459  // (typically called by Hades::eventLoop(...))
460  if (currentRun && currentRun->getRunId()!=runId) { writeContainers(); }
461  FairRtdbRun* run=getRun(runId);
462  if (!run) { run=addRun(runId,refId); }
463  else {
464  run->setRefRun(refId);
465  if (refId!=-1 && !getRun(refId)) { addRun(refId); }
466  }
467  currentRun=run;
468  currentFileName=fileName;
469  return initContainers();
470 }
471 
473 {
474  // reads all containers with all versions for all runs and writes the
475  // containers, the setup information and the version table to the output
476  if (!(getOutput() && output->check())) {
477  cout<<"***********************************************************"<<endl;
478  cout<<"********************* W A R N I N G *********************"<<endl;
479  cout<<"********************* no output ! *********************"<<endl;
480  cout<<"***********************************************************"<<endl;
481  }
482  currentRun=0;
483  Bool_t rc=kTRUE;
484  TIter next(runs);
485  while ((currentRun=(FairRtdbRun*)next())!=0) {
486  rc=initContainers() && rc;
487  writeContainers();
488  }
489  saveOutput();
490  currentRun=0;
491  return kTRUE;
492 }
493 
495 {
496  // private function
497  Text_t* refRunName=(char*)currentRun->getRefRun();
498  Int_t len=strlen(refRunName);
499  if (len<1) {
502  } else {
503  FairRtdbRun* refRun=getRun(refRunName);
504  if (firstInput) { firstInput->readVersions(refRun); }
505  if (secondInput) { secondInput->readVersions(refRun); }
506  }
507  TIter next(containerList);
508  FairParSet* cont;
509  Bool_t rc=kTRUE;
510  cout<<'\n'<<"*************************************************************"<<'\n';
511  if (currentFileName.IsNull()) {
512  cout<<" initialisation for run id "<<currentRun->GetName();
513  } else {
514  cout<<" initialisation for event file "<<currentFileName.Data()<<'\n';
515  cout<<" run id "<<currentRun->GetName();
516  }
517  if (len>0) { cout << " --> " << refRunName; }
518  cout<<'\n'<<"*************************************************************"<<'\n';
519  while ((cont=(FairParSet*)next())) {
520  if (!cont->isStatic()) { rc=cont->init() && rc; }
521  }
522  if (!rc) { Error("initContainers()","Error occured during initialization"); }
523  return rc;
524 }
525 
527 {
528  // sets the status flag in all containers
529  // flag kTRUE sets all 'static'
530  // flag kFALSE sets all 'not static'
531  TIter next(containerList);
532  FairParSet* cont;
533  while ((cont=(FairParSet*)next())) {
534  cont->setStatic(flag);
535  }
536 }
537 
538 Bool_t FairRuntimeDb::setInputVersion(Int_t run,Text_t* container,
539  Int_t version,Int_t inp)
540 {
541  // sets the input version of a container defined by its name and a
542  // run defined by its id taken from input with inputNumber inp
543  // (1 for first input and 2 for second input)
544  FairRtdbRun* r=getRun(run);
545  if (r) {
546  FairParVersion* v=r->getParVersion(container);
547  if (v) {
548  v->setInputVersion(version,inp);
549  return kTRUE;
550  } else { Error("setInputVersion","Container not found"); }
551  } else { Error("setInputVersion","Run not found"); }
552  return kFALSE;
553 }
554 
555 
556 Bool_t FairRuntimeDb::setRootOutputVersion(Int_t run,Text_t* container,
557  Int_t version)
558 {
559  // sets the Root file output version of a container defined by its name
560  // and a run defined by its id
561  // should only be used after initialization 'by hand' on the interpreter level
562  FairRtdbRun* r=getRun(run);
563  if (r) {
564  FairParVersion* v=r->getParVersion(container);
565  if (v) {
566  v->setRootVersion(version);
567  return kTRUE;
568  } else { Error("setRootOutputVersion","Container not found"); }
569  } else { Error("setRootOutputVersion","Run not found"); }
570  return kFALSE;
571 }
572 
574 {
575  // prints the list of the actual containers, the list of the
576  // runs/versions and information about input/output
577  cout<<"--------------------------------------------------------------------------------\n";
578  cout<<"-------------- actual containers in runtime database -------------------------\n";
579  TIter nextCont(containerList);
580  FairParSet* cont;
581  cout.setf(ios::left,ios::adjustfield);
582  while((cont=(FairParSet*)nextCont())) {
583  cout<<setw(45)<<cont->GetName()<<" "<<cont->GetTitle()<<'\n';
584  }
585  TIter next(runs);
586  FairRtdbRun* run;
587  cout<<"-------------- runs, versions ------------------------------------------------\n";
588  cout<<"run id\n";
589  cout<<" "<<setw(45)<<"container";
590  cout.setf(ios::right,ios::adjustfield);
591  cout<<setw(11)<<"1st-inp"
592  <<setw(11)<<" 2nd-inp"
593  <<setw(11)<<" output\n";
594  while ((run=(FairRtdbRun*)next())) {
595  run->print();
596  }
597  cout<<"-------------- input/output --------------------------------------------------\n";
598  if (firstInput) {
599  cout<<"first Input:\n";
600  firstInput->print();
601  } else { cout<<"first input: none"<<'\n'; }
602  if (secondInput) {
603  cout<<"second Input:\n";
604  secondInput->print();
605  } else { cout<<"second input: none"<<'\n'; }
606  if (output) {
607  cout<<"output:\n";
608  output->print();
609  } else { cout<<"output: none"<<'\n'; }
610 }
611 
613 {
614  // resets all input versions in the list of runs and in all containers which are not static
615  // is called each time a new input is set
616  TIter nextRun(runs);
617  FairRtdbRun* run;
618  while ((run=(FairRtdbRun*)nextRun())) {
619  run->resetInputVersions();
620  }
621  TIter nextCont(containerList);
622  FairParSet* cont;
623  while ((cont=(FairParSet*)nextCont())) {
624  if (!cont->isStatic()) { cont->resetInputVersions(); }
625  }
626 }
627 
629 {
630  // resets all output versions in the list of runs
631  // is called each time a new output is set
632  // is called also each time a new input is set which is not identical with the output
633  TIter next(runs);
634  FairRtdbRun* run;
635  while ((run=(FairRtdbRun*)next())) {
636  run->resetOutputVersions();
637  }
638 }
639 
641 {
642  // resets all input and output versions in the list of runs
643  // and in all containers which are not static
646 }
647 
649 {
650  // sets the first input pointer
651  firstInput=inp1;
652  if (inp1->check()==kTRUE) {
653  inp1->setInputNumber(1);
656  return kTRUE;
657  } else { Error("setFirstInput(FairParIo*)","no connection to input"); }
658  return kFALSE;
659 }
660 
662 {
663  // sets the second input pointer
664  secondInput=inp2;
665  if (inp2->check()==kTRUE) {
666  inp2->setInputNumber(2);
669  return kTRUE;
670  } else { Error("setSecondInput(FairParIo*)","no connection to input"); }
671  return kFALSE;
672 }
674 #if (USE_DB_METHOD == 0)
676 {
677  // sets the output pointer
678  output=op;
679  if (output->check()==kTRUE) {
681  if (strcmp(output->IsA()->GetName(),"FairParRootFileIo")==0) {
682  isRootFileOutput=kTRUE;
683  }
684  return kTRUE;
685  } else { Error("setOutput(FairParIo*)","no connection to output"); }
686  return kFALSE;
687 }
688 #endif
689 
690 #if (USE_DB_METHOD > 0)
692 {
693  // sets the output pointer
694  output = op;
695  if (output->check() == kTRUE) {
697  if (strcmp(output->IsA()->GetName(), "FairParRootFileIo") == 0) {
699  } else if (strcmp(output->IsA()->GetName(), "FairParTSQLIo") == 0) {
701  } else { //ASCII
703  }
704  return kTRUE;
705  } else { Error("setOutput(FairParIo*)","no connection to output"); }
706  return kFALSE;
707 }
708 #endif
709 
711 {
712  // return a pointer to the first input
713  if (firstInput) { firstInput->cd(); }
714  return firstInput;
715 }
716 
718 {
719  // return a pointer to the second input
720  if (secondInput) { secondInput->cd(); }
721  return secondInput;
722 }
723 
725 {
726  // return a pointer to the output
727  if (output) { output->cd(); }
728  return output;
729 }
730 
732 {
733  if (firstInput) {
734  firstInput->cd();
735  firstInput->close();
736  firstInput=0;
737  }
738 }
739 
741 {
742  if (secondInput) {
743  secondInput->cd();
744  secondInput->close();
745  secondInput=0;
746  }
747 }
748 
750 {
751  // writes the versions and the containers (if not yet written out)
752  // without the version information the containers cannot be read from a ROOT file!
753  Bool_t rc=kTRUE;
754  if (currentRun!=0) { rc=writeContainers(); }
755  writeVersions();
756  if (!rc) { Error("saveOutput()","Error occured during write"); }
757 }
758 
760 {
761  // calls saveOutput() and deletes then the output
762  if (output) {
763  if (output->isAutoWritable()) { saveOutput(); }
764  output->close();
766  output=0;
767  isRootFileOutput=kFALSE;
768  }
769 }
770 
772 {
773  // activates the detector I/O
774  const char* ioName=io->IsA()->GetName();
775  FairDetParIo* po=io->getDetParIo("FairGenericParIo");
776  if (!po) {
777  if (strcmp(ioName,"FairParRootFileIo")==0) {
779  new FairGenericParRootFileIo(((FairParRootFileIo*)io)->getParRootFile());
780  io->setDetParIo(pn);
781  } else if (strcmp(ioName,"FairParAsciiFileIo")==0) {
783  new FairGenericParAsciiFileIo(((FairParAsciiFileIo*)io)->getFile());
784  io->setDetParIo(pn);
785  } else if(strcmp(ioName,"FairParTSQLIo") == 0) {
786  std::cout << "\n\n\n\t TSQL versie is called en nu de rest \n\n";
788  io->setDetParIo(pn);
789  }
790  }
791  TIter next(&contFactories);
792  FairContFact* fact;
793  while((fact=(FairContFact*)next())) {
794  fact->activateParIo(io);
795  }
796 }