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