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 
9 #include "GaudiKernel/ISvcLocator.h"
10 #include "GaudiKernel/AttribStringParser.h"
11 #include "GaudiKernel/GaudiException.h"
12 #include "GaudiKernel/Property.h"
13 #include "GaudiKernel/IIncidentSvc.h"
14 #include "GaudiKernel/FileIncident.h"
15 #include "GaudiKernel/IEventProcessor.h"
16 #include "GaudiKernel/IJobOptionsSvc.h"
17 #include "GaudiKernel/IIoComponentMgr.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  string::size_type loc = ident.find(" ");
1515  string stream = ident.substr(0,loc);
1516  char typ(0);
1517  typedef std::pair<std::string,std::string> Prop;
1518  std::vector<Prop> props;
1519  string filename, db_typ("ROOT");
1520  int cl(1);
1521 
1522  if (loc != string::npos) {
1523  using Parser = Gaudi::Utils::AttribStringParser;
1524  for (auto attrib: Parser(ident.substr(loc + 1))) {
1525  auto TAG = attrib.tag;
1526  toupper(TAG);
1527 
1528  auto VAL = attrib.value;
1529  toupper(VAL);
1530 
1531  if (TAG == "FILE" || TAG == "DATAFILE") {
1532  filename = attrib.value;
1533  removeDoubleSlash( filename );
1534  } else if ( TAG == "OPT" ) {
1535  if ( VAL == "APPEND" || VAL == "UPDATE" ) {
1536  typ = 'A';
1537  } else if ( VAL == "CREATE" || VAL == "NEW" || VAL == "WRITE" ) {
1538  typ = 'N';
1539  } else if ( VAL == "RECREATE" ) {
1540  typ = 'R';
1541  } else if (VAL == "SHARE") {
1542  typ = 'S';
1543  } else if ( VAL == "OLD" || VAL == "READ" ) {
1544  typ = 'O';
1545  } else {
1546  m_log << MSG::ERROR << "Unknown OPT: \"" << attrib.value << "\""
1547  << endmsg;
1548  typ = 0;
1549  }
1550  } else if (TAG == "TYP") {
1551  db_typ = std::move(attrib.value);
1552  } else if (TAG == "CL") {
1553  cl = atoi(attrib.value.c_str());
1554  } else {
1555  props.push_back( Prop(attrib.tag, attrib.value));
1556  }
1557 
1558  }
1559  }
1560 
1561  if (stream == "temp") {
1562  m_log << MSG::ERROR << "in JobOption \"" << ident
1563  << "\": stream name \"temp\" reserved."
1564  << endmsg;
1565  return StatusCode::FAILURE;
1566  }
1567 
1568  if (db_typ != "ROOT") {
1569  m_log << MSG::ERROR << "in JobOption \"" << ident
1570  << "\": technology type \"" << db_typ << "\" not supported."
1571  << endmsg;
1572  return StatusCode::FAILURE;
1573  }
1574 
1575 
1576  if (m_files.find(stream) != m_files.end()) {
1577  m_log << MSG::ERROR << "in JobOption \"" << ident
1578  << "\":\n stream \"" << stream << "\" already connected to file: \""
1579  << m_files[stream].first->GetName() << "\""
1580  << endmsg;
1581  return StatusCode::FAILURE;
1582  }
1583 
1584  Mode newMode;
1585  if (typ == 'O') {
1586  newMode = THistSvc::READ;
1587  } else if (typ == 'N') {
1588  newMode = THistSvc::WRITE;
1589  } else if (typ == 'A') {
1590  newMode = THistSvc::APPEND;
1591  } else if (typ == 'R') {
1592  newMode = THistSvc::UPDATE;
1593  } else if (typ == 'S') {
1594  newMode = THistSvc::SHARE;
1595  } else {
1596  // something else?
1597  m_log << MSG::ERROR << "No OPT= specified or unknown access mode in: "
1598  << ident << endmsg;
1599  return StatusCode::FAILURE;
1600  }
1601 
1602  // Is this file already connected to another stream?
1603  if (m_fileStreams.find(filename) != m_fileStreams.end()) {
1604  std::pair<streamMap::iterator, streamMap::iterator> fitr =
1605  m_fileStreams.equal_range(filename);
1606 
1607  std::string oldstream = (fitr.first)->second;
1608 
1609  std::pair<TFile*,Mode> f_info = m_files[oldstream];
1610 
1611  if (newMode != f_info.second) {
1612  m_log << MSG::ERROR << "in JobOption \"" << ident
1613  << "\":\n file \"" << filename << "\" already opened by stream: \""
1614  << oldstream << "\" with different access mode."
1615  << endmsg;
1616  return StatusCode::FAILURE;
1617  } else {
1618  TFile *f2 = f_info.first;
1619  m_files[stream] = make_pair(f2,newMode);
1620  if (m_log.level() <= MSG::DEBUG)
1621  m_log << MSG::DEBUG << "Connecting stream: \"" << stream
1622  << "\" to previously opened TFile: \"" << filename << "\""
1623  << endmsg;
1624  return StatusCode::SUCCESS;
1625  }
1626  }
1627 
1628 
1629  IIncidentSvc *pi(0);
1630  if (service("IncidentSvc",pi).isFailure()) {
1631  m_log << MSG::ERROR << "Unable to get the IncidentSvc" << endmsg;
1632  return StatusCode::FAILURE;
1633  }
1634 
1635  void* vf(0);
1636  TFile *f(0);
1637 
1638  if (newMode == THistSvc::READ) {
1639  // old file
1640 
1641  int r = p_fileMgr->open(Io::ROOT,name(), filename,Io::READ,vf,"HIST");
1642 
1643  if (r != 0) {
1644  m_log << "Unable to open ROOT file " << filename << " for reading"
1645  << endmsg;
1646  return StatusCode::FAILURE;
1647  }
1648 
1649 
1650  f = (TFile*) vf;
1651 
1652  // FIX ME!
1653  pi->fireIncident(FileIncident(name(), "BeginHistFile",
1654  filename));
1655 
1656 
1657  } else if (newMode == THistSvc::WRITE) {
1658  // new file. error if file exists
1659 
1660  int r = p_fileMgr->open(Io::ROOT,name(),filename, (Io::WRITE|Io::CREATE|Io::EXCL),
1661  vf,"HIST");
1662 
1663  if (r != 0) {
1664  m_log << "Unable to open ROOT file " << filename << " for writing"
1665  << endmsg;
1666  return StatusCode::FAILURE;
1667  }
1668 
1669  f = (TFile*)vf;
1670 
1671  } else if (newMode == THistSvc::APPEND) {
1672  // update file
1673 
1674  int r = p_fileMgr->open(Io::ROOT,name(),filename, (Io::WRITE | Io::APPEND),
1675  vf,"HIST");
1676  if (r != 0) {
1677  m_log << MSG::ERROR << "unable to open file \"" << filename
1678  << "\" for appending" << endmsg;
1679  return StatusCode::FAILURE;
1680  }
1681 
1682  f = (TFile*) vf;
1683 
1684 
1685  } else if (newMode == THistSvc::SHARE) {
1686  // SHARE file type
1687  //For SHARE files, all data will be stored in a temp file and will be merged into the target file
1688  //in write() when finalize(), this help to solve some confliction. e.g. with storegate
1689 
1690  static int ishared = 0;
1691  stringstream out;
1692  string realfilename=filename;
1693  out << ishared++;
1694  filename = string("tmp_THistSvc_")+out.str()+string(".root");
1695 
1696  if (m_log.level() <= MSG::DEBUG)
1697  m_log << MSG::DEBUG << "Creating temp file \"" << filename
1698  << "\" and realfilename="<<realfilename << endmsg;
1699  m_sharedFiles[stream]=realfilename;
1700 
1701 
1702  int r = p_fileMgr->open(Io::ROOT,name(), filename, (Io::WRITE|Io::CREATE|Io::EXCL),
1703  vf,"HIST");
1704 
1705  if (r != 0) {
1706  m_log << "Unable to open ROOT file " << filename << " for writing"
1707  << endmsg;
1708  return StatusCode::FAILURE;
1709  }
1710 
1711  f = (TFile*)vf;
1712 
1713  } else if (newMode == THistSvc::UPDATE) {
1714  // update file
1715 
1716  int r = p_fileMgr->open(Io::ROOT,name(), filename, (Io::WRITE|Io::CREATE),
1717  vf, "HIST");
1718 
1719  if (r != 0) {
1720  m_log << "Unable to open ROOT file " << filename << " for appending"
1721  << endmsg;
1722  return StatusCode::FAILURE;
1723  }
1724 
1725  f = (TFile*)vf;
1726 
1727  }
1728 
1729  m_files[stream] = make_pair(f,newMode);
1730  m_fileStreams.insert(make_pair(filename,stream));
1731 
1732  if (m_log.level() <= MSG::DEBUG)
1733  m_log << MSG::DEBUG << "Opening TFile \"" << filename << "\" stream: \""
1734  << stream << "\" mode: \"" << typ << "\"" << " comp level: " << cl
1735  << endmsg;
1736 
1737  return StatusCode::SUCCESS;
1738 }
1739 
1740 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1741 
1742 TDirectory*
1744 
1745  string uid = hid.id;
1746  TFile* file = hid.file;
1747  string stream, fdir, bdir, dir, id;
1748 
1749  if (file != 0) {
1750  file->cd("/");
1751  } else {
1752  gROOT->cd();
1753  }
1754 
1755  fdir = uid;
1756  bdir = dirname(fdir);
1757 
1758  while ( (dir = dirname(fdir)) != "") {
1759  if (! gDirectory->GetKey(dir.c_str())) {
1760  gDirectory->mkdir(dir.c_str());
1761  }
1762  gDirectory->cd(dir.c_str());
1763  }
1764 
1765  return gDirectory;
1766 
1767 }
1768 
1769 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1770 
1771 std::string
1772 THistSvc::dirname(std::string& dir) const {
1773 
1774 
1775  string::size_type i = dir.find("/");
1776 
1777  if (i == string::npos) {
1778  return "";
1779  }
1780 
1781  if ( i == 0 ) {
1782  dir.erase(0,1);
1783  return dirname(dir);
1784  }
1785 
1786  string root = dir.substr(0,i);
1787  dir.erase(0,i);
1788 
1789  return root;
1790 
1791 }
1792 
1793 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1794 
1796  m_gd = gDirectory;
1797  m_gf = gFile;
1798  m_ge = gErrorIgnoreLevel;
1799 }
1800 
1802  gDirectory = m_gd;
1803  gFile = m_gf;
1804  gErrorIgnoreLevel = m_ge;
1805 }
1806 
1807 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1808 
1809 void
1810 THistSvc::removeDoubleSlash(std::string& id) const {
1811 
1812  while (id.find("//") != std::string::npos) {
1813  id.replace(id.find("//"),2,"/");
1814  }
1815 
1816 }
1817 
1818 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1819 
1820 void THistSvc::MergeRootFile(TDirectory *target, TDirectory *source) {
1821 
1822  if (m_log.level() <= MSG::DEBUG)
1823  m_log <<MSG::DEBUG << "Target path: " << target->GetPath() << endmsg;
1824  TString path( (char*)strstr(target->GetPath(), ":") );
1825  path.Remove( 0, 2);
1826 
1827  source->cd(path);
1828  TDirectory *current_sourcedir = gDirectory;
1829 
1830  // loop over all keys in this directory
1831  TList *lkeys=current_sourcedir->GetListOfKeys();
1832  int nkeys=lkeys->GetEntries();
1833  TKey *key;
1834  for (int jj=0; jj<nkeys; jj++) {
1835  key=(TKey*) lkeys->At(jj);
1836  string pathnameinsource=current_sourcedir->GetPath()+string("/")+key->GetName();
1837  if (m_log.level() <= MSG::DEBUG)
1838  m_log <<MSG::DEBUG << "Reading Key:" << pathnameinsource << endmsg;
1839  //key->Dump();
1840  //TObject *obj=key->ReadObj();
1841  TObject *obj=source->Get(pathnameinsource.c_str());
1842 
1843  if (obj) {
1844  if (obj->IsA()->InheritsFrom("TDirectory") ) {
1845  // it's a subdirectory
1846 
1847  if (m_log.level() <= MSG::DEBUG)
1848  m_log <<MSG::DEBUG << "Found subdirectory " << obj->GetName()
1849  << endmsg;
1850 
1851  // create a new subdir of same name and title in the target file
1852  target->cd();
1853  TDirectory *newtargetdir =
1854  target->mkdir(obj->GetName(), obj->GetTitle() );
1855 
1856  MergeRootFile(newtargetdir, source);
1857 
1858  } else if (obj->IsA()->InheritsFrom("TTree")) {
1859  if (m_log.level() <= MSG::DEBUG)
1860  m_log <<MSG::DEBUG << "Found TTree " << obj->GetName() << endmsg;
1861  TTree *mytree=dynamic_cast<TTree*>(obj);
1862  int nentries=(int) mytree->GetEntries();
1863  mytree->SetBranchStatus("*",1);
1864 
1865  if (m_log.level() <= MSG::DEBUG)
1866  m_log <<MSG::DEBUG << "Dumping TTree " << nentries <<" entries"
1867  << endmsg;
1868  //mytree->Print();
1869  //for (int ij=0; ij<nentries; ij++) {
1870  //m_log <<MSG::DEBUG << "Dumping TTree Show( " << ij <<" )"
1871  //<< endmsg;
1872  //mytree->Show(ij);
1873  //}
1874  target->cd();
1875  mytree->CloneTree();
1876 
1877  //m_log <<MSG::DEBUG << "Writing TTree to target file: ( "
1878  //<< mycopiedtree->Write(key->GetName()) <<" ) bytes written"
1879  //<< endmsg;
1880 
1881  } else {
1882  target->cd();
1883  obj->Write(key->GetName() );
1884  }
1885  }
1886 
1887  } // while ( ( TKey *key = (TKey*)nextkey() ) )
1888 
1889  // save modifications to target file
1890 
1891 }
1892 
1893 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1894 
1895 bool
1896 THistSvc::exists( const std::string& name ) const {
1897 
1898  TH1* h;
1899 
1900  return getHist_i(name,h,true).isSuccess();
1901 
1902 
1903 }
1904 
1905 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1906 
1907 void
1908 THistSvc::handle( const Incident& /* inc */ ) {
1909 
1910  if (signaledStop) return ;
1911 
1912  if (m_maxFileSize.value() == -1) {
1913  return;
1914  }
1915 
1916  // convert to bytes.
1917  Long64_t mfs = (Long64_t)m_maxFileSize.value() * (Long64_t)1048576;
1918  Long64_t mfs_warn = mfs * 95 / 100;
1919 
1920  updateFiles();
1921 
1922  map<string, pair<TFile*,Mode> >::const_iterator itr;
1923  for (itr=m_files.begin(); itr!= m_files.end(); ++itr) {
1924  TFile* tf = itr->second.first;
1925 
1926 #ifndef NDEBUG
1927  if (m_log.level() <= MSG::DEBUG)
1928  m_log << MSG::DEBUG << "stream: " << itr->first << " name: "
1929  << tf->GetName() << " size: " << tf->GetSize()
1930  << endmsg;
1931 #endif
1932 
1933  // Signal job to terminate if output file is too large
1934  if (tf->GetSize() > mfs) {
1935 
1936  signaledStop = true;
1937 
1938  m_log << MSG::FATAL << "file \"" << tf->GetName()
1939  << "\" associated with stream \"" << itr->first
1940  << "\" has exceeded the max file size of "
1941  << m_maxFileSize.value() << "MB. Terminating Job."
1942  << endmsg;
1943 
1944  IEventProcessor* evt(0);
1945  if (service("ApplicationMgr", evt, true).isSuccess()) {
1946  evt->stopRun();
1947  evt->release();
1948  } else {
1949  abort();
1950  }
1951  } else if (tf->GetSize() > mfs_warn) {
1952  m_log << MSG::WARNING << "file \"" << tf->GetName()
1953  << "\" associated with stream \"" << itr->first
1954  << "\" is at 95% of its maximum allowable file size of "
1955  << m_maxFileSize.value() << "MB"
1956  << endmsg;
1957  }
1958  }
1959 }
1960 
1961 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
1962 
1965 void
1966 THistSvc::copyFileLayout (TDirectory *dst, TDirectory *src) {
1967 
1968  if (m_log.level() <= MSG::DEBUG)
1969  m_log << MSG::DEBUG
1970  << "copyFileLayout() to dst path: " << dst->GetPath () << endmsg;
1971 
1972  // strip out URLs
1973  TString path ((char*)strstr (dst->GetPath(), ":"));
1974  path.Remove (0, 2);
1975 
1976  src->cd (path);
1977  TDirectory *cur_src_dir = gDirectory;
1978 
1979  // loop over all keys in this directory
1980  TList *key_list = cur_src_dir->GetListOfKeys ();
1981  int n = key_list->GetEntries ();
1982  for ( int j = 0; j < n; ++j ) {
1983  TKey *k = (TKey*)key_list->At (j);
1984  const std::string src_pathname = cur_src_dir->GetPath()
1985  + std::string("/")
1986  + k->GetName();
1987  TObject *o=src->Get (src_pathname.c_str());
1988 
1989  if (o != NULL && o->IsA()->InheritsFrom ("TDirectory")) {
1990  if (m_log.level() <= MSG::VERBOSE)
1991  m_log << MSG::VERBOSE << " subdir [" << o->GetName() << "]..."
1992  << endmsg;
1993  dst->cd ();
1994  TDirectory * dst_dir = dst->mkdir (o->GetName(), o->GetTitle());
1995  copyFileLayout (dst_dir, src);
1996  }
1997  } // loop over keys
1998  return;
1999 }
2000 
2001 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
2005 StatusCode
2007 {
2008  bool all_good = true;
2009  if (m_log.level() <= MSG::DEBUG)
2010  m_log << MSG::DEBUG << "reinitializing I/O..." << endmsg;
2011 
2012  // retrieve the I/O component manager...
2013 
2014  IIoComponentMgr* iomgr(0);
2015 
2016  if (service("IoComponentMgr", iomgr, true).isFailure()) {
2017  m_log << MSG::ERROR << "could not retrieve I/O component manager !"
2018  << endmsg;
2019  return StatusCode::FAILURE;
2020  }
2021 
2022  GlobalDirectoryRestore restore;
2023  // to hide the expected errors upon closing the files whose
2024  // file descriptors have been swept under the rug...
2025  gErrorIgnoreLevel = kFatal;
2026 
2027  typedef std::map<std::string, std::pair<TFile*,Mode> > FileReg_t;
2028 
2029  for (FileReg_t::iterator ifile = m_files.begin(), iend=m_files.end();
2030  ifile != iend; ++ifile) {
2031  TFile *f = ifile->second.first;
2032  std::string fname = f->GetName();
2033  if (m_log.level() <= MSG::DEBUG)
2034  m_log << MSG::DEBUG << "file [" << fname << "] mode: ["
2035  << f->GetOption() << "] r:"
2036  << f->GetFileBytesRead()
2037  << " w:" << f->GetFileBytesWritten()
2038  << " cnt:" << f->GetFileCounter()
2039  << endmsg;
2040 
2041  if ( ifile->second.second == READ ) {
2042  if (m_log.level() <= MSG::DEBUG)
2043  m_log << MSG::DEBUG
2044  << " TFile opened in READ mode: not reassigning names" << endmsg;
2045  continue;
2046  }
2047 
2048  if ( !iomgr->io_retrieve (this, fname).isSuccess () ) {
2049  m_log << MSG::ERROR << "could not retrieve new name for [" << fname
2050  << "] !!" << endmsg;
2051  all_good = false;
2052  continue;
2053  } else {
2054  if (m_log.level() <= MSG::DEBUG)
2055  m_log << MSG::DEBUG << "got a new name [" << fname << "]..." << endmsg;
2056  }
2057  // create a new TFile
2058  // TFile *newfile = TFile::Open (fname.c_str(), f->GetOption());
2059 
2060  void* vf;
2061  Option_t *opts = f->GetOption();
2062  int r = p_fileMgr->open(Io::ROOT,name(),fname,Io::WRITE,vf,"HIST");
2063  if (r != 0) {
2064  m_log << MSG::ERROR << "unable to open file \"" << fname
2065  << "\" for writing" << endmsg;
2066  return StatusCode::FAILURE;
2067  }
2068  TFile *newfile = (TFile*) vf;
2069  newfile->SetOption(opts);
2070 
2071 
2072  if (ifile->second.second != THistSvc::READ) {
2073  copyFileLayout (newfile, f);
2074  ifile->second.first = newfile;
2075  }
2076 
2077  // loop over all uids and migrate them to the new file
2078  // XXX FIXME: this double loop sucks...
2079  for ( uidMap::iterator uid = m_uids.begin(), uid_end = m_uids.end();
2080  uid != uid_end;
2081  ++uid ) {
2082  THistID& hid = uid->second;
2083  if ( hid.file != f ) {
2084  continue;
2085  }
2086  TDirectory *olddir = this->changeDir (hid);
2087  hid.file = newfile;
2088  // side-effect: create needed directories...
2089  TDirectory *newdir = this->changeDir (hid);
2090  TClass *cl = hid.obj->IsA();
2091 
2092  // migrate the objects to the new file.
2093  // thanks to the object model of ROOT, it is super easy.
2094  if (cl->InheritsFrom ("TTree")) {
2095  dynamic_cast<TTree*> (hid.obj)->SetDirectory (newdir);
2096  dynamic_cast<TTree*> (hid.obj)->Reset();
2097  }
2098  else if (cl->InheritsFrom ("TH1")) {
2099  dynamic_cast<TH1*> (hid.obj)->SetDirectory (newdir);
2100  dynamic_cast<TH1*> (hid.obj)->Reset();
2101  }
2102  else if (cl->InheritsFrom ("TGraph")) {
2103  olddir->Remove (hid.obj);
2104  newdir->Append (hid.obj);
2105  } else {
2106  m_log << MSG::ERROR
2107  << "id: \"" << hid.id << "\" is not a inheriting from a class "
2108  << "we know how to handle (received [" << cl->GetName()
2109  << "], " << "expected [TTree, TH1 or TGraph]) !"
2110  << endmsg
2111  << "attaching to current dir [" << newdir->GetPath() << "] "
2112  << "nonetheless..." << endmsg;
2113  olddir->Remove (hid.obj);
2114  newdir->Append (hid.obj);
2115  }
2116  }
2117  f->ReOpen ("READ");
2118  p_fileMgr->close(f,name());
2119  f = newfile;
2120  }
2121 
2122  return all_good ? StatusCode::SUCCESS : StatusCode::FAILURE;
2123 }
2124 
2125 
2126 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
2127 
2128 StatusCode
2129 THistSvc::rootOpenAction( const Io::FileAttr* fa, const std::string& caller) {
2130 
2131  if (fa->tech() != Io::ROOT) {
2132  // This should never happen
2133  return StatusCode::SUCCESS;
2134  }
2135 
2136  if (fa->desc() != "HIST") {
2137  return StatusCode::SUCCESS;
2138  }
2139 
2140  p_incSvc->fireIncident(FileIncident(caller, "OpenHistFile", fa->name()));
2141 
2142  if ( fa->flags().isRead() ) {
2143  p_incSvc->fireIncident(FileIncident(caller, "BeginHistFile", fa->name()));
2144  } else if ( fa->flags().isWrite() ) {
2146  fa->name()));
2147  } else {
2148  // for Io::RW
2150  fa->name()));
2151  }
2152 
2153  return StatusCode::SUCCESS;
2154 
2155 
2156 }
2157 
2158 //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
2159 
2160 StatusCode
2161 THistSvc::rootOpenErrAction( const Io::FileAttr* fa, const std::string& caller) {
2162 
2163  if (fa->tech() != Io::ROOT) {
2164  // This should never happen
2165  return StatusCode::SUCCESS;
2166  }
2167 
2168  if (fa->desc() != "HIST") {
2169  return StatusCode::SUCCESS;
2170  }
2171 
2172  if ( fa->flags().isRead() ) {
2174  fa->name()));
2175  } else if ( fa->flags().isWrite() ) {
2177  fa->name()));
2178  } else {
2179  // for Io::RW
2180  p_incSvc->fireIncident(FileIncident(caller, "FailRWFile", fa->name()));
2181  }
2182 
2183 
2184  return StatusCode::SUCCESS;
2185 
2186 
2187 }
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:244
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
if(ep)
Definition: Bootstrap.cpp:337
def remove(file, logdir)
Definition: install.py:153
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:1908
IntegerProperty m_autoFlush
Definition: THistSvc.h:182
std::function< StatusCode(FILEMGR_CALLBACK_ARGS) > bfcn_action_t
Definition: IFileMgr.h:340
virtual StatusCode setProperty(const Property &p)
Set the property by property.
Definition: Service.cpp:340
MSG::Level level()
Retrieve output level.
Definition: MsgStream.h:112
std::vector< std::string > Strings_t
Definition: genconf.cpp:88
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
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
list path
Definition: __init__.py:15
STL namespace.
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:2129
return false
Definition: Bootstrap.cpp:338
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:1966
TDirectory * changeDir(const THistSvc::THistID &hid) const
Definition: THistSvc.cpp:1743
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
StatusCode write()
Definition: THistSvc.cpp:1478
constexpr double second
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
dictionary opts
Definition: ana.py:111
std::string dirname(std::string &dir) const
Definition: THistSvc.cpp:1772
virtual StatusCode getTree(const std::string &name, TTree *&) const
Definition: THistSvc.cpp:1126
#define DECLARE_COMPONENT(type)
Definition: PluginService.h:36
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
IntegerProperty m_maxFileSize
Definition: THistSvc.h:182
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:2161
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:329
virtual StatusCode io_reinit()
callback method to reinitialize the internal state of the component for I/O purposes (e...
Definition: THistSvc.cpp:2006
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:72
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:244
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:1896
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:143
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:212
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:197
constexpr double pi
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:1820
void removeDoubleSlash(std::string &) const
Definition: THistSvc.cpp:1810
SmartIF< ISvcLocator > & serviceLocator() const
Retrieve pointer to service locator.
Definition: Service.cpp:334
void updateFiles()
Definition: THistSvc.cpp:1375
virtual Io::close_t close(const Io::Fd, const std::string &caller)=0