Gaudi Framework, version v24r2

Home   Generated: Wed Dec 4 2013
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
THistSvc.cpp
Go to the documentation of this file.
1 #ifdef __ICC
2 // disable icc remark #2259: non-pointer conversion from "X" to "Y" may lose significant bits
3 // TODO: To be removed, since it comes from ROOT TMathBase.h
4 #pragma warning(disable:2259)
5 #endif
6 
7 #include "THistSvc.h"
8 
11 #include "GaudiKernel/Tokenizer.h"
13 #include "GaudiKernel/Property.h"
19 #include "GaudiKernel/IFileMgr.h"
20 
21 #include "boost/bind.hpp"
22 
23 
24 #include "TROOT.h"
25 #include "TFile.h"
26 #include "TDirectory.h"
27 #include "TKey.h"
28 #include "TError.h"
29 #include "TGraph.h"
30 
31 #include <sstream>
32 #include <streambuf>
33 #include <cstdio>
34 
35 using namespace std;
36 
37 
39 
40 inline void toupper(std::string &s)
41 {
42  std::transform(s.begin(), s.end(), s.begin(),
43  (int(*)(int)) toupper);
44 }
45 
46 
47 //*************************************************************************//
48 
50  : base_class(name, svc), m_log(msgSvc(), name ), signaledStop(false),
51  m_delayConnect(false),m_okToConnect(false),
52  p_incSvc(0), p_fileMgr(0) {
53 
54  declareProperty ("AutoSave", m_autoSave=0 );
55  declareProperty ("AutoFlush", m_autoFlush=0 );
56  declareProperty ("PrintAll", m_print=false);
57  declareProperty ("MaxFileSize", m_maxFileSize=10240,
58  "maximum file size in MB. if exceeded, will cause an abort. -1 to never check.");
62 
63 
64 }
65 
66 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
67 
69 
70 }
71 
72 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
73 
76  GlobalDirectoryRestore restore;
77 
78  // Super ugly hack to make sure we have the OutputLevel set first, so we
79  // can see DEBUG printouts in update handlers.
80  IJobOptionsSvc* jos(0);
81  if( serviceLocator()->service( "JobOptionsSvc", jos, true ).isSuccess() ) {
82  const std::vector<const Property*> *props = jos->getProperties( name() );
83 
84  if (props != NULL) {
86  cur != props->end(); cur++) {
87  if ( (*cur)->name() == "OutputLevel" ) {
88  setProperty( **cur ).ignore();
90  break;
91  }
92  }
93  }
94  }
95 
96 
99 
100  if (status.isFailure()) {
101  m_log << MSG::ERROR << "initializing service" << endmsg;
102  return status;
103  }
104 
107 
108  try {
110  } catch ( GaudiException& err ) {
111  m_log << MSG::ERROR
112  << "Caught: " << err << endmsg;
113  st = StatusCode::FAILURE;
114  }
115 
116  try {
118  } catch ( GaudiException& err ) {
119  m_log << MSG::ERROR
120  << "Caught: " << err << endmsg;
121  st = StatusCode::FAILURE;
122  }
123 
124  // Protect against multiple instances of TROOT
125  if ( 0 == gROOT ) {
126  static TROOT root("root","ROOT I/O");
127  // gDebug = 99;
128  } else {
129  if (m_log.level() <= MSG::VERBOSE)
130  m_log << MSG::VERBOSE << "ROOT already initialized, debug = "
131  << gDebug<< endmsg;
132  }
133 
134  if (service("IncidentSvc", p_incSvc, true).isFailure()) {
135  m_log << MSG::ERROR << "unable to get the IncidentSvc" << endmsg;
136  st = StatusCode::FAILURE;
137  } else {
138  p_incSvc->addListener( this, "EndEvent", 100, true);
139  }
140 
141  if (service("FileMgr",p_fileMgr,true).isFailure()) {
142  m_log << MSG::ERROR << "unable to get the FileMgr" << endmsg;
143  st = StatusCode::FAILURE;
144  } else {
145  m_log << MSG::DEBUG << "got the FileMgr" << endmsg;
146  }
147 
148 
149  // Register open/close callback actions
150 
151  Io::bfcn_action_t boa = boost::bind(&THistSvc::rootOpenAction, this, _1,_2);
153  m_log << MSG::ERROR
154  << "unable to register ROOT file open action with FileMgr"
155  << endmsg;
156  }
157  Io::bfcn_action_t bea = boost::bind(&THistSvc::rootOpenErrAction, this, _1,_2);
159  m_log << MSG::ERROR
160  << "unable to register ROOT file open Error action with FileMgr"
161  << endmsg;
162  }
163 
164 
165  m_okToConnect = true;
166 
167  if (m_delayConnect == true) {
168  if (m_inputfile.value().size() > 0) { setupInputFile(m_inputfile); }
169  if (m_outputfile.value().size() > 0) { setupOutputFile(m_outputfile); }
170 
171  m_delayConnect = false;
172 
173  }
176 
177 
178  IIoComponentMgr* iomgr(0);
179 
180  if (service("IoComponentMgr", iomgr, true).isFailure()) {
181  m_log << MSG::ERROR << "unable to get the IoComponentMgr" << endmsg;
182  st = StatusCode::FAILURE;
183  } else {
184 
185  if ( !iomgr->io_register (this).isSuccess() ) {
186  m_log << MSG::ERROR
187  << "could not register with the I/O component manager !"
188  << endmsg;
189  st = StatusCode::FAILURE;
190  } else {
191  bool all_good = true;
193  // register input/output files...
194  for ( Registry_t::const_iterator
195  ireg = m_files.begin(),
196  iend = m_files.end();
197  ireg != iend;
198  ++ireg ) {
199  const std::string fname = ireg->second.first->GetName();
200  const IIoComponentMgr::IoMode::Type iomode =
201  ( ireg->second.second==THistSvc::READ
204  if ( !iomgr->io_register (this, iomode, fname).isSuccess () ) {
205  m_log << MSG::WARNING << "could not register file ["
206  << fname << "] with the I/O component manager..." << endmsg;
207  all_good = false;
208  } else {
209  m_log << MSG::INFO << "registered file [" << fname << "]... [ok]"
210  << endmsg;
211  }
212  }
213  if (!all_good) {
214  m_log << MSG::ERROR
215  << "problem while registering input/output files with "
216  << "the I/O component manager !" << endmsg;
217  st = StatusCode::FAILURE;
218  }
219  }
220 
221  }
222 
223  if (st.isFailure()) {
224  m_log << MSG::FATAL << "Unable to initialize THistSvc" << endmsg;
225  }
226 
227  return st;
228 
229 }
230 
231 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
232 
235 
236  GlobalDirectoryRestore restore;
237 
238  m_log << MSG::WARNING << "reinitialize not implemented" << endmsg;
239 
240 
241  return StatusCode::SUCCESS;
242 
243 }
244 
245 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
246 
249 
250  GlobalDirectoryRestore restore;
251 
252  if (m_log.level() <= MSG::DEBUG)
253  m_log << MSG::DEBUG << "THistSvc::finalize" << endmsg;
254 
255 #ifndef NDEBUG
256  if (m_log.level() <= MSG::DEBUG) {
258  for (uitr=m_uids.begin(); uitr != m_uids.end(); ++uitr) {
259 
260  TObject* to = uitr->second.obj;
261 
262  string dirname("none");
263  if (to && to->IsA()->InheritsFrom("TTree")) {
264  TTree* tr = dynamic_cast<TTree*>(to);
265  if (tr->GetDirectory() != 0) {
266  dirname = tr->GetDirectory()->GetPath();
267  }
268  } else if (to && to->IsA()->InheritsFrom("TGraph")) {
269  if (!uitr->second.temp) {
270  dirname = uitr->second.file->GetPath();
271  string id2(uitr->second.id);
272  id2.erase(0,id2.find("/",1));
273  id2.erase(id2.rfind("/"), id2.length());
274  if (id2.find("/") == 0) {
275  id2.erase(0,1);
276  }
277  dirname += id2;
278  } else {
279  dirname = "/tmp";
280  }
281  } else if (to && to->IsA()->InheritsFrom("TH1")) {
282  TH1* th = dynamic_cast<TH1*>(to);
283  if (th == 0) {
284  m_log << MSG::ERROR << "Couldn't dcast: " << uitr->first << endmsg;
285  } else {
286  if (th->GetDirectory() != 0) {
287  dirname = th->GetDirectory()->GetPath();
288  }
289  }
290  } else if (! to ) {
291  m_log << MSG::WARNING << uitr->first << " has NULL TObject ptr"
292  << endmsg;
293  }
294 
295  m_log << MSG::DEBUG << "uid: \"" << uitr->first << "\" temp: "
296  << uitr->second.temp << " dir: " << dirname
297  << endmsg;
298  }
299  }
300 #endif
301 
302  StatusCode sc = write();
303  if (sc.isFailure()) {
304  m_log << MSG::ERROR << "problems writing histograms" << endmsg;
305  }
306 
307  if (m_print) {
308  m_log << MSG::INFO << "Listing contents of ROOT files: " << endmsg;
309  }
310  vector<TFile*> deleted_files;
311  map<string, pair<TFile*,Mode> >::const_iterator itr;
312  for (itr = m_files.begin(); itr != m_files.end(); ++itr) {
313 
314  if (find(deleted_files.begin(), deleted_files.end(), itr->second.first) ==
315  deleted_files.end()) {
316  deleted_files.push_back(itr->second.first);
317 
318 #ifndef NDEBUG
319  if (m_log.level() <= MSG::DEBUG)
320  m_log << MSG::DEBUG << "finalizing stream/file " << itr->first << ":"
321  << itr->second.first->GetName()
322  << endmsg;
323 #endif
324  } else {
325 #ifndef NDEBUG
326  if (m_log.level() <= MSG::DEBUG)
327  m_log << MSG::DEBUG << "already finalized stream " << itr->first << endmsg;
328 #endif
329  continue;
330  }
331 
332 
333  if (m_print && m_log.level() <= MSG::INFO) {
334 
335  m_log << MSG::INFO;
336  m_log << "==> File: " << itr->second.first->GetName()
337  << " stream: " << itr->first << endmsg;
338 
339  itr->second.first->Print("base");
340  }
341 
342  string tmpfn=itr->second.first->GetName();
343 
344  p_fileMgr->close(itr->second.first, name());
345 
346  IIncidentSvc *pi(0);
347  if (service("IncidentSvc",pi).isFailure()) {
348  m_log << MSG::ERROR << "Unable to get the IncidentSvc" << endmsg;
349  return StatusCode::FAILURE;
350  }
351 
352  if (itr->second.second==SHARE) {
353 
354  //Merge File
355  void* vf(0);
356  int r = p_fileMgr->open(Io::ROOT,name(), m_sharedFiles[itr->first],
357  Io::WRITE|Io::APPEND,vf,"HIST");
358 
359  if (r != 0 ) {
360  m_log << MSG::ERROR << "unable to open Final Output File: \""
361  << m_sharedFiles[itr->first] << "\" for merging"
362  << endmsg;
363  return StatusCode::FAILURE;
364  }
365 
366  TFile *outputfile = (TFile*) vf;
368  m_sharedFiles[itr->first]));
369 
370  if (m_log.level() <= MSG::DEBUG)
371  m_log << MSG::DEBUG << "THistSvc::write()::Merging Rootfile "<<endmsg;
372 
373  vf = 0;
374  r = p_fileMgr->open(Io::ROOT,name(),tmpfn,Io::READ,vf,"HIST");
375 
376  if (r != 0) {
377  m_log << MSG::ERROR << "unable to open temporary file: \""
378  << tmpfn << endmsg;
379  return StatusCode::FAILURE;
380  }
381 
382  TFile *inputfile = (TFile*) vf;
383 
384  outputfile->SetCompressionLevel( inputfile->GetCompressionLevel() );
385 
386  MergeRootFile(outputfile, inputfile);
387 
388  outputfile->Write();
389  p_fileMgr->close(outputfile,name());
390  p_fileMgr->close(inputfile,name());
391 
392  if (m_log.level() <= MSG::DEBUG)
393  m_log << MSG::DEBUG << "Trying to remove temporary file \"" << tmpfn
394  << "\""<<endmsg;
395 
396  std::remove(tmpfn.c_str());
397  }
398  delete itr->second.first;
399  }
400 
403  m_files.clear();
404  m_uids.clear();
405  m_ids.clear();
406  m_tobjs.clear();
407 
408  return Service::finalize();
409 }
410 
411 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
412 
413 bool
414 THistSvc::browseTDir(TDirectory *dir) const {
415 
416  if (dir == 0) {
417  std::cerr << "TDirectory == 0" << std::endl;
418  return false;
419  }
420 
421  GlobalDirectoryRestore restore;
422 
423  dir->cd();
424 
425 
426  cout << "-> " << dir->GetPath() << " "
427  << dir->GetListOfKeys()->GetSize() << endl;
428 
429  // TIter nextkey(dir->GetListOfKeys());
430  TIter nextkey(dir->GetList());
431  while (TKey *key = (TKey*)nextkey()) {
432 
433  TObject *obj = key->ReadObj();
434  if (obj == 0) { cout << key->GetName() << " obj==0"<< endl; continue; }
435  // if (obj->IsA()->InheritsFrom("TDirectory")) {
436  cout << " Key: " << key->GetName() << " "
437  << " tit: " << obj->GetTitle() << " "
438  << " (" << key->GetClassName() << ")" << endl;
439  // }
440  }
441 
442  nextkey = dir->GetListOfKeys();
443  while (TKey *key = (TKey*)nextkey()) {
444 
445  TObject *obj = key->ReadObj();
446  if (obj == 0) { cout << key->GetName() << " obj==0"<< endl; continue; }
447  if (obj->IsA()->InheritsFrom("TDirectory")) {
448  TDirectory *tt = dynamic_cast<TDirectory*>(obj);
449  browseTDir(tt);
450  }
451  }
452 
453  return true;
454 }
455 
456 
457 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
458 
460 THistSvc::getTHists(TDirectory *td, TList & tl, bool rcs) const {
461  GlobalDirectoryRestore restore;
462 
463  gErrorIgnoreLevel = kBreak;
464 
465  if (!td->cd()) {
466  m_log << MSG::ERROR << "getTHists: No such TDirectory \"" << td->GetPath()
467  << "\"" << endmsg;
468  return StatusCode::FAILURE;
469  }
470 
471  if (m_log.level() <= MSG::DEBUG)
472  m_log << MSG::DEBUG << "getTHists: \"" << td->GetPath() << "\": found "
473  << td->GetListOfKeys()->GetSize() << " keys" << endmsg;
474 
475  TIter nextkey(td->GetListOfKeys());
476  while (TKey *key = (TKey*)nextkey()) {
477  if (m_log.level() <= MSG::DEBUG)
478  m_log << MSG::DEBUG << " key: " << key->GetName();
479  TObject *obj = key->ReadObj();
480  if (obj != 0 && obj->IsA()->InheritsFrom("TDirectory")) {
481  if (m_log.level() <= MSG::DEBUG)
482  m_log << " (" << obj->IsA()->GetName() << ")";
483  } else if (obj != 0 && obj->IsA()->InheritsFrom("TH1")) {
484  if (m_log.level() <= MSG::DEBUG)
485  m_log << " (" << obj->IsA()->GetName() << ")";
486  tl.Add(obj);
487  } else if (obj != 0) {
488  if (m_log.level() <= MSG::DEBUG)
489  m_log << " [" << obj->IsA()->GetName() << "]";
490  }
491  if (m_log.level() <= MSG::DEBUG)
492  m_log << endmsg;
493  }
494 
495  // operate recursively
496  if (rcs) {
497  nextkey = td->GetListOfKeys();
498  while (TKey *key = (TKey*)nextkey()) {
499  TObject *obj = key->ReadObj();
500  if (obj != 0 && obj->IsA()->InheritsFrom("TDirectory")) {
501  TDirectory *tt = dynamic_cast<TDirectory*>(obj);
502  getTHists(tt, tl, rcs);
503  }
504  }
505  }
506 
507  return StatusCode::SUCCESS;
508 
509 
510 }
511 
512 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
513 
515 THistSvc::getTHists(const std::string& dir, TList & tl, bool rcs) const {
516 
517  GlobalDirectoryRestore restore;
518 
519  gErrorIgnoreLevel = kBreak;
520 
521  StatusCode sc;
522 
523  std::string stream,rem,r2;
524  parseString(dir,stream,rem);
525 
526  map< string,pair<TFile*,Mode> >::const_iterator itr = m_files.find(stream);
527  if (itr != m_files.end()) {
528  r2 = itr->second.first->GetName();
529  r2 += ":/";
530  r2 += rem;
531 
532  if (m_log.level() <= MSG::DEBUG)
533  m_log << MSG::DEBUG << "getTHists: \"" << dir
534  << "\" looks like a stream name." << " associated TFile: \""
535  << itr->second.first->GetName() << "\"" << endmsg;
536 
537  if (gDirectory->cd(r2.c_str())) {
538  m_curstream = stream;
539  sc = getTHists(gDirectory,tl,rcs);
540  m_curstream = "";
541  return sc;
542  } else {
543  if (m_log.level() <= MSG::DEBUG)
544  m_log << MSG::DEBUG << "getTHists: no such TDirectory \""
545  << r2 << "\"" << endmsg;
546  }
547 
548  } else {
549  if (m_log.level() <= MSG::DEBUG)
550  m_log << MSG::DEBUG << "getTHists: stream \"" << stream << "\" not found"
551  << endmsg;
552  }
553 
554  if (!gDirectory->cd(dir.c_str())) {
555  m_log << MSG::ERROR << "getTHists: No such TDirectory/stream \"" << dir
556  << "\"" << endmsg;
557  sc = StatusCode::FAILURE;
558  } else {
559  sc = getTHists(gDirectory,tl,rcs);
560  }
561 
562  return sc;
563 
564 }
565 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
566 
568 THistSvc::getTTrees(TDirectory *td, TList & tl, bool rcs) const {
569  GlobalDirectoryRestore restore;
570 
571  gErrorIgnoreLevel = kBreak;
572 
573  if (!td->cd()) {
574  m_log << MSG::ERROR << "getTTrees: No such TDirectory \""
575  << td->GetPath() << "\"" << endmsg;
576  return StatusCode::FAILURE;
577  }
578 
579  if (m_log.level() <= MSG::DEBUG)
580  m_log << MSG::DEBUG << "getTHists: \"" << td->GetPath() << "\": found "
581  << td->GetListOfKeys()->GetSize() << " keys" << endmsg;
582 
583  TIter nextkey(td->GetListOfKeys());
584  while (TKey *key = (TKey*)nextkey()) {
585  if (m_log.level() <= MSG::DEBUG)
586  m_log << MSG::DEBUG << " key: " << key->GetName();
587  TObject *obj = key->ReadObj();
588  if (obj != 0 && obj->IsA()->InheritsFrom("TDirectory")) {
589  if (m_log.level() <= MSG::DEBUG)
590  m_log << " (" << obj->IsA()->GetName() << ")";
591  } else if (obj != 0 && obj->IsA()->InheritsFrom("TTree")) {
592  if (m_log.level() <= MSG::DEBUG)
593  m_log << " (" << obj->IsA()->GetName() << ")";
594  tl.Add(obj);
595  } else if (obj != 0) {
596  if (m_log.level() <= MSG::DEBUG)
597  m_log << " [" << obj->IsA()->GetName() << "]";
598  }
599  m_log << endmsg;
600  }
601 
602  // operate recursively
603  if (rcs) {
604  nextkey = td->GetListOfKeys();
605  while (TKey *key = (TKey*)nextkey()) {
606  TObject *obj = key->ReadObj();
607  if (obj != 0 && obj->IsA()->InheritsFrom("TDirectory")) {
608  TDirectory *tt = dynamic_cast<TDirectory*>(obj);
609  getTTrees(tt, tl, rcs);
610  }
611  }
612  }
613 
614  return StatusCode::SUCCESS;
615 
616 }
617 
618 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
619 
621 THistSvc::getTTrees(const std::string& dir, TList & tl, bool rcs) const {
622  GlobalDirectoryRestore restore;
623 
624  gErrorIgnoreLevel = kBreak;
625 
626  StatusCode sc;
627 
628  std::string stream,rem,r2;
629  parseString(dir,stream,rem);
630 
631  map< string,pair<TFile*,Mode> >::const_iterator itr = m_files.find(stream);
632  if (itr != m_files.end()) {
633  r2 = itr->second.first->GetName();
634  r2 += ":/";
635  r2 += rem;
636 
637  if (m_log.level() <= MSG::DEBUG)
638  m_log << MSG::DEBUG << "getTTrees: \"" << dir
639  << "\" looks like a stream name." << " associated TFile: \""
640  << itr->second.first->GetName() << "\"" << endmsg;
641 
642  if (gDirectory->cd(r2.c_str())) {
643  return getTTrees(gDirectory,tl,rcs);
644  } else {
645  if (m_log.level() <= MSG::DEBUG)
646  m_log << MSG::DEBUG << "getTTrees: no such TDirectory \""
647  << r2 << "\"" << endmsg;
648  }
649 
650  } else {
651  if (m_log.level() <= MSG::DEBUG)
652  m_log << MSG::DEBUG << "getTTrees: stream \"" << stream << "\" not found"
653  << endmsg;
654  }
655 
656  if (!gDirectory->cd(dir.c_str())) {
657  m_log << MSG::ERROR << "getTTrees: No such TDirectory/stream \"" << dir
658  << "\"" << endmsg;
659  sc = StatusCode::FAILURE;
660  } else {
661  sc = getTTrees(gDirectory,tl,rcs);
662  }
663 
664  return sc;
665 
666 
667 }
668 
669 
670 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
671 
673 THistSvc::getTHists(TDirectory *td, TList & tl, bool rcs, bool reg) {
674 
675  GlobalDirectoryRestore restore;
676 
677  gErrorIgnoreLevel = kBreak;
678 
679  if (!td->cd()) {
680  m_log << MSG::ERROR << "getTHists: No such TDirectory \"" << td->GetPath()
681  << "\"" << endmsg;
682  return StatusCode::FAILURE;
683  }
684 
685  if (m_log.level() <= MSG::DEBUG)
686  m_log << MSG::DEBUG << "getTHists: \"" << td->GetPath() << "\": found "
687  << td->GetListOfKeys()->GetSize() << " keys" << endmsg;
688 
689  TIter nextkey(td->GetListOfKeys());
690  while (TKey *key = (TKey*)nextkey()) {
691  if (m_log.level() <= MSG::DEBUG)
692  m_log << MSG::DEBUG << " key: " << key->GetName();
693  TObject *obj = key->ReadObj();
694  if (obj != 0 && obj->IsA()->InheritsFrom("TDirectory")) {
695  if (m_log.level() <= MSG::DEBUG)
696  m_log << " (" << obj->IsA()->GetName() << ")";
697  } else if (obj != 0 && obj->IsA()->InheritsFrom("TH1")) {
698  if (m_log.level() <= MSG::DEBUG)
699  m_log << " (" << obj->IsA()->GetName() << ")";
700  tl.Add(obj);
701  if (reg && m_curstream != "") {
702  string dir = td->GetPath();
703  string fil = td->GetFile()->GetName();
704  dir.erase(0,fil.length()+1);
705  string id = "/" + m_curstream;
706  if ( dir == "/" ) {
707  id = id + "/" + key->GetName();
708  } else {
709  id = id + dir + "/" + key->GetName();
710  }
711  if (!exists(id)) {
712  if (m_log.level() <= MSG::DEBUG)
713  m_log << " reg as \"" << id << "\"";
714  regHist(id).ignore();
715  } else {
716  if (m_log.level() <= MSG::DEBUG)
717  m_log << " already registered";
718  }
719  }
720  } else if (obj != 0) {
721  if (m_log.level() <= MSG::DEBUG)
722  m_log << " [" << obj->IsA()->GetName() << "]";
723  }
724  if (m_log.level() <= MSG::DEBUG)
725  m_log << endmsg;
726  }
727 
728  // operate recursively
729  if (rcs) {
730  nextkey = td->GetListOfKeys();
731  while (TKey *key = (TKey*)nextkey()) {
732  TObject *obj = key->ReadObj();
733  if (obj != 0 && obj->IsA()->InheritsFrom("TDirectory")) {
734  TDirectory *tt = dynamic_cast<TDirectory*>(obj);
735  getTHists(tt, tl, rcs, reg);
736  }
737  }
738  }
739 
740  return StatusCode::SUCCESS;
741 
742 }
743 
744 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
745 
747 THistSvc::getTHists(const std::string& dir, TList & tl, bool rcs, bool reg) {
748 
749  GlobalDirectoryRestore restore;
750 
751  gErrorIgnoreLevel = kBreak;
752 
753  StatusCode sc;
754 
755  std::string stream,rem,r2;
756  parseString(dir,stream,rem);
757 
758  map< string,pair<TFile*,Mode> >::const_iterator itr = m_files.find(stream);
759  if (itr != m_files.end()) {
760  r2 = itr->second.first->GetName();
761  r2 += ":/";
762  r2 += rem;
763 
764  if (m_log.level() <= MSG::DEBUG)
765  m_log << MSG::DEBUG << "getTHists: \"" << dir
766  << "\" looks like a stream name." << " associated TFile: \""
767  << itr->second.first->GetName() << "\"" << endmsg;
768 
769  if (gDirectory->cd(r2.c_str())) {
770  m_curstream = stream;
771  sc = getTHists(gDirectory,tl,rcs,reg);
772  m_curstream = "";
773  return sc;
774  } else {
775  if (m_log.level() <= MSG::DEBUG)
776  m_log << MSG::DEBUG << "getTHists: no such TDirectory \""
777  << r2 << "\"" << endmsg;
778  }
779 
780  } else {
781  if (m_log.level() <= MSG::DEBUG)
782  m_log << MSG::DEBUG << "getTHists: stream \"" << stream << "\" not found"
783  << endmsg;
784  }
785 
786  if (!gDirectory->cd(dir.c_str())) {
787  m_log << MSG::ERROR << "getTHists: No such TDirectory/stream \"" << dir
788  << "\"" << endmsg;
789  sc = StatusCode::FAILURE;
790  } else {
791  if (reg) {
792  m_log << MSG::WARNING << "Unable to register histograms automatically "
793  << "without a valid stream name" << endmsg;
794  reg = false;
795  }
796  sc = getTHists(gDirectory,tl,rcs,reg);
797  }
798 
799  return sc;
800 
801 }
802 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
803 
805 THistSvc::getTTrees(TDirectory *td, TList & tl, bool rcs, bool reg) {
806 
807  GlobalDirectoryRestore restore;
808 
809  gErrorIgnoreLevel = kBreak;
810 
811  if (!td->cd()) {
812  m_log << MSG::ERROR << "getTTrees: No such TDirectory \""
813  << td->GetPath() << "\"" << endmsg;
814  return StatusCode::FAILURE;
815  }
816 
817  if (m_log.level() <= MSG::DEBUG)
818  m_log << MSG::DEBUG << "getTHists: \"" << td->GetPath() << "\": found "
819  << td->GetListOfKeys()->GetSize() << " keys" << endmsg;
820 
821  TIter nextkey(td->GetListOfKeys());
822  while (TKey *key = (TKey*)nextkey()) {
823  if (m_log.level() <= MSG::DEBUG)
824  m_log << MSG::DEBUG << " key: " << key->GetName();
825  TObject *obj = key->ReadObj();
826  if (obj != 0 && obj->IsA()->InheritsFrom("TDirectory")) {
827  if (m_log.level() <= MSG::DEBUG)
828  m_log << " (" << obj->IsA()->GetName() << ")";
829  } else if (obj != 0 && obj->IsA()->InheritsFrom("TTree")) {
830  if (m_log.level() <= MSG::DEBUG)
831  m_log << " (" << obj->IsA()->GetName() << ")";
832  tl.Add(obj);
833  if (reg && m_curstream != "") {
834  string dir = td->GetPath();
835  string fil = td->GetFile()->GetName();
836  dir.erase(0,fil.length()+1);
837  string id = "/" + m_curstream;
838  if ( dir == "/" ) {
839  id = id + "/" + key->GetName();
840  } else {
841  id = id + dir + "/" + key->GetName();
842  }
843  if (!exists(id)) {
844  if (m_log.level() <= MSG::DEBUG)
845  m_log << " reg as \"" << id << "\"";
846  regHist(id).ignore();
847  } else {
848  if (m_log.level() <= MSG::DEBUG)
849  m_log << " already registered";
850  }
851  }
852  } else if (obj != 0) {
853  if (m_log.level() <= MSG::DEBUG)
854  m_log << " [" << obj->IsA()->GetName() << "]";
855  }
856  if (m_log.level() <= MSG::DEBUG)
857  m_log << endmsg;
858  }
859 
860  // operate recursively
861  if (rcs) {
862  nextkey = td->GetListOfKeys();
863  while (TKey *key = (TKey*)nextkey()) {
864  TObject *obj = key->ReadObj();
865  if (obj != 0 && obj->IsA()->InheritsFrom("TDirectory")) {
866  TDirectory *tt = dynamic_cast<TDirectory*>(obj);
867  getTTrees(tt, tl, rcs, reg);
868  }
869  }
870  }
871 
872  return StatusCode::SUCCESS;
873 
874 }
875 
876 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
877 
879 THistSvc::getTTrees(const std::string& dir, TList & tl, bool rcs, bool reg) {
880 
881  GlobalDirectoryRestore restore;
882 
883  gErrorIgnoreLevel = kBreak;
884 
885  StatusCode sc;
886 
887  std::string stream,rem,r2;
888  parseString(dir,stream,rem);
889 
890  map< string,pair<TFile*,Mode> >::const_iterator itr = m_files.find(stream);
891  if (itr != m_files.end()) {
892  r2 = itr->second.first->GetName();
893  r2 += ":/";
894  r2 += rem;
895 
896  if (m_log.level() <= MSG::DEBUG)
897  m_log << MSG::DEBUG << "getTTrees: \"" << dir
898  << "\" looks like a stream name." << " associated TFile: \""
899  << itr->second.first->GetName() << "\"" << endmsg;
900 
901  if (gDirectory->cd(r2.c_str())) {
902  return getTTrees(gDirectory,tl,rcs,reg);
903  } else {
904  if (m_log.level() <= MSG::DEBUG)
905  m_log << MSG::DEBUG << "getTTrees: no such TDirectory \""
906  << r2 << "\"" << endmsg;
907  }
908 
909  } else {
910  if (m_log.level() <= MSG::DEBUG)
911  m_log << MSG::DEBUG << "getTTrees: stream \"" << stream << "\" not found"
912  << endmsg;
913  }
914 
915  if (!gDirectory->cd(dir.c_str())) {
916  m_log << MSG::ERROR << "getTTrees: No such TDirectory/stream \"" << dir
917  << "\"" << endmsg;
918  sc = StatusCode::FAILURE;
919  } else {
920  sc = getTTrees(gDirectory,tl,rcs,reg);
921  }
922 
923  return sc;
924 
925 }
926 
927 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
928 
930 THistSvc::deReg(TObject* obj) {
931 
932  objMap::iterator itr = m_tobjs.find(obj);
933  if (itr != m_tobjs.end()) {
934  THistID hid = itr->second;
935 
936  uidMap::iterator itr2 = m_uids.find(hid.id);
937  if (itr2 == m_uids.end()) {
938  m_log << MSG::ERROR << "Problems deregistering TObject \""
939  << obj->GetName()
940  << "\" with id \"" << hid.id << "\"" << endmsg;
941  return StatusCode::FAILURE;
942  }
943 
944  std::string id,root,rem;
945  parseString(hid.id, root, rem);
946 
947  idMap::iterator itr3;
948  bool found(false);
949 
951  if (mitr.first == mitr.second) {
952  m_log << MSG::ERROR << "Problems deregistering TObject \""
953  << obj->GetName()
954  << "\" with id \"" << hid.id << "\"" << endmsg;
955  return StatusCode::FAILURE;
956  } else {
957  for (itr3 = mitr.first; itr3 != mitr.second; ++itr3) {
958  if (itr3->second.obj == obj) {
959  found = true;
960  break;
961  }
962  }
963  if (!found) {
964  m_log << MSG::ERROR << "Problems deregistering TObject \""
965  << obj->GetName()
966  << "\" with id \"" << hid.id << "\"" << endmsg;
967  }
968  }
969 
970  m_tobjs.erase(itr);
971  m_uids.erase(itr2);
972  m_ids.erase(itr3);
973 
974  return StatusCode::SUCCESS;
975 
976  } else {
977  m_log << MSG::ERROR << "Cannot unregister TObject \"" << obj->GetName()
978  << "\": not known to THistSvc" << endmsg;
979  return StatusCode::FAILURE;
980  }
981 
982 }
983 
984 
985 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
986 
989 
990  uidMap::iterator itr = m_uids.find(id);
991  if (itr == m_uids.end()) {
992  m_log << MSG::ERROR << "Problems deregistering id \""
993  << id << "\"" << endmsg;
994  return StatusCode::FAILURE;
995  }
996 
997  TObject* obj = itr->second.obj;
998 
999  return deReg(obj);
1000 }
1001 
1002 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1003 
1004 StatusCode
1006 
1007  TH1 *hist(0);
1008 
1009  return regHist_i(hist, id);
1010 }
1011 
1012 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1013 
1014 StatusCode
1015 THistSvc::regHist(const std::string& id, TH1* hist) {
1016  return regHist_i(hist, id);
1017 }
1018 
1019 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1020 
1021 StatusCode
1022 THistSvc::regHist(const std::string& id, TH2* hist) {
1023  return regHist_i(hist, id);
1024 }
1025 
1026 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1027 
1028 StatusCode
1029 THistSvc::regHist(const std::string& id, TH3* hist) {
1030  return regHist_i(hist, id);
1031 }
1032 
1033 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1034 
1035 StatusCode
1037  TTree *hist(0);
1038  return regHist_i(hist, id);
1039 }
1040 
1041 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1042 
1043 StatusCode
1044 THistSvc::regTree(const std::string& id, TTree* hist) {
1045  StatusCode sc = regHist_i(hist, id);
1046  if (hist != 0 && sc.isSuccess()) {
1047  if (m_autoSave != 0)
1048  hist->SetAutoSave(m_autoSave);
1049  hist->SetAutoFlush(m_autoFlush);
1050  }
1051  return sc;
1052 }
1053 
1054 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1055 
1056 StatusCode
1058  TGraph *hist(0);
1059  return regHist_i(hist, id);
1060 }
1061 
1062 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1063 
1064 StatusCode
1065 THistSvc::regGraph(const std::string& id, TGraph* hist) {
1066  if ( strcmp(hist->GetName(),"Graph") == 0 ) {
1067 
1068  std::string id2(id);
1069  string::size_type i = id2.rfind("/");
1070  if (i != string::npos) {
1071  id2.erase(0,i+1);
1072  }
1073 
1074  m_log << MSG::INFO << "setting name of TGraph id: \"" << id << "\" to \""
1075  << id2 << "\" since it is unset" << endmsg;
1076  hist->SetName(id2.c_str());
1077  }
1078 
1079  return regHist_i(hist, id);
1080 }
1081 
1082 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1083 
1084 StatusCode
1085 THistSvc::getHist(const std::string& id, TH1*& hist) const {
1086  return getHist_i(id, hist);
1087 }
1088 
1089 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1090 
1091 StatusCode
1092 THistSvc::getHist(const std::string& id, TH2*& hist) const {
1093  return getHist_i(id, hist);
1094 }
1095 
1096 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1097 
1098 StatusCode
1099 THistSvc::getHist(const std::string& id, TH3*& hist) const {
1100  return getHist_i(id, hist);
1101 }
1102 
1103 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1104 
1107 
1109  names.reserve(m_uids.size());
1110 
1112  for (itr = m_uids.begin(); itr != m_uids.end(); ++itr) {
1113  THistID tid = itr->second;
1114 
1115  if (tid.obj->IsA()->InheritsFrom("TH1")) {
1116  names.push_back(itr->first);
1117  }
1118 
1119  }
1120 
1121  return names;
1122 
1123 }
1124 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1125 
1126 StatusCode
1127 THistSvc::getTree(const std::string& id, TTree*& hist) const {
1128  return getHist_i(id, hist);
1129 }
1130 
1131 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1132 
1135 
1137  names.reserve(m_uids.size());
1138 
1140  for (itr = m_uids.begin(); itr != m_uids.end(); ++itr) {
1141  THistID tid = itr->second;
1142 
1143  if (tid.obj->IsA()->InheritsFrom("TTree")) {
1144  names.push_back(itr->first);
1145  }
1146 
1147  }
1148 
1149  return names;
1150 
1151 }
1152 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1153 
1154 StatusCode
1155 THistSvc::getGraph(const std::string& id, TGraph*& hist) const {
1156  return getHist_i(id, hist);
1157 }
1158 
1159 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1160 
1163 
1165  names.reserve(m_uids.size());
1166 
1168  for (itr = m_uids.begin(); itr != m_uids.end(); ++itr) {
1169  THistID tid = itr->second;
1170 
1171  if (tid.obj->IsA()->InheritsFrom("TGraph")) {
1172  names.push_back(itr->first);
1173  }
1174 
1175  }
1176 
1177  return names;
1178 
1179 }
1180 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1181 
1182 StatusCode
1183 THistSvc::readHist(const std::string& id, TH1*& hist) const {
1184  return readHist_i(id, hist);
1185 }
1186 
1187 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1188 
1189 StatusCode
1190 THistSvc::readHist(const std::string& id, TH2*& hist) const {
1191  return readHist_i(id, hist);
1192 }
1193 
1194 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1195 
1196 StatusCode
1197 THistSvc::readHist(const std::string& id, TH3*& hist) const {
1198  return readHist_i(id, hist);
1199 }
1200 
1201 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1202 
1203 StatusCode
1204 THistSvc::readTree(const std::string& id, TTree*& hist) const {
1205  return readHist_i(id, hist);
1206 }
1207 
1208 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1209 
1210 bool
1211 THistSvc::findStream(const string& id, string& stream, string& rem,
1212  TFile*& file) const {
1213 
1214  string::size_type pos = id.find("/");
1215 
1216  if (pos == string::npos) {
1217  stream = "temp";
1218  rem = id;
1219  } else if (pos != 0) {
1220  stream = "temp";
1221  rem = id;
1222  } else {
1223 
1224  string::size_type pos2 = id.find("/",pos+1);
1225 
1226  if (pos2 == string::npos) {
1227  m_log << MSG::ERROR << "badly formed Hist/Tree id: \"" << id << "\""
1228  << endmsg;
1229  return false;
1230  }
1231 
1232  parseString(id,stream,rem);
1233 
1234  }
1235 
1236  if (stream == "temp") {
1237  file = 0;
1238  return true;
1239  }
1240 
1241  map< string,pair<TFile*,Mode> >::const_iterator itr = m_files.find(stream);
1242  if (itr != m_files.end()) {
1243  file = itr->second.first;
1244  } else {
1245  file = 0;
1246  m_log << MSG::WARNING << "no stream \"" << stream
1247  << "\" associated with id: \"" << id << "\""
1248  << endmsg;
1249  }
1250 
1251  return true;
1252 
1253 }
1254 
1255 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1256 
1257 void
1258 THistSvc::parseString(const string& id, string& root, string& rem) const {
1259  string::size_type pos = id.find("/");
1260 
1261  if (pos == string::npos) {
1262  root = "";
1263  rem = id;
1264  return;
1265  }
1266 
1267  if (pos == 0) {
1268  parseString(id.substr(1,id.length()),root,rem);
1269  } else {
1270  root = id.substr(0,pos);
1271  rem = id.substr(pos+1,id.length());
1272  }
1273 
1274 }
1275 
1276 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1277 
1278 void
1280 {
1281 
1282  m_log << MSG::WARNING << "\"CompressionLevel\" Property has been deprecated. "
1283  << "Set it via the \"CL=\" parameter in the \"Output\" Property"
1284  << endmsg;
1285 
1286 }
1287 
1288 
1289 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1290 
1291 void
1293 {
1294 
1296 
1297  m_log <<MSG::DEBUG << "Delaying connection of Input Files until Initialize"
1298  << ". now in " << FSMState()
1299  << endmsg;
1300 
1301  m_delayConnect = true;
1302  } else {
1303 
1304  m_log <<MSG::DEBUG << "Now connecting of Input Files"
1305  << endmsg;
1306 
1308 
1311  itr = m_inputfile.value().begin(),
1312  iEnd = m_inputfile.value().end();
1313  itr != iEnd;
1314  ++itr ) {
1315  if ( m_alreadyConnectedInFiles.end() ==
1316  m_alreadyConnectedInFiles.find( *itr ) ) {
1317  if ( connect(*itr).isFailure() ) {
1318  sc = StatusCode::FAILURE;
1319  } else {
1321  }
1322  }
1323  }
1324 
1325  if ( !sc.isSuccess() ) {
1326  throw GaudiException( "Problem connecting inputfile !!", name(),
1328  }
1329 
1330  }
1331 
1332  return;
1333 }
1334 
1335 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1336 
1337 void
1339 {
1341  m_log <<MSG::DEBUG << "Delaying connection of Input Files until Initialize"
1342  << ". now in " << FSMState()
1343  << endmsg;
1344  m_delayConnect = true;
1345  } else {
1346 
1348 
1351  itr = m_outputfile.value().begin(),
1352  iEnd = m_outputfile.value().end();
1353  itr != iEnd;
1354  ++itr ) {
1356  m_alreadyConnectedOutFiles.find( *itr ) ) {
1357  if ( connect(*itr).isFailure() ) {
1358  sc = StatusCode::FAILURE;
1359  } else {
1361  }
1362  }
1363  }
1364 
1365  if ( !sc.isSuccess() ) {
1366  throw GaudiException( "Problem connecting outputfile !!", name(),
1368  }
1369  return;
1370  }
1371 }
1372 
1373 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1374 
1375 void
1377 
1378  // If TTrees grow beyond TTree::fgMaxTreeSize, a new file is
1379  // automatically created by root, and the old one closed. We
1380  // need to migrate all the UIDs over to show the correct file
1381  // pointer. This is ugly.
1382 
1383  if (m_log.level() <= MSG::DEBUG)
1384  m_log << MSG::DEBUG << "updateFiles()" << endmsg;
1385 
1386 
1387  uidMap::iterator uitr, uitr2;
1388  for (uitr=m_uids.begin(); uitr != m_uids.end(); ++uitr) {
1389 #ifndef NDEBUG
1390  if (m_log.level() <= MSG::VERBOSE)
1391  m_log << MSG::VERBOSE << " update: " << uitr->first << " "
1392  << uitr->second.id << " " << uitr->second.mode << endmsg;
1393 #endif
1394  TObject* to = uitr->second.obj;
1395  TFile* oldFile = uitr->second.file;
1396  if (!to) {
1397  m_log << MSG::WARNING << uitr->first << ": TObject == 0" << endmsg;
1398  } else if ( uitr->second.temp || uitr->second.mode == READ ) {
1399  // do nothing - no need to check how big the file is since we
1400  // are just reading it.
1401 #ifndef NDEBUG
1402  if (m_log.level() <= MSG::VERBOSE)
1403  m_log << MSG::VERBOSE << " skipping" << endmsg;
1404 #endif
1405 
1406  } else if (to->IsA()->InheritsFrom("TTree")) {
1407  TTree* tr = dynamic_cast<TTree*>(to);
1408  TFile* newFile = tr->GetCurrentFile();
1409 
1410  if (oldFile != newFile) {
1411  std::string newFileName = newFile->GetName();
1412  std::string oldFileName(""), streamName, rem;
1413  TFile* dummy;
1414  findStream(uitr->second.id, streamName, rem, dummy);
1415 
1417  for (itr=m_files.begin(); itr!= m_files.end(); ++itr) {
1418  if (itr->second.first == oldFile) {
1419  itr->second.first = newFile;
1420 
1421  }
1422  }
1423 
1424  uitr2 = uitr;
1425  for (; uitr2 != m_uids.end(); ++uitr2) {
1426  if (uitr2->second.file == oldFile) {
1427  uitr2->second.file = newFile;
1428  }
1429  }
1430 
1431  streamMap::iterator sitr;
1432  for (sitr = m_fileStreams.begin(); sitr!=m_fileStreams.end(); ++sitr) {
1433  if (sitr->second == streamName) {
1434  oldFileName = sitr->first;
1435  break;
1436  }
1437  }
1438 
1439 
1440 #ifndef NDEBUG
1441  if (m_log.level() <= MSG::DEBUG)
1442  m_log << MSG::DEBUG << "migrating uid: " << uitr->second.id
1443  << " stream: " << streamName
1444  << " oldFile: " << oldFileName
1445  << " newFile: " << newFileName
1446  << endmsg;
1447 #endif
1448 
1449 
1450  if (oldFileName != "") {
1451  while ( (sitr=m_fileStreams.find(oldFileName)) != m_fileStreams.end() ) {
1452 
1453 #ifndef NDEBUG
1454  if (m_log.level() <= MSG::DEBUG)
1455  m_log << MSG::DEBUG << "changing filename \"" << oldFileName
1456  << "\" to \"" << newFileName << "\" for stream \""
1457  << sitr->second << "\"" << endmsg;
1458 #endif
1459  m_fileStreams.erase(sitr);
1460  m_fileStreams.insert( make_pair(newFileName,streamName) );
1461  }
1462 
1463 
1464  } else {
1465  m_log << MSG::ERROR
1466  << "Problems updating fileStreams with new file name" << endmsg;
1467  }
1468 
1469  }
1470 
1471  }
1472  }
1473 
1474 }
1475 
1476 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1477 
1478 StatusCode
1480 
1481  updateFiles();
1482 
1483  map<string, pair<TFile*,Mode> >::const_iterator itr;
1484  for (itr=m_files.begin(); itr!= m_files.end(); ++itr) {
1485  if (itr->second.second == WRITE || itr->second.second == UPDATE
1486  ||itr->second.second==SHARE) {
1487  itr->second.first->Write("",TObject::kOverwrite);
1488  } else if (itr->second.second == APPEND) {
1489  itr->second.first->Write("");
1490  }
1491  }
1492 
1493 
1494  if (m_log.level() <= MSG::DEBUG)
1495  m_log << MSG::DEBUG << "THistSvc::write()::List of Files connected in ROOT "
1496  << endmsg;
1497 
1498  TSeqCollection *filelist=gROOT->GetListOfFiles();
1499  for (int ii=0; ii<filelist->GetEntries(); ii++) {
1500  if (m_log.level() <= MSG::DEBUG)
1501  m_log << MSG::DEBUG
1502  << "THistSvc::write()::List of Files connected in ROOT: \""
1503  << filelist->At(ii)->GetName()<<"\""<<endmsg;
1504  }
1505 
1506  return StatusCode::SUCCESS;
1507 
1508 }
1509 
1510 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1511 
1512 StatusCode
1514 
1515  Tokenizer tok(true);
1516 
1517  string::size_type loc = ident.find(" ");
1518  string stream = ident.substr(0,loc);
1519  char typ(0);
1521  std::vector<Prop> props;
1522  string val,VAL,TAG,filename,db_typ("ROOT");
1523  int cl(1);
1524 
1525  tok.analyse(ident.substr(loc+1,ident.length()), " ", "", "", "=", "'", "'");
1526 
1527  for ( Tokenizer::Items::iterator i = tok.items().begin(); i != tok.items().end(); i++) {
1528  const std::string& tag = (*i).tag();
1529  TAG = tag;
1530  toupper(TAG);
1531 
1532  val = (*i).value();
1533  VAL = val;
1534  toupper(VAL);
1535 
1536  if (TAG == "FILE" || TAG == "DATAFILE") {
1537  filename = val;
1538  removeDoubleSlash( filename );
1539  } else if ( TAG == "OPT" ) {
1540  if ( VAL == "APPEND" || VAL == "UPDATE" ) {
1541  typ = 'A';
1542  } else if ( VAL == "CREATE" || VAL == "NEW" || VAL == "WRITE" ) {
1543  typ = 'N';
1544  } else if ( VAL == "RECREATE" ) {
1545  typ = 'R';
1546  } else if (VAL == "SHARE") {
1547  typ = 'S';
1548  } else if ( VAL == "OLD" || VAL == "READ" ) {
1549  typ = 'O';
1550  } else {
1551  m_log << MSG::ERROR << "Unknown OPT: \"" << (*i).value() << "\""
1552  << endmsg;
1553  typ = 0;
1554  }
1555  } else if (TAG == "TYP") {
1556  db_typ = (*i).value();
1557  } else if (TAG == "CL") {
1558  cl = atoi(val.c_str());
1559  } else {
1560  props.push_back( Prop((*i).tag(), (*i).value()));
1561  }
1562 
1563  }
1564 
1565  if (stream == "temp") {
1566  m_log << MSG::ERROR << "in JobOption \"" << ident
1567  << "\": stream name \"temp\" reserved."
1568  << endmsg;
1569  return StatusCode::FAILURE;
1570  }
1571 
1572  if (db_typ != "ROOT") {
1573  m_log << MSG::ERROR << "in JobOption \"" << ident
1574  << "\": technology type \"" << db_typ << "\" not supported."
1575  << endmsg;
1576  return StatusCode::FAILURE;
1577  }
1578 
1579 
1580  if (m_files.find(stream) != m_files.end()) {
1581  m_log << MSG::ERROR << "in JobOption \"" << ident
1582  << "\":\n stream \"" << stream << "\" already connected to file: \""
1583  << m_files[stream].first->GetName() << "\""
1584  << endmsg;
1585  return StatusCode::FAILURE;
1586  }
1587 
1588  Mode newMode;
1589  if (typ == 'O') {
1590  newMode = THistSvc::READ;
1591  } else if (typ == 'N') {
1592  newMode = THistSvc::WRITE;
1593  } else if (typ == 'A') {
1594  newMode = THistSvc::APPEND;
1595  } else if (typ == 'R') {
1596  newMode = THistSvc::UPDATE;
1597  } else if (typ == 'S') {
1598  newMode = THistSvc::SHARE;
1599  } else {
1600  // something else?
1601  m_log << MSG::ERROR << "No OPT= specified or unknown access mode in: "
1602  << ident << endmsg;
1603  return StatusCode::FAILURE;
1604  }
1605 
1606  // Is this file already connected to another stream?
1607  if (m_fileStreams.find(filename) != m_fileStreams.end()) {
1609  m_fileStreams.equal_range(filename);
1610 
1611  std::string oldstream = (fitr.first)->second;
1612 
1613  std::pair<TFile*,Mode> f_info = m_files[oldstream];
1614 
1615  if (newMode != f_info.second) {
1616  m_log << MSG::ERROR << "in JobOption \"" << ident
1617  << "\":\n file \"" << filename << "\" already opened by stream: \""
1618  << oldstream << "\" with different access mode."
1619  << endmsg;
1620  return StatusCode::FAILURE;
1621  } else {
1622  TFile *f2 = f_info.first;
1623  m_files[stream] = make_pair(f2,newMode);
1624  if (m_log.level() <= MSG::DEBUG)
1625  m_log << MSG::DEBUG << "Connecting stream: \"" << stream
1626  << "\" to previously opened TFile: \"" << filename << "\""
1627  << endmsg;
1628  return StatusCode::SUCCESS;
1629  }
1630  }
1631 
1632 
1633  IIncidentSvc *pi(0);
1634  if (service("IncidentSvc",pi).isFailure()) {
1635  m_log << MSG::ERROR << "Unable to get the IncidentSvc" << endmsg;
1636  return StatusCode::FAILURE;
1637  }
1638 
1639  void* vf(0);
1640  TFile *f(0);
1641 
1642  if (newMode == THistSvc::READ) {
1643  // old file
1644 
1645  int r = p_fileMgr->open(Io::ROOT,name(), filename,Io::READ,vf,"HIST");
1646 
1647  if (r != 0) {
1648  m_log << "Unable to open ROOT file " << filename << " for reading"
1649  << endmsg;
1650  return StatusCode::FAILURE;
1651  }
1652 
1653 
1654  f = (TFile*) vf;
1655 
1656  // FIX ME!
1657  pi->fireIncident(FileIncident(name(), "BeginHistFile",
1658  filename));
1659 
1660 
1661  } else if (newMode == THistSvc::WRITE) {
1662  // new file. error if file exists
1663 
1664  int r = p_fileMgr->open(Io::ROOT,name(),filename, (Io::WRITE|Io::CREATE|Io::EXCL),
1665  vf,"HIST");
1666 
1667  if (r != 0) {
1668  m_log << "Unable to open ROOT file " << filename << " for writing"
1669  << endmsg;
1670  return StatusCode::FAILURE;
1671  }
1672 
1673  f = (TFile*)vf;
1674 
1675  } else if (newMode == THistSvc::APPEND) {
1676  // update file
1677 
1678  int r = p_fileMgr->open(Io::ROOT,name(),filename, (Io::WRITE | Io::APPEND),
1679  vf,"HIST");
1680  if (r != 0) {
1681  m_log << MSG::ERROR << "unable to open file \"" << filename
1682  << "\" for appending" << endmsg;
1683  return StatusCode::FAILURE;
1684  }
1685 
1686  f = (TFile*) vf;
1687 
1688 
1689  } else if (newMode == THistSvc::SHARE) {
1690  // SHARE file type
1691  //For SHARE files, all data will be stored in a temp file and will be merged into the target file
1692  //in write() when finalize(), this help to solve some confliction. e.g. with storegate
1693 
1694  static int ishared = 0;
1695  stringstream out;
1696  string realfilename=filename;
1697  out << ishared++;
1698  filename = string("tmp_THistSvc_")+out.str()+string(".root");
1699 
1700  if (m_log.level() <= MSG::DEBUG)
1701  m_log << MSG::DEBUG << "Creating temp file \"" << filename
1702  << "\" and realfilename="<<realfilename << endmsg;
1703  m_sharedFiles[stream]=realfilename;
1704 
1705 
1706  int r = p_fileMgr->open(Io::ROOT,name(), filename, (Io::WRITE|Io::CREATE|Io::EXCL),
1707  vf,"HIST");
1708 
1709  if (r != 0) {
1710  m_log << "Unable to open ROOT file " << filename << " for writing"
1711  << endmsg;
1712  return StatusCode::FAILURE;
1713  }
1714 
1715  f = (TFile*)vf;
1716 
1717  } else if (newMode == THistSvc::UPDATE) {
1718  // update file
1719 
1720  int r = p_fileMgr->open(Io::ROOT,name(), filename, (Io::WRITE|Io::CREATE),
1721  vf, "HIST");
1722 
1723  if (r != 0) {
1724  m_log << "Unable to open ROOT file " << filename << " for appending"
1725  << endmsg;
1726  return StatusCode::FAILURE;
1727  }
1728 
1729  f = (TFile*)vf;
1730 
1731  }
1732 
1733  m_files[stream] = make_pair(f,newMode);
1734  m_fileStreams.insert(make_pair(filename,stream));
1735 
1736  if (m_log.level() <= MSG::DEBUG)
1737  m_log << MSG::DEBUG << "Opening TFile \"" << filename << "\" stream: \""
1738  << stream << "\" mode: \"" << typ << "\"" << " comp level: " << cl
1739  << endmsg;
1740 
1741  return StatusCode::SUCCESS;
1742 }
1743 
1744 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1745 
1746 TDirectory*
1748 
1749  string uid = hid.id;
1750  TFile* file = hid.file;
1751  string stream, fdir, bdir, dir, id;
1752 
1753  if (file != 0) {
1754  file->cd("/");
1755  } else {
1756  gROOT->cd();
1757  }
1758 
1759  fdir = uid;
1760  bdir = dirname(fdir);
1761 
1762  while ( (dir = dirname(fdir)) != "") {
1763  if (! gDirectory->GetKey(dir.c_str())) {
1764  gDirectory->mkdir(dir.c_str());
1765  }
1766  gDirectory->cd(dir.c_str());
1767  }
1768 
1769  return gDirectory;
1770 
1771 }
1772 
1773 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1774 
1777 
1778 
1779  string::size_type i = dir.find("/");
1780 
1781  if (i == string::npos) {
1782  return "";
1783  }
1784 
1785  if ( i == 0 ) {
1786  dir.erase(0,1);
1787  return dirname(dir);
1788  }
1789 
1790  string root = dir.substr(0,i);
1791  dir.erase(0,i);
1792 
1793  return root;
1794 
1795 }
1796 
1797 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1798 
1800  m_gd = gDirectory;
1801  m_gf = gFile;
1802  m_ge = gErrorIgnoreLevel;
1803 }
1804 
1806  gDirectory = m_gd;
1807  gFile = m_gf;
1808  gErrorIgnoreLevel = m_ge;
1809 }
1810 
1811 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1812 
1813 void
1815 
1816  while (id.find("//") != std::string::npos) {
1817  id.replace(id.find("//"),2,"/");
1818  }
1819 
1820 }
1821 
1822 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1823 
1824 void THistSvc::MergeRootFile(TDirectory *target, TDirectory *source) {
1825 
1826  if (m_log.level() <= MSG::DEBUG)
1827  m_log <<MSG::DEBUG << "Target path: " << target->GetPath() << endmsg;
1828  TString path( (char*)strstr(target->GetPath(), ":") );
1829  path.Remove( 0, 2);
1830 
1831  source->cd(path);
1832  TDirectory *current_sourcedir = gDirectory;
1833 
1834  // loop over all keys in this directory
1835  TList *lkeys=current_sourcedir->GetListOfKeys();
1836  int nkeys=lkeys->GetEntries();
1837  TKey *key;
1838  for (int jj=0; jj<nkeys; jj++) {
1839  key=(TKey*) lkeys->At(jj);
1840  string pathnameinsource=current_sourcedir->GetPath()+string("/")+key->GetName();
1841  if (m_log.level() <= MSG::DEBUG)
1842  m_log <<MSG::DEBUG << "Reading Key:" << pathnameinsource << endmsg;
1843  //key->Dump();
1844  //TObject *obj=key->ReadObj();
1845  TObject *obj=source->Get(pathnameinsource.c_str());
1846 
1847  if (obj) {
1848  if (obj->IsA()->InheritsFrom("TDirectory") ) {
1849  // it's a subdirectory
1850 
1851  if (m_log.level() <= MSG::DEBUG)
1852  m_log <<MSG::DEBUG << "Found subdirectory " << obj->GetName()
1853  << endmsg;
1854 
1855  // create a new subdir of same name and title in the target file
1856  target->cd();
1857  TDirectory *newtargetdir =
1858  target->mkdir(obj->GetName(), obj->GetTitle() );
1859 
1860  MergeRootFile(newtargetdir, source);
1861 
1862  } else if (obj->IsA()->InheritsFrom("TTree")) {
1863  if (m_log.level() <= MSG::DEBUG)
1864  m_log <<MSG::DEBUG << "Found TTree " << obj->GetName() << endmsg;
1865  TTree *mytree=dynamic_cast<TTree*>(obj);
1866  int nentries=(int) mytree->GetEntries();
1867  mytree->SetBranchStatus("*",1);
1868 
1869  if (m_log.level() <= MSG::DEBUG)
1870  m_log <<MSG::DEBUG << "Dumping TTree " << nentries <<" entries"
1871  << endmsg;
1872  //mytree->Print();
1873  //for (int ij=0; ij<nentries; ij++) {
1874  //m_log <<MSG::DEBUG << "Dumping TTree Show( " << ij <<" )"
1875  //<< endmsg;
1876  //mytree->Show(ij);
1877  //}
1878  target->cd();
1879  mytree->CloneTree();
1880 
1881  //m_log <<MSG::DEBUG << "Writing TTree to target file: ( "
1882  //<< mycopiedtree->Write(key->GetName()) <<" ) bytes written"
1883  //<< endmsg;
1884 
1885  } else {
1886  target->cd();
1887  obj->Write(key->GetName() );
1888  }
1889  }
1890 
1891  } // while ( ( TKey *key = (TKey*)nextkey() ) )
1892 
1893  // save modifications to target file
1894 
1895 }
1896 
1897 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1898 
1899 bool
1901 
1902  TH1* h;
1903 
1904  return getHist_i(name,h,true).isSuccess();
1905 
1906 
1907 }
1908 
1909 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1910 
1911 void
1912 THistSvc::handle( const Incident& /* inc */ ) {
1913 
1914  if (signaledStop) return ;
1915 
1916  if (m_maxFileSize.value() == -1) {
1917  return;
1918  }
1919 
1920  // convert to bytes.
1921  Long64_t mfs = (Long64_t)m_maxFileSize.value() * (Long64_t)1048576;
1922  Long64_t mfs_warn = mfs * 95 / 100;
1923 
1924  updateFiles();
1925 
1926  map<string, pair<TFile*,Mode> >::const_iterator itr;
1927  for (itr=m_files.begin(); itr!= m_files.end(); ++itr) {
1928  TFile* tf = itr->second.first;
1929 
1930 #ifndef NDEBUG
1931  if (m_log.level() <= MSG::DEBUG)
1932  m_log << MSG::DEBUG << "stream: " << itr->first << " name: "
1933  << tf->GetName() << " size: " << tf->GetSize()
1934  << endmsg;
1935 #endif
1936 
1937  // Signal job to terminate if output file is too large
1938  if (tf->GetSize() > mfs) {
1939 
1940  signaledStop = true;
1941 
1942  m_log << MSG::FATAL << "file \"" << tf->GetName()
1943  << "\" associated with stream \"" << itr->first
1944  << "\" has exceeded the max file size of "
1945  << m_maxFileSize.value() << "MB. Terminating Job."
1946  << endmsg;
1947 
1948  IEventProcessor* evt(0);
1949  if (service("ApplicationMgr", evt, true).isSuccess()) {
1950  evt->stopRun();
1951  evt->release();
1952  } else {
1953  abort();
1954  }
1955  } else if (tf->GetSize() > mfs_warn) {
1956  m_log << MSG::WARNING << "file \"" << tf->GetName()
1957  << "\" associated with stream \"" << itr->first
1958  << "\" is at 95% of its maximum allowable file size of "
1959  << m_maxFileSize.value() << "MB"
1960  << endmsg;
1961  }
1962  }
1963 }
1964 
1965 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1966 
1969 void
1970 THistSvc::copyFileLayout (TDirectory *dst, TDirectory *src) {
1971 
1972  if (m_log.level() <= MSG::DEBUG)
1973  m_log << MSG::DEBUG
1974  << "copyFileLayout() to dst path: " << dst->GetPath () << endmsg;
1975 
1976  // strip out URLs
1977  TString path ((char*)strstr (dst->GetPath(), ":"));
1978  path.Remove (0, 2);
1979 
1980  src->cd (path);
1981  TDirectory *cur_src_dir = gDirectory;
1982 
1983  // loop over all keys in this directory
1984  TList *key_list = cur_src_dir->GetListOfKeys ();
1985  int n = key_list->GetEntries ();
1986  for ( int j = 0; j < n; ++j ) {
1987  TKey *k = (TKey*)key_list->At (j);
1988  const std::string src_pathname = cur_src_dir->GetPath()
1989  + std::string("/")
1990  + k->GetName();
1991  TObject *o=src->Get (src_pathname.c_str());
1992 
1993  if (o != NULL && o->IsA()->InheritsFrom ("TDirectory")) {
1994  if (m_log.level() <= MSG::VERBOSE)
1995  m_log << MSG::VERBOSE << " subdir [" << o->GetName() << "]..."
1996  << endmsg;
1997  dst->cd ();
1998  TDirectory * dst_dir = dst->mkdir (o->GetName(), o->GetTitle());
1999  copyFileLayout (dst_dir, src);
2000  }
2001  } // loop over keys
2002  return;
2003 }
2004 
2005 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
2009 StatusCode
2011 {
2012  bool all_good = true;
2013  if (m_log.level() <= MSG::DEBUG)
2014  m_log << MSG::DEBUG << "reinitializing I/O..." << endmsg;
2015 
2016  // retrieve the I/O component manager...
2017 
2018  IIoComponentMgr* iomgr(0);
2019 
2020  if (service("IoComponentMgr", iomgr, true).isFailure()) {
2021  m_log << MSG::ERROR << "could not retrieve I/O component manager !"
2022  << endmsg;
2023  return StatusCode::FAILURE;
2024  }
2025 
2026  GlobalDirectoryRestore restore;
2027  // to hide the expected errors upon closing the files whose
2028  // file descriptors have been swept under the rug...
2029  gErrorIgnoreLevel = kFatal;
2030 
2032 
2033  for (FileReg_t::iterator ifile = m_files.begin(), iend=m_files.end();
2034  ifile != iend; ++ifile) {
2035  TFile *f = ifile->second.first;
2036  std::string fname = f->GetName();
2037  if (m_log.level() <= MSG::DEBUG)
2038  m_log << MSG::DEBUG << "file [" << fname << "] mode: ["
2039  << f->GetOption() << "] r:"
2040  << f->GetFileBytesRead()
2041  << " w:" << f->GetFileBytesWritten()
2042  << " cnt:" << f->GetFileCounter()
2043  << endmsg;
2044 
2045  if ( ifile->second.second == READ ) {
2046  if (m_log.level() <= MSG::DEBUG)
2047  m_log << MSG::DEBUG
2048  << " TFile opened in READ mode: not reassigning names" << endmsg;
2049  continue;
2050  }
2051 
2052  if ( !iomgr->io_retrieve (this, fname).isSuccess () ) {
2053  m_log << MSG::ERROR << "could not retrieve new name for [" << fname
2054  << "] !!" << endmsg;
2055  all_good = false;
2056  continue;
2057  } else {
2058  if (m_log.level() <= MSG::DEBUG)
2059  m_log << MSG::DEBUG << "got a new name [" << fname << "]..." << endmsg;
2060  }
2061  // create a new TFile
2062  // TFile *newfile = TFile::Open (fname.c_str(), f->GetOption());
2063 
2064  void* vf;
2065  Option_t *opts = f->GetOption();
2066  int r = p_fileMgr->open(Io::ROOT,name(),fname,Io::WRITE,vf,"HIST");
2067  if (r != 0) {
2068  m_log << MSG::ERROR << "unable to open file \"" << fname
2069  << "\" for writing" << endmsg;
2070  return StatusCode::FAILURE;
2071  }
2072  TFile *newfile = (TFile*) vf;
2073  newfile->SetOption(opts);
2074 
2075 
2076  if (ifile->second.second != THistSvc::READ) {
2077  copyFileLayout (newfile, f);
2078  ifile->second.first = newfile;
2079  }
2080 
2081  // loop over all uids and migrate them to the new file
2082  // XXX FIXME: this double loop sucks...
2083  for ( uidMap::iterator uid = m_uids.begin(), uid_end = m_uids.end();
2084  uid != uid_end;
2085  ++uid ) {
2086  THistID& hid = uid->second;
2087  if ( hid.file != f ) {
2088  continue;
2089  }
2090  TDirectory *olddir = this->changeDir (hid);
2091  hid.file = newfile;
2092  // side-effect: create needed directories...
2093  TDirectory *newdir = this->changeDir (hid);
2094  TClass *cl = hid.obj->IsA();
2095 
2096  // migrate the objects to the new file.
2097  // thanks to the object model of ROOT, it is super easy.
2098  if (cl->InheritsFrom ("TTree")) {
2099  dynamic_cast<TTree*> (hid.obj)->SetDirectory (newdir);
2100  dynamic_cast<TTree*> (hid.obj)->Reset();
2101  }
2102  else if (cl->InheritsFrom ("TH1")) {
2103  dynamic_cast<TH1*> (hid.obj)->SetDirectory (newdir);
2104  dynamic_cast<TH1*> (hid.obj)->Reset();
2105  }
2106  else if (cl->InheritsFrom ("TGraph")) {
2107  olddir->Remove (hid.obj);
2108  newdir->Append (hid.obj);
2109  } else {
2110  m_log << MSG::ERROR
2111  << "id: \"" << hid.id << "\" is not a inheriting from a class "
2112  << "we know how to handle (received [" << cl->GetName()
2113  << "], " << "expected [TTree, TH1 or TGraph]) !"
2114  << endmsg
2115  << "attaching to current dir [" << newdir->GetPath() << "] "
2116  << "nonetheless..." << endmsg;
2117  olddir->Remove (hid.obj);
2118  newdir->Append (hid.obj);
2119  }
2120  }
2121  f->ReOpen ("READ");
2122  p_fileMgr->close(f,name());
2123  f = newfile;
2124  }
2125 
2126  return all_good ? StatusCode::SUCCESS : StatusCode::FAILURE;
2127 }
2128 
2129 
2130 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
2131 
2132 StatusCode
2134 
2135  if (fa->tech() != Io::ROOT) {
2136  // This should never happen
2137  return StatusCode::SUCCESS;
2138  }
2139 
2140  if (fa->desc() != "HIST") {
2141  return StatusCode::SUCCESS;
2142  }
2143 
2144  p_incSvc->fireIncident(FileIncident(caller, "OpenHistFile", fa->name()));
2145 
2146  if ( fa->flags().isRead() ) {
2147  p_incSvc->fireIncident(FileIncident(caller, "BeginHistFile", fa->name()));
2148  } else if ( fa->flags().isWrite() ) {
2150  fa->name()));
2151  } else {
2152  // for Io::RW
2154  fa->name()));
2155  }
2156 
2157  return StatusCode::SUCCESS;
2158 
2159 
2160 }
2161 
2162 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
2163 
2164 StatusCode
2166 
2167  if (fa->tech() != Io::ROOT) {
2168  // This should never happen
2169  return StatusCode::SUCCESS;
2170  }
2171 
2172  if (fa->desc() != "HIST") {
2173  return StatusCode::SUCCESS;
2174  }
2175 
2176  if ( fa->flags().isRead() ) {
2178  fa->name()));
2179  } else if ( fa->flags().isWrite() ) {
2181  fa->name()));
2182  } else {
2183  // for Io::RW
2184  p_incSvc->fireIncident(FileIncident(caller, "FailRWFile", fa->name()));
2185  }
2186 
2187 
2188  return StatusCode::SUCCESS;
2189 
2190 
2191 }

Generated at Wed Dec 4 2013 14:33:11 for Gaudi Framework, version v24r2 by Doxygen version 1.8.2 written by Dimitri van Heesch, © 1997-2004