GammaWare  Head Version for release 0.9
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
HistoDB.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2004-2006 by Olivier Stezowski & Christophe Theisen *
3  * stezow(AT)ipnl.in2p3.fr, christophe.theisen(AT)cea.fr *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ***************************************************************************/
20 
23 #ifndef GW_HISTODB_H
24 #include "HistoDB.h"
25 #endif
26 
27 #ifndef ROOT_TSystem
28 #include <TSystem.h>
29 #endif
30 
31 #include <iostream>
32 
33 using namespace std;
34 using namespace Gw;
35 
36 
37 // ROOT dictionnary
39 
40 //__________________________________________________________
41 HistoDB::HistoDB()
42 {
43  fCurrentDB = 0x0; fStatus = HistoDB::kGood;
44 }
45 
46 //__________________________________________________________
47 HistoDB::~HistoDB()
48 {
49  fCurrentDB = 0x0; fStatus = HistoDB::kGood;
50 
51  map<const char *, HistoConverter *>::iterator im; // iterator on the map prototype
52  for (im = fConnections.begin() ; im != fConnections.end() ; im++ ) delete im->second;
53 }
54 
55 //__________________________________________________________
56 void HistoDB::AddFileExt(const char* type, const char* ext)
57 {
58  TString dbtype(type), tmp;
59 
60  // find out the corresponding DB service in the prototype list
61  map<const char *, HistoConverter *>::iterator im; // iterator on the map
62 
63  for (im = fCurrentDB->GetMapPrototype()->begin() ; im != fCurrentDB->GetMapPrototype()->end() ; im++ ) {
64  tmp = im->first;
65  if ( dbtype == tmp )
66  im->second->SetFileExt(ext);
67  }
68 }
69 
70 //_________________________________________________________________
71 void HistoDB::AddOption(const char* type, Option_t* opt, const char* mode)
72 {
73  TString dbtype(type), tmp;
74 
75  // find out the corresponding DB service in the prototype list
76  map<const char *, HistoConverter *>::iterator im; // iterator on the map
77 
78  for (im = fCurrentDB->GetMapPrototype()->begin() ; im != fCurrentDB->GetMapPrototype()->end() ; im++ ) {
79  tmp = im->first;
80  if ( dbtype == tmp )
81  im->second->SetOption(opt,mode);
82  }
83 }
84 
85 
86 //__________________________________________________________
87 void HistoDB::SetCurrent(const char *alias)
88 {
89  if ( fConnections.find(alias) != fConnections.end() ) { fCurrentDB = fConnections[alias]; }
90 }
91 
92 //________________________________________________________________
93 HistoConverter *HistoDB::Open(const char *alias, const char *name)
94 {
95  TString dbtype, dbname, tmp; HistoConverter *newdb; newdb = 0x0;
96 
97  // to get the db service type and its name
98  dbtype = name; dbname = name;
99  if ( dbtype.Contains(':') ) {
100  dbtype.Remove(dbtype.First(':')); dbname.Remove(0,dbname.First(':')+1);
101  }
102  else {
103  cout << name << " is not a valid name " << endl;
104  return 0x0;
105  }
106 
107  // find out the corresponding DB service in the prototype list
108  map<const char *, HistoConverter *>::iterator im; // iterator on the map
109 
110  for (im = fCurrentDB->GetMapPrototype()->begin() ; im != fCurrentDB->GetMapPrototype()->end() ; im++ ) {
111  tmp = im->first;
112  if ( dbtype == tmp ) {
113  newdb = im->second->NewDB(dbname.Data());
114  newdb->SetFileExt( im->second->GetFileExt() );
115  newdb->SetOption( im->second->GetOption() );
116  newdb->CheckMineTypes();
117  }
118  }
119  // allocation failed, don't know how to allocate this service.
120  if ( newdb == 0x0 ) { // opening fails
121  cout << " Cannot allocate HistoDB service " << name << endl; return 0x0;
122  }
123  // check out if this is not a zombie (zombie = not well open)
124  if ( newdb->GetStatus() == fCurrentDB->kZombie ) {
125  cout << " Cannot open a connection to "
126  << name << endl << " --> " << newdb->GetError() << endl;
127 
128  delete newdb; return 0x0;
129  }
130 
131  // look if there is already an open connection corresponding to alias
132  bool isnew = false;
133  if ( fConnections.find(alias) == fConnections.end() ) { isnew = true; }
134 
135  if (isnew) fConnections[alias] = newdb;
136  else {
137  cout << " An HistoDB service already exists with the alias " << name << endl;
138  delete newdb; newdb = 0x0;
139  }
140  if ( newdb ) fCurrentDB = newdb; // newdb becomes the current one
141 
142  return newdb;
143 }
144 
145 //_____________________________________________________
146 void HistoDB::SetMode(const char *alias, Option_t *mode)
147 {
148  TString opt = mode;
149 
150  if ( fConnections.find(alias) == fConnections.end() ) {
151  if ( opt.Contains("overwrite") )
152  fConnections[alias]->SetMode(HistoConverter::kOverwrite);
153  else
154  fConnections[alias]->SetMode(HistoConverter::kVersion);
155  }
156 }
157 
158 //__________________________________________________________
159 void HistoDB::SetMode(Option_t *mode)
160 {
161  TString opt = mode;
162 
163  if ( fCurrentDB ) {
164  if ( opt.Contains("overwrite") )
165  fCurrentDB->SetMode(HistoConverter::kOverwrite);
166  else
167  fCurrentDB->SetMode(HistoConverter::kVersion);
168  }
169 }
170 
171 //__________________________________________________________
172 void HistoDB::ls(Option_t *o)
173 {
174  TString opt = o;
175  map<const char *, HistoConverter *>::iterator im; // iterator on the map prototype
176 
177  if ( opt.Contains("proto") ) { // list of prototypes
178  cout << "Known DB system to import/export ROOT histograms" << endl;
179  for (im = fCurrentDB->GetMapPrototype()->begin() ; im != fCurrentDB->GetMapPrototype()->end() ; im++ ) {
180  cout << " - " << im->first << endl ;
181  }
182  }
183  if ( opt.Contains("cdb") ) { // current db system
184  if ( fCurrentDB == 0x0 ) {
185  cout << "No current DB service defined !" << endl;
186  }
187  else {
188  cout << "Current DB service is:" << endl; fCurrentDB->ls(o);
189  }
190  }
191  if ( opt.Contains("all") ) { // all db system defined
192  cout << "List of all DB services open:" << endl;
193  for (im = fConnections.begin() ; im != fConnections.end() ; im++ ) {
194  cout << "\t" << im->first << " "; im->second->ls(o); }
195  }
196 }
197 
198 //__________________________________________________________
199 void HistoDB::SetVerboseLevel(const int level){
200 
201  HistoConverter::SetVerboseLevel(level);
202 
203 }
204 
205 //__________________________________________________________
206 int HistoDB::GetVerboseLevel(){
207 
208  return HistoConverter::GetVerboseLevel();
209 
210 }
211 
212 //__________________________________________________________
213 TH1 *HistoDB::Get(int i)
214 {
215  TH1 *histo = 0x0;
216 
217  if ( fCurrentDB && fStatus == HistoDB::kGood ) {
218  if ( (histo = fCurrentDB->Get(i)) == 0x0 ) {
219  fStatus = HistoDB::kFail; cerr << fCurrentDB->GetError() << endl;
220  }
221  }
222  return histo;
223 }
224 
225 //__________________________________________________________
226 TH1 *HistoDB::Get(const char *name)
227 {
228  TH1 *histo = 0x0;
229 
230  if ( fCurrentDB && fStatus == HistoDB::kGood ) {
231  if ( (histo = fCurrentDB->Get(name)) == 0x0 ) {
232  fStatus = HistoDB::kFail; cerr << fCurrentDB->GetError() << endl;
233  }
234  }
235  return histo;
236 }
237 
238 //__________________________________________________________
239 bool HistoDB::Write(const TH1 &h)
240 {
241 bool result = false;
242  if ( fCurrentDB && fStatus == HistoDB::kGood ) {
243  result = fCurrentDB->Write(h);
244  if ( result == false ) {
245  fStatus = HistoDB::kFail; cerr << fCurrentDB->GetError() << endl;
246  }
247  }
248  return result;
249 }
250 //__________________________________________________________
251 bool HistoDB::Write(const TH2 &h)
252 {
253 bool result = false;
254  if ( fCurrentDB && fStatus == HistoDB::kGood ) {
255  result = fCurrentDB->Write(h);
256  if ( result == false ) {
257  fStatus = HistoDB::kFail; cerr << fCurrentDB->GetError() << endl;
258  }
259  }
260  return result;
261 }
262 
263 //__________________________________________________________
265 {
266  if ( fCurrentDB && fStatus == HistoDB::kGood ) {
267  if ( fCurrentDB->Write(h) == false ) {
268  fStatus = HistoDB::kFail; cerr << fCurrentDB->GetError() << endl;
269  }
270  }
271  return (*this);
272 }
273 
274 //__________________________________________________________
276 {
277 
278  if ( fCurrentDB && fStatus == HistoDB::kGood ) {
279  if ( fCurrentDB->Read(h) == false ) {
280  fStatus = HistoDB::kFail; cerr << fCurrentDB->GetError() << endl;
281  }
282  }
283  return (*this);
284 }
285 
286 //__________________________________________________________
288 {
289  if ( fCurrentDB && fStatus == HistoDB::kGood ) {
290  if ( fCurrentDB->Write(h) == false ) {
291  fStatus = HistoDB::kFail; cerr << fCurrentDB->GetError() << endl;
292  }
293  }
294  return (*this);
295 }
296 
297 //__________________________________________________________
299 {
300  if ( fCurrentDB && fStatus == HistoDB::kGood ) {
301  if ( fCurrentDB->Read(h) == false ) {
302  fStatus = HistoDB::kFail; cerr << fCurrentDB->GetError() << endl;
303  }
304  }
305  return (*this);
306 }
307 
308 //__________________________________________________________
309 HistoDB & HistoDB::operator << (const THStack &hs)
310 {
311  if ( fCurrentDB && fStatus == HistoDB::kGood ) {
312  if ( fCurrentDB->Write(hs) == false ) {
313  fStatus = HistoDB::kFail; cerr << fCurrentDB->GetError() << endl;
314  }
315  }
316  return (*this);
317 }
318 
319 //__________________________________________________________
321 {
322  if ( fCurrentDB && fStatus == HistoDB::kGood ) {
323  if ( fCurrentDB->Read(hs) == false ) {
324  fStatus = HistoDB::kFail; cerr << fCurrentDB->GetError() << endl;
325  }
326  }
327  return (*this);
328 }
329 
330 //__________________________________________________________
331 void HistoDB::MakeConverter(const char *classname) const
332 {
333  TString tmp;
334 
335  // open the file for the header part
336  tmp = classname; tmp += ".h"; ofstream header(tmp.Data());
337  if ( !header ) { cout << " Cannot open file " << tmp.Data() << endl; return; }
338 
339  // open the file for the implementation part
340  tmp = classname; tmp += ".C"; ofstream imp(tmp.Data());
341  if ( !imp ) { cout << " Cannot open file " << tmp.Data() << endl; header.close(); return; }
342 
343  // set the header part
344  header << "#ifndef " << classname << "_H" << endl;
345  header << "#define " << classname << "_H 1" << endl;
346  header << endl;
347  header << "#include <HistoDB.h> " << endl;
348  header << endl;
349  header << "class "<< classname <<": public HistoConverter " << endl;
350  header << "{ " << endl;
351  header << "public:" << endl;
352  header << " "<< classname <<"();" << endl;
353  header << " "<< classname <<"(const char *name);" << endl;
354  header << " virtual ~"<< classname <<"();" << endl;
355  header << endl;
356  header << " virtual TH1 *Get(int); " << endl;
357  header << " virtual TH1 *Get(const char *); " << endl;
358  header << endl;
359  header << " virtual bool Read(TH1 &);" << endl;
360  header << " virtual bool Write(const TH1 &);" << endl;
361  header << endl;
362  header << " virtual bool Read(TH2 &);" << endl;
363  header << " virtual bool Write(const TH2 &);" << endl;
364  header << endl;
365  header << " virtual bool Read(THStack &);" << endl;
366  header << " virtual bool Write(const THStack &);" << endl;
367  header << endl;
368  header << " virtual HistoConverter *NewDB(const char *) const;" << endl;
369  header << endl;
370  header << " virtual const char *GetType() const { return \""
371  << classname << "\" ; }" << endl;
372  header << "};" << endl;
373  header << "#endif " << endl;
374 
375  imp << endl;
376  imp << "#include \"" << classname << ".h\"" << endl;
377  imp << endl;
378  imp << "namespace { " << classname << " g" << classname
379  << "; } // prototype ONLY use to creat a new DB system" << endl;
380  imp << endl;
381  imp << classname << "::" << classname << "(const char *name) : HistoConverter(name)" << endl;
382  imp << "{ " << endl;
383  imp << endl;
384  imp << "} " << endl;
385  imp << endl;
386  imp << classname << "::" << classname << "() : HistoConverter()" << endl;
387  imp << "{ " << endl;
388  imp << endl;
389  imp << " // add this interface to the DB service " << endl;
390  imp << " AddPrototype(GetType(),this);" << endl;
391  imp << "} " << endl;
392  imp << classname << "::~" << classname << "()" << endl;
393  imp << "{ " << endl;
394  imp << endl;
395  imp << "} " << endl;
396  imp << endl;
397  imp << "HistoConverter *" << classname
398  << "::NewDB(const char *name) const { return new "<< classname << "(name) ;}" << endl;
399  imp << endl;
400  imp << "TH1 *" << classname << "::Get(int which)" << endl;
401  imp << "{ " << endl;
402  imp << " SetError(HistoConverter::kFail,\"[" << classname << "::Get(int which)"
403  << "] NO IMPLEMENTATION !!\") ; return 0x0;" << endl;
404  imp << "} " << endl;
405  imp << endl;
406  imp << "TH1 *" << classname << "::Get(const char *name)" << endl;
407  imp << "{ " << endl;
408  imp << " SetError(HistoConverter::kFail,\"[" << classname << "::Get(const char *name)"
409  << "] NO IMPLEMENTATION !!\") ; return 0x0;" << endl;
410  imp << "} " << endl;
411  imp << endl;
412  imp << "bool " << classname << "::Read(TH1 &h)" << endl;
413  imp << "{ " << endl;
414  imp << " SetError(HistoConverter::kFail,\"[" << classname << "::Read(TH1 &h)"
415  << "] NO IMPLEMENTATION !!\") ; return false;" << endl;
416  imp << "} " << endl;
417  imp << endl;
418  imp << "bool " << classname << "::Write(const TH1 &h)" << endl;
419  imp << "{ " << endl;
420  imp << " SetError(HistoConverter::kFail,\"[" << classname << "::Write(const TH1 &h)"
421  << "] NO IMPLEMENTATION !!\") ; return false;" << endl;
422  imp << "} " << endl;
423  imp << endl;
424  imp << "bool " << classname << "::Read(TH2 &h)" << endl;
425  imp << "{ " << endl;
426  imp << " SetError(HistoConverter::kFail,\"[" << classname << "::Read(TH2 &h)"
427  << "] NO IMPLEMENTATION !!\") ; return false;" << endl;
428  imp << "} " << endl;
429  imp << endl;
430  imp << "bool " << classname << "::Write(const TH2 &h)" << endl;
431  imp << "{ " << endl;
432  imp << " SetError(HistoConverter::kFail,\"[" << classname << "::Write(const TH2 &h)"
433  << "] NO IMPLEMENTATION !!\") ; return false;" << endl;
434  imp << "} " << endl;
435  imp << endl;
436  imp << "bool " << classname << "::Read(THStack &hs)" << endl;
437  imp << "{ " << endl;
438  imp << " SetError(HistoConverter::kFail,\"[" << classname << "::Read(THStack &hs)"
439  << "] NO IMPLEMENTATION !!\") ; return false;" << endl;
440  imp << "} " << endl;
441  imp << endl;
442  imp << "bool " << classname << "::Write(const THStack &hs)" << endl;
443  imp << "{ " << endl;
444  imp << " SetError(HistoConverter::kFail,\"[" << classname << "::Write(const THStack &hs)"
445  << "] NO IMPLEMENTATION !!\") ; return false;" << endl;
446  imp << "} " << endl;
447 
448  header.close(); imp.close();
449 }
450 
std::istream & operator>>(std::istream &is, ADF::FactoryItem &item)
void SetFileExt(TString ext)
to set/get file extension of the spectra/histo
void SetOption(Option_t *opt, const char *mode="reset")
set options
TH1F * histo[MaxValue]
Definition: ReadDaqAlone.C:31
header file for the HistoDB facility
void SetMode(HistoConverter::EMode mode)
int GetStatus() const
ClassImp(HistoDB)
std::ostream & operator<<(std::ostream &out, const Parity &p)
to write a parity in a stream
Definition: Parity.cpp:93
ADF::LogMessage & endl(ADF::LogMessage &log)
Service to read/write ROOT histograms from/to different DB systems.
Definition: HistoDB.h:90
const char * GetError() const
virtual HistoConverter * NewDB(const char *) const
to creat a new DB system
void CheckMineTypes()
check mine types