Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Fun4AllServer.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file Fun4AllServer.cc
1 #include "Fun4AllServer.h"
2 
3 #include "Fun4AllHistoBinDefs.h"
4 #include "Fun4AllHistoManager.h" // for Fun4AllHistoManager
5 #include "Fun4AllMemoryTracker.h"
6 #include "Fun4AllMonitoring.h"
7 #include "Fun4AllOutputManager.h"
8 #include "Fun4AllReturnCodes.h"
9 #include "Fun4AllSyncManager.h"
10 #include "SubsysReco.h"
11 
12 #include <phool/PHCompositeNode.h>
13 #include <phool/PHNode.h> // for PHNode
14 #include <phool/PHNodeIterator.h>
15 #include <phool/PHNodeReset.h>
16 #include <phool/PHObject.h>
18 #include <phool/PHTimeStamp.h>
19 #include <phool/PHTimer.h> // for PHTimer
20 #include <phool/getClass.h>
21 #include <phool/phool.h>
22 #include <phool/recoConsts.h>
23 
24 #include <Rtypes.h> // for kMAXSIGNALS
25 #include <TDirectory.h>
26 #include <TH1.h>
27 #include <TROOT.h>
28 #include <TSysEvtHandler.h> // for ESignals
29 
30 #include <TSystem.h>
31 
32 #include <algorithm>
33 #include <cstdlib>
34 #include <exception>
35 #include <iostream>
36 #include <memory> // for allocator_traits<>::value_type
37 #include <sstream>
38 
39 //#define FFAMEMTRACKER
40 
42 
44 {
45  if (__instance)
46  {
47  return __instance;
48  }
49  __instance = new Fun4AllServer();
50  return __instance;
51 }
52 
54  : Fun4AllBase(name)
55 #ifdef FFAMEMTRACKER
56  , ffamemtracker(Fun4AllMemoryTracker::instance())
57 #endif
58 {
59  InitAll();
60  return;
61 }
62 
64 {
65  Reset();
66  delete beginruntimestamp;
67  while (Subsystems.begin() != Subsystems.end())
68  {
69  if (Verbosity() >= VERBOSITY_MORE)
70  {
71  Subsystems.back().first->Verbosity(Verbosity());
72  }
73  delete Subsystems.back().first;
74  Subsystems.pop_back();
75  }
76  while (HistoManager.begin() != HistoManager.end())
77  {
78  if (Verbosity() >= VERBOSITY_MORE)
79  {
80  HistoManager.back()->Verbosity(Verbosity());
81  }
82  delete HistoManager.back();
83  HistoManager.pop_back();
84  }
85  while (OutputManager.begin() != OutputManager.end())
86  {
87  if (Verbosity() >= VERBOSITY_MORE)
88  {
89  OutputManager.back()->Verbosity(Verbosity());
90  }
91  delete OutputManager.back();
92  OutputManager.pop_back();
93  }
94  while (SyncManagers.begin() != SyncManagers.end())
95  {
96  SyncManagers.back()->Verbosity(Verbosity());
97  delete SyncManagers.back();
98  SyncManagers.pop_back();
99  }
100  while (topnodemap.begin() != topnodemap.end())
101  {
102  if (Verbosity() >= VERBOSITY_MORE)
103  {
104  topnodemap.begin()->second->print();
105  }
106  delete topnodemap.begin()->second;
107  topnodemap.erase(topnodemap.begin());
108  }
109  while (TDirCollection.begin() != TDirCollection.end())
110  {
111  delete TDirCollection.back();
112  TDirCollection.pop_back();
113  }
115  delete rc;
116  delete ffamemtracker;
117  __instance = nullptr;
118  return;
119 }
120 
122 {
123  // first remove stupid root signal handler to get
124  // decent crashes with debuggable core file
125  for (int i = 0; i < kMAXSIGNALS; i++)
126  {
127  gSystem->IgnoreSignal((ESignals) i);
128  }
130  std::string histomanagername;
131  histomanagername = Name() + "HISTOS";
132  ServerHistoManager = new Fun4AllHistoManager(histomanagername);
134  double uplim = NFRAMEWORKBINS - 0.5;
135  FrameWorkVars = new TH1D("FrameWorkVars", "FrameWorkVars", NFRAMEWORKBINS, -0.5, uplim);
136  registerHisto("FrameWorkVars", FrameWorkVars);
137  defaultSyncManager = new Fun4AllSyncManager("DefaultSyncManager");
138  SyncManagers.push_back(defaultSyncManager);
139  TopNode = new PHCompositeNode("TOP");
140  topnodemap["TOP"] = TopNode;
142  return;
143 }
144 
146 {
147  int iret = 0;
148  std::cout << "Fun4AllServer::dumpHistos() dumping histograms" << std::endl;
149  if (!filename.empty())
150  {
152  }
153  std::vector<Fun4AllHistoManager *>::const_iterator hiter;
154  for (hiter = HistoManager.begin(); hiter != HistoManager.end(); ++hiter)
155  {
156  iret += (*hiter)->dumpHistos("", openmode);
157  }
158  return iret;
159 }
160 
161 bool Fun4AllServer::registerHisto(TNamed *h1d, const int replace)
162 {
163  return ServerHistoManager->registerHisto(h1d, replace);
164 }
165 
166 bool Fun4AllServer::registerHisto(const std::string &hname, TNamed *h1d, const int replace)
167 {
168  return ServerHistoManager->registerHisto(hname, h1d, replace);
169 }
170 
172 {
173  int iret = ServerHistoManager->isHistoRegistered(name);
174  return iret;
175 }
176 
177 int Fun4AllServer::registerSubsystem(SubsysReco *subsystem, const std::string &topnodename)
178 {
180 
181  // if somebody opens a TFile (or changes the gDirectory) in the ctor
182  // we need to set it to a "known" directory
183  gROOT->cd(default_Tdirectory.c_str());
184  std::string currdir = gDirectory->GetPath();
185  TDirectory *tmpdir = gDirectory;
186  if (!tmpdir->FindObject(topnodename.c_str()))
187  {
188  tmpdir = tmpdir->mkdir(topnodename.c_str());
189  if (!tmpdir)
190  {
191  std::cout << PHWHERE << " Error creating TDirectory topdir " << topnodename << std::endl;
192  exit(1);
193  }
194  // store the TDir pointer so it can be cleaned up in the dtor
195  // if one deletes it here the Histograms are dangling somewhere
196  // in root (at least according to valgrind the delete doesn't work
197  // properly anymore)
198  TDirCollection.push_back(tmpdir);
199  }
200  gROOT->cd(topnodename.c_str());
201  tmpdir = gDirectory;
202  if (!tmpdir->FindObject(subsystem->Name().c_str()))
203  {
204  tmpdir = tmpdir->mkdir(subsystem->Name().c_str());
205  if (!tmpdir)
206  {
207  std::cout << PHWHERE << "Error creating TDirectory subdir " << subsystem->Name() << std::endl;
208  exit(1);
209  }
210  // store the TDir pointer so it can be cleaned up in the dtor
211  // if one deletes it here the Histograms are dangling somewhere
212  // in root
213  TDirCollection.push_back(tmpdir);
214  }
215  PHCompositeNode *subsystopNode = se->topNode(topnodename);
216  std::pair<SubsysReco *, PHCompositeNode *> newsubsyspair(subsystem, subsystopNode);
217  int iret = 0;
218  try
219  {
220  std::string memory_tracker_name = subsystem->Name() + "_" + topnodename;
221 #ifdef FFAMEMTRACKER
222  ffamemtracker->Start(memory_tracker_name, "SubsysReco");
223 #endif
224  iret = subsystem->Init(subsystopNode);
225 #ifdef FFAMEMTRACKER
226  ffamemtracker->Stop(memory_tracker_name, "SubsysReco");
227 #endif
228  }
229  catch (const std::exception &e)
230  {
231  std::cout << PHWHERE << " caught exception thrown during SubsysReco::Init() from "
232  << subsystem->Name() << std::endl;
233  std::cout << "error: " << e.what() << std::endl;
234  exit(1);
235  }
236  catch (...)
237  {
238  std::cout << PHWHERE << " caught unknown type exception thrown during SubsysReco::Init() from "
239  << subsystem->Name() << std::endl;
240  exit(1);
241  }
242  gROOT->cd(currdir.c_str());
243  if (iret)
244  {
246  {
247  if (Verbosity() >= VERBOSITY_SOME)
248  {
249  std::cout << "Not Registering Subsystem " << subsystem->Name() << std::endl;
250  }
251  return 0;
252  }
253  std::cout << PHWHERE << " Error from Init() method by "
254  << subsystem->Name() << ", return code: " << iret << std::endl;
255  return iret;
256  }
257  if (Verbosity() >= VERBOSITY_SOME)
258  {
259  std::cout << "Registering Subsystem " << subsystem->Name() << std::endl;
260  }
261  Subsystems.push_back(newsubsyspair);
262  std::string timer_name;
263  timer_name = subsystem->Name() + "_" + topnodename;
264  PHTimer timer(timer_name);
265  if (timer_map.find(timer_name) == timer_map.end())
266  {
267  timer_map.insert(make_pair(timer_name, timer));
268  }
269  RetCodes.push_back(iret); // vector with return codes
270  return 0;
271 }
272 
274 {
275  std::pair<SubsysReco *, PHCompositeNode *> subsyspair(subsystem, 0);
276  DeleteSubsystems.push_back(subsyspair);
278  return 0;
279 }
280 
282 {
283  std::vector<std::pair<SubsysReco *, PHCompositeNode *>>::iterator sysiter, removeiter;
284  for (removeiter = DeleteSubsystems.begin();
285  removeiter != DeleteSubsystems.end();
286  ++removeiter)
287  {
288  int index = 0;
289  int foundit = 0;
290  for (sysiter = Subsystems.begin(); sysiter != Subsystems.end(); ++sysiter)
291  {
292  if ((*sysiter).first == (*removeiter).first)
293  {
294  foundit = 1;
295  break;
296  }
297  index++;
298  }
299  if (!foundit)
300  {
301  std::cout << "unregisterSubsystem: Could not find SubsysReco "
302  << (*removeiter).first->Name()
303  << " in Fun4All Reco Module list" << std::endl;
304  delete (*removeiter).first;
305  continue;
306  }
307  if (Verbosity() >= VERBOSITY_MORE)
308  {
309  std::cout << "Removing Subsystem: " << (*removeiter).first->Name()
310  << " at index " << index << std::endl;
311  }
312  Subsystems.erase(Subsystems.begin() + index);
313  delete (*removeiter).first;
314  // also update the vector with return codes
315  RetCodes.erase(RetCodes.begin() + index);
316  std::vector<Fun4AllOutputManager *>::iterator outiter;
317  for (outiter = OutputManager.begin(); outiter != OutputManager.end(); ++outiter)
318  {
319  UpdateEventSelector(*outiter);
320  }
321  }
323  DeleteSubsystems.clear();
324  return 0;
325 }
326 
327 SubsysReco *
329 {
330  std::vector<std::pair<SubsysReco *, PHCompositeNode *>>::iterator sysiter;
331  for (sysiter = Subsystems.begin(); sysiter != Subsystems.end(); ++sysiter)
332  {
333  if ((*sysiter).first->Name() == name)
334  {
336  {
337  std::cout << "Found Subsystem " << name << std::endl;
338  }
339  return (*sysiter).first;
340  }
341  }
342  std::cout << "Could not find SubsysReco " << name << std::endl;
343  return nullptr;
344 }
345 
346 int Fun4AllServer::AddComplaint(const std::string &complaint, const std::string &remedy)
347 {
349  std::string separatorstring = "------------------------------";
350  std::ostringstream complaintno;
351  complaintno << "Problem No " << ScreamEveryEvent;
352 
353  ComplaintList.push_back(separatorstring);
354  ComplaintList.push_back(complaintno.str());
355  ComplaintList.push_back(complaint);
356  ComplaintList.emplace_back(" ");
357  ComplaintList.emplace_back("Remedy:");
358  ComplaintList.push_back(remedy);
359  ComplaintList.push_back(separatorstring);
360  return 0;
361 }
362 
364 {
365  std::vector<Fun4AllOutputManager *>::iterator iter;
366  for (iter = OutputManager.begin(); iter != OutputManager.end(); ++iter)
367  {
368  if ((*iter)->Name() == manager->Name())
369  {
370  std::cout << "OutputManager " << manager->Name() << " allready in list" << std::endl;
371  return -1;
372  }
373  }
374  if (Verbosity() >= VERBOSITY_SOME)
375  {
376  std::cout << "Registering OutputManager " << manager->Name() << std::endl;
377  }
378  UpdateEventSelector(manager);
379  OutputManager.push_back(manager);
380  return 0;
381 }
382 
384 {
385  std::vector<std::string>::iterator striter;
386  std::vector<std::pair<SubsysReco *, PHCompositeNode *>>::const_iterator subsysiter;
387 
388 tryagain:
389  manager->RecoModuleIndex()->clear();
390  for (striter = manager->EventSelector()->begin(); striter != manager->EventSelector()->end(); ++striter)
391  {
393  {
394  std::cout << PHWHERE << "striter: " << *striter << std::endl;
395  }
396  unsigned index = 0;
397  int found = 0;
398  for (subsysiter = Subsystems.begin(); subsysiter != Subsystems.end(); ++subsysiter)
399  {
400  if (*striter == (*subsysiter).first->Name())
401  {
402  manager->RecoModuleIndex()->push_back(index);
404  {
405  std::cout << PHWHERE << "setting RecoModuleIndex to " << index << std::endl;
406  }
407  found = 1;
408  break;
409  }
410  index++;
411  }
412  if (!found)
413  {
414  std::cout << "Could not find module " << *striter
415  << ", removing it from list of event selector modules" << std::endl;
416  manager->EventSelector()->erase(striter);
417  // NOLINTNEXTLINE(hicpp-avoid-goto)
418  goto tryagain;
419  }
420  }
421  return 0;
422 }
423 
426 {
427  std::vector<Fun4AllOutputManager *>::iterator iter;
428  for (iter = OutputManager.begin(); iter != OutputManager.end(); ++iter)
429  {
430  if (name == (*iter)->Name())
431  {
433  {
434  std::cout << "Found OutputManager " << name << std::endl;
435  }
436  return *iter;
437  }
438  }
439  std::cout << "Could not find OutputManager" << name << std::endl;
440  return nullptr;
441 }
442 
445 {
446  std::vector<Fun4AllHistoManager *>::iterator iter;
447  for (iter = HistoManager.begin(); iter != HistoManager.end(); ++iter)
448  {
449  if ((*iter)->Name() == name)
450  {
452  {
453  std::cout << "Found HistoManager " << name << std::endl;
454  }
455  return *iter;
456  }
457  }
458  if (Verbosity() >= VERBOSITY_MORE)
459  {
460  std::cout << "Could not find HistoManager " << name << std::endl;
461  }
462  return nullptr;
463 }
464 
466 {
467  std::vector<Fun4AllHistoManager *>::iterator iter;
468  for (iter = HistoManager.begin(); iter != HistoManager.end(); ++iter)
469  {
470  if ((*iter)->Name() == manager->Name())
471  {
472  std::cout << "HistoManager " << manager->Name() << " allready in list" << std::endl;
473  return -1;
474  }
475  }
476  if (Verbosity() >= VERBOSITY_SOME)
477  {
478  std::cout << "Registering HistoManager " << manager->Name() << std::endl;
479  }
480  HistoManager.push_back(manager);
481  return 0;
482 }
483 
484 TNamed *
485 Fun4AllServer::getHisto(const unsigned int ihisto) const
486 {
487  return ServerHistoManager->getHisto(ihisto);
488 }
489 
491 Fun4AllServer::getHistoName(const unsigned int ihisto) const
492 {
493  return (ServerHistoManager->getHistoName(ihisto));
494 }
495 
496 TNamed *Fun4AllServer::getHisto(const std::string &hname) const
497 {
498  return (ServerHistoManager->getHisto(hname));
499 }
500 
502 {
503  eventcounter++;
504  unsigned icnt = 0;
505  int eventbad = 0;
506  if (ScreamEveryEvent)
507  {
508  std::cout << "*******************************************************************************" << std::endl;
509  std::cout << "*******************************************************************************" << std::endl;
510  std::cout << "*******************************************************************************" << std::endl;
511  std::cout << "Now that I have your attention, please fix the following "
512  << ScreamEveryEvent << " problem(s):" << std::endl;
513  std::vector<std::string>::const_iterator viter;
514  for (viter = ComplaintList.begin(); viter != ComplaintList.end(); ++viter)
515  {
516  std::cout << *viter << std::endl;
517  }
518  std::cout << " " << std::endl;
519  std::cout << "*******************************************************************************" << std::endl;
520  std::cout << "*******************************************************************************" << std::endl;
521  std::cout << "*******************************************************************************" << std::endl;
522  }
524  {
526  }
527  gROOT->cd(default_Tdirectory.c_str());
528  std::string currdir = gDirectory->GetPath();
529  for (auto &Subsystem : Subsystems)
530  {
531  if (Verbosity() >= VERBOSITY_MORE)
532  {
533  std::cout << "Fun4AllServer::process_event processing " << Subsystem.first->Name() << std::endl;
534  }
535  std::string newdirname = Subsystem.second->getName() + "/" + Subsystem.first->Name();
536  if (!gROOT->cd(newdirname.c_str()))
537  {
538  std::cout << PHWHERE << "Unexpected TDirectory Problem cd'ing to "
539  << Subsystem.second->getName()
540  << " - send e-mail to off-l with your macro" << std::endl;
541  exit(1);
542  }
543  else
544  {
546  {
547  std::cout << "process_event: cded to " << newdirname << std::endl;
548  }
549  }
550 
551  try
552  {
553  std::string timer_name;
554  timer_name = Subsystem.first->Name() + "_" + Subsystem.second->getName();
555  std::map<const std::string, PHTimer>::iterator titer = timer_map.find(timer_name);
556  bool timer_found = false;
557  if (titer != timer_map.end())
558  {
559  timer_found = true;
560  titer->second.restart();
561  }
562  else
563  {
564  std::cout << "could not find timer for " << timer_name << std::endl;
565  }
566 #ifdef FFAMEMTRACKER
567  ffamemtracker->Start(timer_name, "SubsysReco");
568  ffamemtracker->Snapshot("Fun4AllServerProcessEvent");
569 #endif
570  int retcode = Subsystem.first->process_event(Subsystem.second);
571 #ifdef FFAMEMTRACKER
572  ffamemtracker->Snapshot("Fun4AllServerProcessEvent");
573 #endif
574  // we have observed an index overflow in RetCodes. I assume it is some
575  // memory corruption elsewhere which hits the icnt variable. Rather than
576  // the previous [], use at() which does bounds checking and throws an
577  // exception which will allow us to catch this and print out icnt and the size
578  try
579  {
580  RetCodes.at(icnt) = retcode;
581  }
582  catch (const std::exception &e)
583  {
584  std::cout << PHWHERE << " caught exception thrown during RetCodes.at(icnt)" << std::endl;
585  std::cout << "RetCodes.size(): " << RetCodes.size() << ", icnt: " << icnt << std::endl;
586  std::cout << "error: " << e.what() << std::endl;
587  gSystem->Exit(1);
588  }
589  if (timer_found)
590  {
591  titer->second.stop();
592  }
593 #ifdef FFAMEMTRACKER
594  ffamemtracker->Stop(timer_name, "SubsysReco");
595 #endif
596  }
597  catch (const std::exception &e)
598  {
599  std::cout << PHWHERE << " caught exception thrown during process_event from "
600  << Subsystem.first->Name() << std::endl;
601  std::cout << "error: " << e.what() << std::endl;
602  gSystem->Exit(1);
603  }
604  catch (...)
605  {
606  std::cout << PHWHERE << " caught unknown type exception thrown during process_event from "
607  << Subsystem.first->Name() << std::endl;
608  exit(1);
609  }
610  if (RetCodes[icnt])
611  {
613  {
615  {
616  std::cout << "Fun4AllServer::Discard Event by " << Subsystem.first->Name() << std::endl;
617  }
618  }
619  else if (RetCodes[icnt] == Fun4AllReturnCodes::ABORTEVENT)
620  {
622  eventbad = 1;
623  if (Verbosity() >= VERBOSITY_MORE)
624  {
625  std::cout << "Fun4AllServer::Abort Event by " << Subsystem.first->Name() << std::endl;
626  }
627  break;
628  }
629  else if (RetCodes[icnt] == Fun4AllReturnCodes::ABORTRUN)
630  {
632  std::cout << "Fun4AllServer::Abort Run by " << Subsystem.first->Name() << std::endl;
634  }
635  else
636  {
637  std::cout << "Fun4AllServer::Unknown return code: "
638  << RetCodes[icnt] << " from process_event method of "
639  << Subsystem.first->Name() << std::endl;
640  std::cout << "This smells like an uninitialized return code and" << std::endl;
641  std::cout << "it is too dangerous to continue, this Run will be aborted" << std::endl;
642  std::cout << "If you do not know how to fix this please send mail to" << std::endl;
643  std::cout << "phenix-off-l with this message" << std::endl;
645  }
646  }
647  icnt++;
648  }
649  if (!eventbad)
650  {
652  }
653 
654  gROOT->cd(currdir.c_str());
655 
656  // mainIter.print();
657  if (!OutputManager.empty() && !eventbad) // there are registered IO managers and
658  // the event is not flagged bad
659  {
660  PHNodeIterator iter(TopNode);
661  PHCompositeNode *dstNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "DST"));
662 
663  if (dstNode)
664  {
665  // check if we have same number of nodes. After first event is
666  // written out root I/O doesn't permit adding nodes, otherwise
667  // events get out of sync
668  static int first = 1;
669  int newcount = CountOutNodes(dstNode);
670  if (first)
671  {
672  first = 0;
673  OutNodeCount = newcount; // save number of nodes before first write
674  MakeNodesTransient(dstNode); // make all nodes transient before 1st write in case someone sneaked a node in at the first event
675  }
676 
677  if (OutNodeCount != newcount)
678  {
679  iter.print();
680  std::cout << PHWHERE << " FATAL: Someone changed the number of Output Nodes on the fly, from " << OutNodeCount << " to " << newcount << std::endl;
681  exit(1);
682  }
683  std::vector<Fun4AllOutputManager *>::iterator iterOutMan;
684  for (iterOutMan = OutputManager.begin(); iterOutMan != OutputManager.end(); ++iterOutMan)
685  {
686  if (!(*iterOutMan)->DoNotWriteEvent(&RetCodes))
687  {
688  if (Verbosity() >= VERBOSITY_MORE)
689  {
690  std::cout << "Writing Event for " << (*iterOutMan)->Name() << std::endl;
691  }
692 #ifdef FFAMEMTRACKER
693  ffamemtracker->Snapshot("Fun4AllServerOutputManager");
694  ffamemtracker->Start((*iterOutMan)->Name(), "OutputManager");
695 #endif
696  (*iterOutMan)->WriteGeneric(dstNode);
697 #ifdef FFAMEMTRACKER
698  ffamemtracker->Stop((*iterOutMan)->Name(), "OutputManager");
699  ffamemtracker->Snapshot("Fun4AllServerOutputManager");
700 #endif
701  if ((*iterOutMan)->EventsWritten() >= (*iterOutMan)->GetNEvents())
702  {
703  if (Verbosity() > 0)
704  {
705  std::cout << PHWHERE << (*iterOutMan)->Name() << " wrote " << (*iterOutMan)->EventsWritten()
706  << " events, closing " << (*iterOutMan)->OutFileName() << std::endl;
707  }
708  PHNodeIterator nodeiter(TopNode);
709  PHCompositeNode *runNode = dynamic_cast<PHCompositeNode *>(nodeiter.findFirst("PHCompositeNode", "RUN"));
710  MakeNodesTransient(runNode); // make all nodes transient by default
711  (*iterOutMan)->WriteNode(runNode);
712  }
713  }
714  else
715  {
716  if (Verbosity() >= VERBOSITY_MORE)
717  {
718  std::cout << "Not Writing Event for " << (*iterOutMan)->Name() << std::endl;
719  }
720  }
721  }
722  }
723  }
724  for (auto &Subsystem : Subsystems)
725  {
727  {
728  std::cout << "Fun4AllServer::process_event Resetting Event " << Subsystem.first->Name() << std::endl;
729  }
730  Subsystem.first->ResetEvent(Subsystem.second);
731  }
732  for (auto &syncman : SyncManagers)
733  {
735  {
736  std::cout << "Fun4AllServer::process_event Resetting Event for Sync Manager " << syncman->Name() << std::endl;
737  }
738  syncman->ResetEvent();
739  }
741  ResetNodeTree();
742  return 0;
743 }
744 
746 {
747  std::vector<std::string> ResetNodeList;
748  ResetNodeList.emplace_back("DST");
750  reset.Verbosity(Verbosity() > 2 ? Verbosity() - 2 : 0); // one lower verbosity level than Fun4AllServer
751  std::map<std::string, PHCompositeNode *>::const_iterator iter;
752  for (iter = topnodemap.begin(); iter != topnodemap.end(); ++iter)
753  {
754  PHNodeIterator mainIter((*iter).second);
755  for (const auto &nodename : ResetNodeList)
756  {
757  if (mainIter.cd(nodename))
758  {
759  mainIter.forEach(reset);
760  mainIter.cd();
761  }
762  }
763  }
764  return 0; // anything except 0 would abort the event loop in pmonitor
765 }
766 
768 {
769  int i = 0;
770  std::vector<std::pair<SubsysReco *, PHCompositeNode *>>::iterator iter;
771  for (iter = Subsystems.begin(); iter != Subsystems.end(); ++iter)
772  {
774  {
775  std::cout << "Fun4AllServer::Reset Resetting " << (*iter).first->Name() << std::endl;
776  }
777  i += (*iter).first->Reset((*iter).second);
778  }
779  std::vector<Fun4AllHistoManager *>::iterator hiter;
780  for (hiter = HistoManager.begin(); hiter != HistoManager.end(); ++hiter)
781  {
782  (*hiter)->Reset();
783  }
784  return i;
785 }
786 
788 {
789  beginruntimestamp = new PHTimeStamp(TimeStp);
790  std::cout << "Setting BOR timestamp to ";
792  std::cout << std::endl;
793  bortime_override = 1;
794  return 0;
795 }
796 
797 int Fun4AllServer::BeginRun(const int runno)
798 {
799  eventcounter = 0; // reset event counter for every new run
800 #ifdef FFAMEMTRACKER
801  ffamemtracker->Snapshot("Fun4AllServerBeginRun");
802 #endif
803  if (!bortime_override)
804  {
805  if (beginruntimestamp)
806  {
807  delete beginruntimestamp;
808  }
810  }
811  else
812  {
813  std::cout << "overriding BOR timestamp by ";
815  std::cout << std::endl;
816  // rc->set_TimeStamp(*beginruntimestamp);
817  }
818  if (Verbosity() >= VERBOSITY_SOME)
819  {
820  std::cout << "Fun4AllServer::BeginRun: Run number " << runno << " uses RECO TIMESTAMP: ";
822  std::cout << std::endl;
823  }
824  std::vector<std::pair<SubsysReco *, PHCompositeNode *>>::iterator iter;
825  int iret = 0;
826 
827  // check if any registered SubsysReco wants to be dropped and
828  // remove it from the list before its BeginRun is executed
830  {
832  }
833 
834  // we have to do the same TDirectory games as in the Init methods
835  // save the current dir, cd to the subsystem name dir (which was
836  // created in init) call the InitRun of the module and cd back
837 
838  gROOT->cd(default_Tdirectory.c_str());
839  std::string currdir = gDirectory->GetPath();
840 
841  for (iter = Subsystems.begin(); iter != Subsystems.end(); ++iter)
842  {
843  iret = BeginRunSubsystem(*iter);
844  }
845  for (; !NewSubsystems.empty(); NewSubsystems.pop_front())
846  {
847  registerSubsystem((NewSubsystems.front()).first, (NewSubsystems.front()).second);
848  BeginRunSubsystem(std::make_pair(NewSubsystems.front().first, topNode(NewSubsystems.front().second)));
849  }
850  gROOT->cd(currdir.c_str());
851  // print out all node trees
852  Print("NODETREE");
853 #ifdef FFAMEMTRACKER
854  ffamemtracker->Snapshot("Fun4AllServerBeginRun");
855 #endif
856  return iret;
857 }
858 
859 int Fun4AllServer::BeginRunSubsystem(const std::pair<SubsysReco *, PHCompositeNode *> &subsys)
860 {
861  int iret = 0;
862  std::string newdirname = subsys.second->getName() + "/" + subsys.first->Name();
863  if (!gROOT->cd(newdirname.c_str()))
864  {
865  std::cout << PHWHERE << "Unexpected TDirectory Problem cd'ing to "
866  << subsys.second->getName()
867  << " - send e-mail to off-l with your macro" << std::endl;
868  exit(1);
869  }
870  else
871  {
873  {
874  std::cout << "BeginRun: cded to " << newdirname << std::endl;
875  }
876  }
877 
878  if (Verbosity() >= VERBOSITY_SOME)
879  {
880  std::cout << "Fun4AllServer::BeginRun: InitRun for " << subsys.first->Name() << std::endl;
881  }
882  try
883  {
884 #ifdef FFAMEMTRACKER
885  ffamemtracker->Start(subsys.first->Name(), "SubsysReco");
886 #endif
887  iret = subsys.first->InitRun(subsys.second);
888 #ifdef FFAMEMTRACKER
889  ffamemtracker->Stop(subsys.first->Name(), "SubsysReco");
890 #endif
891  }
892  catch (const std::exception &e)
893  {
894  std::cout << PHWHERE << " caught exception thrown during SubsysReco::InitRun() from "
895  << subsys.first->Name() << std::endl;
896  std::cout << "error: " << e.what() << std::endl;
897  exit(1);
898  }
899  catch (...)
900  {
901  std::cout << PHWHERE << " caught unknown type exception thrown during SubsysReco::InitRun() from "
902  << subsys.first->Name() << std::endl;
903  exit(1);
904  }
905 
906  if (iret == Fun4AllReturnCodes::ABORTRUN)
907  {
908  std::cout << PHWHERE << "Module " << subsys.first->Name() << " issued Abort Run, exiting" << std::endl;
909  exit(-1);
910  }
911  else if (iret != Fun4AllReturnCodes::EVENT_OK)
912  {
913  std::cout << PHWHERE << "Module " << subsys.first->Name() << " issued non Fun4AllReturnCodes::EVENT_OK return code " << iret << " in InitRun()" << std::endl;
914  exit(-2);
915  }
916  return iret;
917 }
918 
920 {
921  int icount = 0;
922  icount = CountOutNodesRecursive(startNode, icount);
923  return icount;
924 }
925 
926 // NOLINTNEXTLINE(misc-no-recursion)
928 {
929  PHNodeIterator nodeiter(startNode);
930  PHPointerListIterator<PHNode> iterat(nodeiter.ls());
931  PHNode *thisNode;
932  int icnt = icount;
933  while ((thisNode = iterat()))
934  {
935  if ((thisNode->getType() == "PHCompositeNode"))
936  {
937  icnt = CountOutNodesRecursive(static_cast<PHCompositeNode *>(thisNode), icnt); // if this is a CompositeNode do this trick again
938  }
939  else
940  {
941  icnt++;
943  {
944  std::cout << thisNode->getName() << ", Node Count: " << icnt << std::endl;
945  }
946  }
947  }
948  return icnt;
949 }
950 
951 // NOLINTNEXTLINE(misc-no-recursion)
953 {
954  PHNodeIterator nodeiter(startNode);
955  PHPointerListIterator<PHNode> iterat(nodeiter.ls());
956  PHNode *thisNode;
957  while ((thisNode = iterat()))
958  {
959  if ((thisNode->getType() == "PHCompositeNode"))
960  {
961  MakeNodesTransient(static_cast<PHCompositeNode *>(thisNode)); // if this is a CompositeNode do this trick again
962  }
963  else
964  {
965  thisNode->makeTransient();
966  }
967  }
968  return 0;
969 }
970 
971 // NOLINTNEXTLINE(misc-no-recursion)
973 {
974  PHNodeIterator nodeiter(startNode);
975  PHPointerListIterator<PHNode> iterat(nodeiter.ls());
976  PHNode *thisNode;
977  while ((thisNode = iterat()))
978  {
979  if ((thisNode->getType() == "PHCompositeNode"))
980  {
981  MakeNodesPersistent(static_cast<PHCompositeNode *>(thisNode)); // if this is a CompositeNode do this trick again
982  }
983  else
984  {
985  thisNode->makePersistent();
986  }
987  }
988  return 0;
989 }
990 
991 int Fun4AllServer::EndRun(const int runno)
992 {
993  std::vector<std::pair<SubsysReco *, PHCompositeNode *>>::iterator iter;
994  gROOT->cd(default_Tdirectory.c_str());
995  std::string currdir = gDirectory->GetPath();
996  for (iter = Subsystems.begin(); iter != Subsystems.end(); ++iter)
997  {
998  if (Verbosity() >= VERBOSITY_MORE)
999  {
1000  std::cout << "Fun4AllServer::EndRun: EndRun("
1001  << runno << ") for " << (*iter).first->Name() << std::endl;
1002  }
1003  std::string newdirname = (*iter).second->getName() + "/" + (*iter).first->Name();
1004  if (!gROOT->cd(newdirname.c_str()))
1005  {
1006  std::cout << PHWHERE << "Unexpected TDirectory Problem cd'ing to "
1007  << (*iter).second->getName()
1008  << " - send e-mail to off-l with your macro" << std::endl;
1009  exit(1);
1010  }
1011  else
1012  {
1013  if (Verbosity() >= VERBOSITY_EVEN_MORE)
1014  {
1015  std::cout << "EndRun: cded to " << newdirname << std::endl;
1016  }
1017  }
1018  try
1019  {
1020  (*iter).first->EndRun(runno);
1021  }
1022  catch (const std::exception &e)
1023  {
1024  std::cout << PHWHERE << " caught exception thrown during SubsysReco::EndRun() from "
1025  << (*iter).first->Name() << std::endl;
1026  std::cout << "error: " << e.what() << std::endl;
1027  exit(1);
1028  }
1029  catch (...)
1030  {
1031  std::cout << PHWHERE << " caught unknown type exception thrown during SubsysReco::EndRun() from "
1032  << (*iter).first->Name() << std::endl;
1033  exit(1);
1034  }
1035  }
1036  gROOT->cd(currdir.c_str());
1037 
1038  return 0;
1039 }
1040 
1042 {
1044  EndRun(rc->get_IntFlag("RUNNUMBER")); // call SubsysReco EndRun methods for current run
1045  int i = 0;
1046  std::vector<std::pair<SubsysReco *, PHCompositeNode *>>::iterator iter;
1047  gROOT->cd(default_Tdirectory.c_str());
1048  std::string currdir = gDirectory->GetPath();
1049  for (iter = Subsystems.begin(); iter != Subsystems.end(); ++iter)
1050  {
1051  if (Verbosity() >= VERBOSITY_SOME)
1052  {
1053  std::cout << "Fun4AllServer::End: End for " << (*iter).first->Name() << std::endl;
1054  }
1055  std::string newdirname = (*iter).second->getName() + "/" + (*iter).first->Name();
1056  if (!gROOT->cd(newdirname.c_str()))
1057  {
1058  std::cout << PHWHERE << "Unexpected TDirectory Problem cd'ing to "
1059  << (*iter).second->getName()
1060  << " - send e-mail to off-l with your macro" << std::endl;
1061  exit(1);
1062  }
1063  else
1064  {
1065  if (Verbosity() >= VERBOSITY_EVEN_MORE)
1066  {
1067  std::cout << "End: cded to " << newdirname << std::endl;
1068  }
1069  }
1070  try
1071  {
1072  i += (*iter).first->End((*iter).second);
1073  }
1074  catch (const std::exception &e)
1075  {
1076  std::cout << PHWHERE << " caught exception thrown during SusbsysReco::End() from "
1077  << (*iter).first->Name() << std::endl;
1078  std::cout << "error: " << e.what() << std::endl;
1079  exit(1);
1080  }
1081  catch (...)
1082  {
1083  std::cout << PHWHERE << " caught unknown type exception thrown during SubsysReco::End() from "
1084  << (*iter).first->Name() << std::endl;
1085  exit(1);
1086  }
1087  }
1088  gROOT->cd(currdir.c_str());
1089  PHNodeIterator nodeiter(TopNode);
1090  PHCompositeNode *runNode = dynamic_cast<PHCompositeNode *>(nodeiter.findFirst("PHCompositeNode", "RUN"));
1091  if (!runNode)
1092  {
1093  std::cout << "No Run Node, not writing Runwise info" << std::endl;
1094  }
1095  else
1096  {
1097  if (!OutputManager.empty()) // there are registered IO managers
1098  {
1099  MakeNodesTransient(runNode); // make all nodes transient by default
1100  std::vector<Fun4AllOutputManager *>::iterator IOiter;
1101  for (IOiter = OutputManager.begin(); IOiter != OutputManager.end(); ++IOiter)
1102  {
1103  (*IOiter)->WriteNode(runNode);
1104  }
1105  }
1106  }
1107  // close output files (check for existing output managers is
1108  // done inside outfileclose())
1109  outfileclose();
1110 
1111  if (ScreamEveryEvent)
1112  {
1113  std::cout << "*******************************************************************************" << std::endl;
1114  std::cout << "*******************************************************************************" << std::endl;
1115  std::cout << "*******************************************************************************" << std::endl;
1116  std::cout << "Now that we are at the End(), please fix the following "
1117  << ScreamEveryEvent << " problem(s):" << std::endl;
1118  std::vector<std::string>::const_iterator viter;
1119  for (viter = ComplaintList.begin(); viter != ComplaintList.end(); ++viter)
1120  {
1121  std::cout << *viter << std::endl;
1122  }
1123  std::cout << " " << std::endl;
1124  std::cout << "*******************************************************************************" << std::endl;
1125  std::cout << "*******************************************************************************" << std::endl;
1126  std::cout << "*******************************************************************************" << std::endl;
1127  }
1128 
1129  return i;
1130 }
1131 
1132 void Fun4AllServer::Print(const std::string &what) const
1133 {
1134  if (what == "ALL" || what == "HISTOS")
1135  {
1136  // loop over the map and print out the content (name and location in memory)
1137  for (auto &histoman : HistoManager)
1138  {
1139  histoman->Print(what);
1140  }
1141  }
1142  if (what == "ALL" || what == "SUBSYSTEMS")
1143  {
1144  // loop over the map and print out the content (name and location in memory)
1145  std::cout << "--------------------------------------" << std::endl
1146  << std::endl;
1147  std::cout << "List of Subsystems in Fun4AllServer:" << std::endl;
1148 
1149  std::vector<std::pair<SubsysReco *, PHCompositeNode *>>::const_iterator miter;
1150  for (miter = Subsystems.begin(); miter != Subsystems.end(); ++miter)
1151  {
1152  std::cout << (*miter).first->Name()
1153  << " running under topNode " << (*miter).second->getName() << std::endl;
1154  }
1155  std::cout << std::endl;
1156  }
1157 
1158  if (what == "ALL" || what == "INPUTMANAGER")
1159  {
1160  // the input managers are managed by the input singleton
1161  for (auto &syncman : SyncManagers)
1162  {
1163  std::cout << "SyncManager: " << syncman->Name() << std::endl;
1164  syncman->Print(what);
1165  }
1166  }
1167 
1168  if (what == "ALL" || what.find("OUTPUTMANAGER") != std::string::npos)
1169  {
1170  // loop over the map and print out the content (name and location in memory)
1171  std::string pass_on = what;
1172  if (pass_on == "ALL" || pass_on == "OUTPUTMANAGER")
1173  {
1174  std::cout << "--------------------------------------" << std::endl
1175  << std::endl;
1176  std::cout << "List of OutputManagers in Fun4AllServer:" << std::endl;
1177  pass_on = "ALL";
1178  }
1179  else
1180  {
1181  std::string::size_type pos = pass_on.find('%');
1182  pass_on = pass_on.substr(pos + 1, pass_on.size());
1183  }
1184  for (auto &outman : OutputManager)
1185  {
1186  outman->Print(pass_on);
1187  }
1188  std::cout << std::endl;
1189  }
1190  if (what == "ALL" || what == "TOPNODES")
1191  {
1192  // loop over the map and print out the content (name and location in memory)
1193  std::cout << "--------------------------------------" << std::endl
1194  << std::endl;
1195  std::cout << "List of TopNodes in Fun4AllServer:" << std::endl;
1196 
1197  std::map<std::string, PHCompositeNode *>::const_iterator iter;
1198  for (iter = topnodemap.begin(); iter != topnodemap.end(); ++iter)
1199  {
1200  std::cout << iter->first << " is at " << std::hex
1201  << iter->second << std::dec << std::endl;
1202  }
1203  std::cout << std::endl;
1204  }
1205  if (what == "ALL" || what == "NODETREE")
1206  {
1207  // loop over the map and print out the content (name and location in memory)
1208  std::cout << "--------------------------------------" << std::endl
1209  << std::endl;
1210  std::cout << "List of Nodes in Fun4AllServer:" << std::endl;
1211 
1212  std::map<std::string, PHCompositeNode *>::const_iterator iter;
1213  for (iter = topnodemap.begin(); iter != topnodemap.end(); ++iter)
1214  {
1215  std::cout << "Node Tree under TopNode " << iter->first << std::endl;
1216  PHNodeIterator nodeiter(iter->second);
1217  nodeiter.print();
1218  std::cout << std::endl;
1219  }
1220  std::cout << std::endl;
1221  }
1222  return;
1223 }
1224 
1225 void Fun4AllServer::identify(std::ostream &out) const
1226 {
1227  out << "Fun4AllServer Name: " << Name() << std::endl;
1228  return;
1229 }
1230 
1232 {
1233  while (!OutputManager.empty())
1234  {
1235  if (Verbosity() >= VERBOSITY_MORE)
1236  {
1237  std::cout << "Erasing OutputManager "
1238  << (*OutputManager.begin())->Name()
1239  << " at memory location " << *(OutputManager.begin()) << std::endl;
1240  }
1241  delete *(OutputManager.begin());
1242  OutputManager.erase(OutputManager.begin());
1243  }
1244  return 0;
1245 }
1246 
1248 {
1249  PHCompositeNode *dstNode, *runNode, *parNode;
1250  dstNode = new PHCompositeNode("DST");
1251  topNode->addNode(dstNode);
1252  runNode = new PHCompositeNode("RUN");
1253  topNode->addNode(runNode);
1254  parNode = new PHCompositeNode("PAR");
1255  topNode->addNode(parNode);
1256  return 0;
1257 }
1258 
1261 {
1262  std::map<std::string, PHCompositeNode *>::const_iterator iter;
1263  iter = topnodemap.find(name);
1264  if (iter != topnodemap.end())
1265  {
1266  return iter->second;
1267  }
1268  AddTopNode(name);
1269  iter = topnodemap.find(name);
1270  if (iter != topnodemap.end())
1271  {
1272  InitNodeTree(iter->second);
1273  return iter->second;
1274  }
1275  std::cout << PHWHERE << " Could not create new topNode " << name
1276  << " send email to off-l with the following printout: " << std::endl;
1277  for (iter = topnodemap.begin(); iter != topnodemap.end(); ++iter)
1278  {
1279  std::cout << iter->first << " is at " << std::hex << iter->second << std::dec << std::endl;
1280  }
1281  exit(1);
1282 }
1283 
1285 {
1286  std::map<std::string, PHCompositeNode *>::const_iterator iter;
1287  iter = topnodemap.find(name);
1288  if (iter != topnodemap.end())
1289  {
1290  return -1;
1291  }
1292  PHCompositeNode *newNode = new PHCompositeNode(name);
1293  topnodemap[name] = newNode;
1294  return 0;
1295 }
1296 
1298 {
1299  PHNodeIterator iter(topNode(topnodename));
1300  PHCompositeNode *thisNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", name));
1301  if (!thisNode)
1302  {
1303  thisNode = new PHCompositeNode(name);
1304  topNode(topnodename)->addNode(thisNode);
1305  }
1306  return thisNode;
1307 }
1308 
1310 {
1311  int iret = defaultSyncManager->registerInputManager(InManager);
1312  return iret;
1313 }
1314 
1317 {
1318  std::vector<Fun4AllSyncManager *>::const_iterator iter;
1319  for (iter = SyncManagers.begin(); iter != SyncManagers.end(); ++iter)
1320  {
1321  if ((*iter)->getInputManager(name))
1322  {
1323  return (*iter)->getInputManager(name);
1324  }
1325  }
1326  std::cout << "Could not locate input manager " << name << std::endl;
1327  return nullptr;
1328 }
1329 
1331 {
1332  return (defaultSyncManager->PrdfEvents());
1333 }
1334 
1336 {
1337  return (defaultSyncManager->TotalEvents());
1338 }
1339 
1340 //_________________________________________________________________
1341 int Fun4AllServer::run(const int nevnts, const bool require_nevents)
1342 {
1344  static bool run_number_forced = rc->FlagExist("RUNNUMBER");
1345  static int ifirst = 1;
1346  if (ifirst && run_number_forced)
1347  {
1348  runnumber = rc->get_IntFlag("RUNNUMBER");
1349  std::cout << "Fun4AllServer: Runnumber forced to " << runnumber << " by RUNNUMBER IntFlag" << std::endl;
1350  }
1351  int iret = 0;
1352  int icnt = 0;
1353  int icnt_good = 0;
1354  std::vector<Fun4AllSyncManager *>::const_iterator iter;
1355  while (!iret)
1356  {
1357  int resetnodetree = 0;
1358  for (iter = SyncManagers.begin(); iter != SyncManagers.end(); ++iter)
1359  {
1360  if (Verbosity() >= VERBOSITY_MORE)
1361  {
1362  std::cout << "executing run for input master " << (*iter)->Name() << std::endl;
1363  }
1364  int retval = (*iter)->run(1);
1365  // if a new input file is opened during syncing and it contains
1366  // different nodes
1367  // as the previous one, the info in the nodes which are only in
1368  // the previous file will be carried to another event. We also
1369  // do not know under which topNode the input managers put
1370  // their data. This is why
1371  // the whole node tree is resetted whenever one of the Sync Managers
1372  // requires it.
1374  {
1375  resetnodetree = 1;
1376  }
1377  else
1378  {
1379  iret += retval;
1380  }
1381  }
1382  if (resetnodetree)
1383  {
1384  // if the node tree needs resetting, we just push the current
1385  // event(s) (which are all properly synced at this point)
1386  // back into the input managers and just read again.
1387  for (iter = SyncManagers.begin(); iter != SyncManagers.end(); ++iter)
1388  {
1389  (*iter)->PushBackInputMgrsEvents(1);
1390  }
1391  ResetNodeTree();
1392  continue; // go back to run loop
1393  }
1394  if (iret)
1395  {
1396  break;
1397  }
1398  int currentrun = 0;
1399  for (iter = SyncManagers.begin(); iter != SyncManagers.end(); ++iter)
1400  {
1401  int runno = (*iter)->CurrentRun();
1402  // std::cout << (*iter)->Name() << " run no: " << runno << std::endl;
1403  if (runno != 0)
1404  {
1405  if (currentrun == 0)
1406  {
1407  currentrun = runno;
1408  }
1409  else
1410  {
1411  if (currentrun != runno)
1412  {
1413  if (!(*iter)->MixRunsOk())
1414  {
1415  std::cout << "Mixing of Runs within same event is not supported" << std::endl;
1416  std::cout << "Here is the list of Sync Managers and their runnumbers:" << std::endl;
1417  std::vector<Fun4AllSyncManager *>::const_iterator syiter;
1418  for (syiter = SyncManagers.begin(); syiter != SyncManagers.end(); ++syiter)
1419  {
1420  std::cout << (*syiter)->Name() << " run number: " << (*syiter)->CurrentRun() << std::endl;
1421  }
1422  std::cout << "Exiting now" << std::endl;
1423  exit(1);
1424  }
1425  }
1426  }
1427  }
1428  }
1429  if (ifirst)
1430  {
1431  if (currentrun != runnumber && !run_number_forced) // use real run if not forced
1432  {
1433  runnumber = currentrun;
1434  }
1435  setRun(runnumber);
1437  ifirst = 0;
1438  }
1439  else if (!run_number_forced)
1440  {
1441  if (currentrun != runnumber)
1442  {
1443  EndRun(runnumber);
1444  runnumber = currentrun;
1445  setRun(runnumber);
1447  }
1448  }
1449  if (Verbosity() >= 1)
1450  {
1451  std::cout << "Fun4AllServer::run - processing event "
1452  << (icnt + 1) << " from run " << runnumber << std::endl;
1453  }
1454 
1455  if (icnt == 0 and Verbosity() > VERBOSITY_QUIET)
1456  {
1457  // increase verbosity for the first event in verbose modes
1458  int iverb = Verbosity();
1459  Verbosity(++iverb);
1460  }
1461 
1462  iret = process_event();
1463 
1464  if (icnt == 0 and Verbosity() > VERBOSITY_QUIET)
1465  {
1466  // increase verbosity for the first event in verbose modes
1467  int iverb = Verbosity();
1468  Verbosity(--iverb);
1469  }
1470 
1471  ++icnt; // completed one event processing
1472 
1473  if (require_nevents)
1474  {
1475  if (std::find(RetCodes.begin(),
1476  RetCodes.end(),
1477  static_cast<int>(Fun4AllReturnCodes::ABORTEVENT)) == RetCodes.end())
1478  {
1479  icnt_good++;
1480  }
1481  if (iret || (nevnts > 0 && icnt_good >= nevnts))
1482  {
1483  break;
1484  }
1485  }
1486  else if (iret || (nevnts > 0 && icnt >= nevnts))
1487  {
1488  break;
1489  }
1490  }
1491  return iret;
1492 }
1493 
1494 //_________________________________________________________________
1495 int Fun4AllServer::skip(const int nevnts)
1496 {
1497  int iret = 0;
1498  if (nevnts > 0) // do not execute for nevnts <= 0
1499  {
1500  std::vector<Fun4AllSyncManager *>::const_iterator iter;
1501  for (iter = SyncManagers.begin(); iter != SyncManagers.end(); ++iter)
1502  {
1503  iret += (*iter)->skip(nevnts);
1504  }
1505  eventcounter += nevnts; // update event counter so it reflects the number of events in the input
1506  }
1507  return iret;
1508 }
1509 
1510 //_________________________________________________________________
1512 {
1513  int iret = 0;
1514  std::vector<Fun4AllSyncManager *>::const_iterator iter;
1515  for (iter = SyncManagers.begin(); iter != SyncManagers.end(); ++iter)
1516  {
1517  iret += (*iter)->fileopen(managername, filename);
1518  }
1519  return iret;
1520 }
1521 
1522 int Fun4AllServer::BranchSelect(const std::string &managername, const std::string &branch, int iflag)
1523 {
1524  int iret = 0;
1525  std::vector<Fun4AllSyncManager *>::const_iterator iter;
1526  for (iter = SyncManagers.begin(); iter != SyncManagers.end(); ++iter)
1527  {
1528  iret += (*iter)->BranchSelect(managername, branch, iflag);
1529  }
1530  return iret;
1531 }
1532 
1533 int Fun4AllServer::BranchSelect(const std::string &branch, int iflag)
1534 {
1535  int iret = 0;
1536  std::vector<Fun4AllSyncManager *>::const_iterator iter;
1537  for (iter = SyncManagers.begin(); iter != SyncManagers.end(); ++iter)
1538  {
1539  iret += (*iter)->BranchSelect(branch, iflag);
1540  }
1541  return iret;
1542 }
1543 
1545 {
1546  int iret = 0;
1547  std::vector<Fun4AllSyncManager *>::const_iterator iter;
1548  for (iter = SyncManagers.begin(); iter != SyncManagers.end(); ++iter)
1549  {
1550  iret += (*iter)->setBranches(managername);
1551  }
1552  return iret;
1553 }
1554 
1556 {
1557  int iret = 0;
1558  std::vector<Fun4AllSyncManager *>::const_iterator iter;
1559  for (iter = SyncManagers.begin(); iter != SyncManagers.end(); ++iter)
1560  {
1561  iret += (*iter)->setBranches();
1562  }
1563  return iret;
1564 }
1565 
1566 int Fun4AllServer::fileclose(const std::string &managername)
1567 {
1568  int iret = 0;
1569  std::vector<Fun4AllSyncManager *>::const_iterator iter;
1570  for (iter = SyncManagers.begin(); iter != SyncManagers.end(); ++iter)
1571  {
1572  iret += (*iter)->fileclose(managername);
1573  }
1574  return iret;
1575 }
1576 
1578 {
1579  int iret = defaultSyncManager->SegmentNumber();
1580  return iret;
1581 }
1582 
1583 void Fun4AllServer::GetInputFullFileList(std::vector<std::string> &fnames) const
1584 {
1586  return;
1587 }
1588 
1589 unsigned
1590 Fun4AllServer::GetTopNodes(std::vector<std::string> &names) const
1591 {
1592  std::map<std::string, PHCompositeNode *>::const_iterator iter;
1593  for (iter = topnodemap.begin(); iter != topnodemap.end(); ++iter)
1594  {
1595  names.push_back(iter->first);
1596  }
1597  return names.size();
1598 }
1599 
1600 void Fun4AllServer::GetOutputManagerList(std::vector<std::string> &names) const
1601 {
1602  names.clear();
1603  std::vector<Fun4AllOutputManager *>::const_iterator iter;
1604  for (iter = OutputManager.begin(); iter != OutputManager.end(); ++iter)
1605  {
1606  names.push_back((*iter)->Name());
1607  }
1608  return;
1609 }
1610 
1611 void Fun4AllServer::GetModuleList(std::vector<std::string> &names) const
1612 {
1613  names.clear();
1614  std::vector<std::pair<SubsysReco *, PHCompositeNode *>>::const_iterator iter;
1615  for (iter = Subsystems.begin(); iter != Subsystems.end(); ++iter)
1616  {
1617  names.push_back((*iter).first->Name());
1618  }
1619  return;
1620 }
1621 
1623 {
1624  for (auto &syncman : SyncManagers)
1625  {
1626  if (syncman->Name() == newmaster->Name())
1627  {
1628  std::cout << "Input Master " << newmaster->Name()
1629  << " already registered" << std::endl;
1630  return -1;
1631  }
1632  }
1633  if (Verbosity() >= VERBOSITY_SOME)
1634  {
1635  std::cout << "Registering Input Master " << newmaster->Name() << std::endl;
1636  }
1637  SyncManagers.push_back(newmaster);
1638  return 0;
1639 }
1640 
1643 {
1644  if (name == "DefaultSyncManager")
1645  {
1646  return defaultSyncManager;
1647  }
1648  std::vector<Fun4AllSyncManager *>::iterator iter;
1649 
1650  for (iter = SyncManagers.begin(); iter != SyncManagers.end(); ++iter)
1651  {
1652  if ((*iter)->Name() == name)
1653  {
1654  return *iter;
1655  }
1656  }
1657  std::cout << "Could not find Input Master " << name << std::endl;
1658  return nullptr;
1659 }
1660 
1661 int Fun4AllServer::setRun(const int runno)
1662 {
1664  rc->set_IntFlag("RUNNUMBER", runno);
1665  if (!rc->FlagExist("TIMESTAMP"))
1666  {
1667  rc->set_uint64Flag("TIMESTAMP", runno);
1668  }
1669  std::cout << "Fun4AllServer::setRun(): run " << runno
1670  << " uses CDB TIMESTAMP " << rc->get_uint64Flag("TIMESTAMP")
1671  << std::endl;
1672  FrameWorkVars->SetBinContent(RUNNUMBERBIN, (Stat_t) runno);
1673  return 0;
1674 }
1675 
1677 {
1678  PHObject *obj = findNode::getClass<PHObject>(TopNode, name);
1679  if (obj)
1680  {
1681  obj->identify();
1682  }
1683  else
1684  {
1685  std::cout << "Could not locate node " << name
1686  << " or no PHObject Node" << std::endl;
1687  }
1688  return;
1689 }
1690 
1692 {
1693  std::map<const std::string, PHTimer>::const_iterator iter;
1694  PHTimer::PRINT(std::cout, "**");
1695  if (name.empty())
1696  {
1697  for (iter = timer_map.begin(); iter != timer_map.end(); ++iter)
1698  {
1699  iter->second.print_stat();
1700  }
1701  }
1702  else
1703  {
1704  iter = timer_map.find(name);
1705  if (iter != timer_map.end())
1706  {
1707  iter->second.print_stat();
1708  }
1709  else
1710  {
1711  std::cout << "No timer with name " << name << " found" << std::endl;
1712  std::cout << "Existing timers:" << std::endl;
1713  for (iter = timer_map.begin(); iter != timer_map.end(); ++iter)
1714  {
1715  std::cout << iter->first << std::endl;
1716  }
1717  }
1718  }
1719  return;
1720 }
1721 
1723 {
1724 #ifdef FFAMEMTRACKER
1726 #else
1727  std::cout << "PrintMemoryTracker called with " << name << " is disabled" << std::endl;
1728 #endif
1729  return;
1730 }