Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-06 08:17:17

0001 #include "Fun4AllServer.h"
0002 
0003 #include "Fun4AllDstOutputManager.h"
0004 #include "Fun4AllHistoBinDefs.h"
0005 #include "Fun4AllHistoManager.h"  // for Fun4AllHistoManager
0006 #include "Fun4AllMemoryTracker.h"
0007 #include "Fun4AllMonitoring.h"
0008 #include "Fun4AllOutputManager.h"
0009 #include "Fun4AllReturnCodes.h"
0010 #include "Fun4AllSyncManager.h"
0011 #include "SubsysReco.h"
0012 
0013 #include <phool/PHCompositeNode.h>
0014 #include <phool/PHNode.h>  // for PHNode
0015 #include <phool/PHNodeIterator.h>
0016 #include <phool/PHNodeReset.h>
0017 #include <phool/PHObject.h>
0018 #include <phool/PHPointerListIterator.h>
0019 #include <phool/PHTimeStamp.h>
0020 #include <phool/PHTimer.h>  // for PHTimer
0021 #include <phool/getClass.h>
0022 #include <phool/phool.h>
0023 #include <phool/recoConsts.h>
0024 
0025 #include <Rtypes.h>  // for kMAXSIGNALS
0026 #include <TDirectory.h>
0027 #include <TH1.h>
0028 #include <TROOT.h>
0029 #include <TSysEvtHandler.h>  // for ESignals
0030 
0031 #include <TSystem.h>
0032 
0033 #include <algorithm>
0034 #include <cstdlib>
0035 #include <exception>
0036 #include <iostream>
0037 #include <memory>  // for allocator_traits<>::value_type
0038 #include <sstream>
0039 
0040 // #define FFAMEMTRACKER
0041 
0042 Fun4AllServer *Fun4AllServer::__instance = nullptr;
0043 
0044 Fun4AllServer *Fun4AllServer::instance()
0045 {
0046   if (__instance)
0047   {
0048     return __instance;
0049   }
0050   __instance = new Fun4AllServer();
0051   return __instance;
0052 }
0053 
0054 Fun4AllServer::Fun4AllServer(const std::string &name)
0055   : Fun4AllBase(name)
0056 #ifdef FFAMEMTRACKER
0057   , ffamemtracker(Fun4AllMemoryTracker::instance())
0058 #endif
0059 {
0060   InitAll();
0061   return;
0062 }
0063 
0064 Fun4AllServer::~Fun4AllServer()
0065 {
0066   Reset();
0067   delete beginruntimestamp;
0068   while (Subsystems.begin() != Subsystems.end())
0069   {
0070     if (Verbosity() >= VERBOSITY_MORE)
0071     {
0072       Subsystems.back().first->Verbosity(Verbosity());
0073     }
0074     delete Subsystems.back().first;
0075     Subsystems.pop_back();
0076   }
0077   while (HistoManager.begin() != HistoManager.end())
0078   {
0079     if (Verbosity() >= VERBOSITY_MORE)
0080     {
0081       HistoManager.back()->Verbosity(Verbosity());
0082     }
0083     delete HistoManager.back();
0084     HistoManager.pop_back();
0085   }
0086   while (OutputManager.begin() != OutputManager.end())
0087   {
0088     if (Verbosity() >= VERBOSITY_MORE)
0089     {
0090       OutputManager.back()->Verbosity(Verbosity());
0091     }
0092     delete OutputManager.back();
0093     OutputManager.pop_back();
0094   }
0095   while (SyncManagers.begin() != SyncManagers.end())
0096   {
0097     SyncManagers.back()->Verbosity(Verbosity());
0098     delete SyncManagers.back();
0099     SyncManagers.pop_back();
0100   }
0101   while (topnodemap.begin() != topnodemap.end())
0102   {
0103     if (Verbosity() >= VERBOSITY_MORE)
0104     {
0105       topnodemap.begin()->second->print();
0106     }
0107     delete topnodemap.begin()->second;
0108     topnodemap.erase(topnodemap.begin());
0109   }
0110   while (TDirCollection.begin() != TDirCollection.end())
0111   {
0112     delete TDirCollection.back();
0113     TDirCollection.pop_back();
0114   }
0115   recoConsts *rc = recoConsts::instance();
0116   delete rc;
0117   delete ffamemtracker;
0118   __instance = nullptr;
0119   return;
0120 }
0121 
0122 void Fun4AllServer::InitAll()
0123 {
0124   // first remove stupid root signal handler to get
0125   // decent crashes with debuggable core file
0126   for (int i = 0; i < kMAXSIGNALS; i++)
0127   {
0128     gSystem->IgnoreSignal((ESignals) i);
0129   }
0130   Fun4AllMonitoring::instance()->Snapshot("StartUp");
0131   std::string histomanagername;
0132   histomanagername = Name() + "HISTOS";
0133   ServerHistoManager = new Fun4AllHistoManager(histomanagername);
0134   registerHistoManager(ServerHistoManager);
0135   double uplim = NFRAMEWORKBINS - 0.5;
0136   FrameWorkVars = new TH1D("FrameWorkVars", "FrameWorkVars", NFRAMEWORKBINS, -0.5, uplim);
0137   registerHisto("FrameWorkVars", FrameWorkVars);
0138   defaultSyncManager = new Fun4AllSyncManager("DefaultSyncManager");
0139   SyncManagers.push_back(defaultSyncManager);
0140   TopNode = new PHCompositeNode("TOP");
0141   topnodemap["TOP"] = TopNode;
0142   InitNodeTree(TopNode);
0143   return;
0144 }
0145 
0146 int Fun4AllServer::dumpHistos(const std::string &filename, const std::string &openmode)
0147 {
0148   int iret = 0;
0149   std::cout << "Fun4AllServer::dumpHistos() dumping histograms" << std::endl;
0150   if (!filename.empty())
0151   {
0152     ServerHistoManager->setOutfileName(filename);
0153   }
0154   std::vector<Fun4AllHistoManager *>::const_iterator hiter;
0155   for (hiter = HistoManager.begin(); hiter != HistoManager.end(); ++hiter)
0156   {
0157     iret += (*hiter)->dumpHistos("", openmode);
0158   }
0159   return iret;
0160 }
0161 
0162 bool Fun4AllServer::registerHisto(TNamed *h1d, const int replace)
0163 {
0164   return ServerHistoManager->registerHisto(h1d, replace);
0165 }
0166 
0167 bool Fun4AllServer::registerHisto(const std::string &hname, TNamed *h1d, const int replace)
0168 {
0169   return ServerHistoManager->registerHisto(hname, h1d, replace);
0170 }
0171 
0172 int Fun4AllServer::isHistoRegistered(const std::string &name) const
0173 {
0174   int iret = ServerHistoManager->isHistoRegistered(name);
0175   return iret;
0176 }
0177 
0178 int Fun4AllServer::registerSubsystem(SubsysReco *subsystem, const std::string &topnodename)
0179 {
0180   Fun4AllServer *se = Fun4AllServer::instance();
0181 
0182   // if somebody opens a TFile (or changes the gDirectory) in the ctor
0183   // we need to set it to a "known" directory
0184   gROOT->cd(default_Tdirectory.c_str());
0185   std::string currdir = gDirectory->GetPath();
0186   TDirectory *tmpdir = gDirectory;
0187   if (!tmpdir->FindObject(topnodename.c_str()))
0188   {
0189     tmpdir = tmpdir->mkdir(topnodename.c_str());
0190     if (!tmpdir)
0191     {
0192       std::cout << PHWHERE << " Error creating TDirectory topdir " << topnodename << std::endl;
0193       exit(1);
0194     }
0195     // store the TDir pointer so it can be cleaned up in the dtor
0196     // if one deletes it here the Histograms are dangling somewhere
0197     // in root (at least according to valgrind the delete doesn't work
0198     // properly anymore)
0199     TDirCollection.push_back(tmpdir);
0200   }
0201   gROOT->cd(topnodename.c_str());
0202   tmpdir = gDirectory;
0203   if (!tmpdir->FindObject(subsystem->Name().c_str()))
0204   {
0205     tmpdir = tmpdir->mkdir(subsystem->Name().c_str());
0206     if (!tmpdir)
0207     {
0208       std::cout << PHWHERE << "Error creating TDirectory subdir " << subsystem->Name() << std::endl;
0209       exit(1);
0210     }
0211     // store the TDir pointer so it can be cleaned up in the dtor
0212     // if one deletes it here the Histograms are dangling somewhere
0213     // in root
0214     TDirCollection.push_back(tmpdir);
0215   }
0216   PHCompositeNode *subsystopNode = se->topNode(topnodename);
0217   std::pair<SubsysReco *, PHCompositeNode *> newsubsyspair(subsystem, subsystopNode);
0218   int iret = 0;
0219   try
0220   {
0221 #ifdef FFAMEMTRACKER
0222     std::string memory_tracker_name = subsystem->Name() + "_" + topnodename;
0223     ffamemtracker->Start(memory_tracker_name, "SubsysReco");
0224 #endif
0225     if (Verbosity() >= 3)
0226     {
0227       std::cout << "Calling Init() for Subsystem " << subsystem->Name() << std::endl;
0228     }
0229     iret = subsystem->Init(subsystopNode);
0230 #ifdef FFAMEMTRACKER
0231     ffamemtracker->Stop(memory_tracker_name, "SubsysReco");
0232 #endif
0233   }
0234   catch (const std::exception &e)
0235   {
0236     std::cout << PHWHERE << " caught exception thrown during SubsysReco::Init() from "
0237               << subsystem->Name() << std::endl;
0238     std::cout << "error: " << e.what() << std::endl;
0239     exit(1);
0240   }
0241   catch (...)
0242   {
0243     std::cout << PHWHERE << " caught unknown type exception thrown during SubsysReco::Init() from "
0244               << subsystem->Name() << std::endl;
0245     exit(1);
0246   }
0247   gROOT->cd(currdir.c_str());
0248   if (iret)
0249   {
0250     if (iret == Fun4AllReturnCodes::DONOTREGISTERSUBSYSTEM)
0251     {
0252       if (Verbosity() >= VERBOSITY_SOME)
0253       {
0254         std::cout << "Not Registering Subsystem " << subsystem->Name() << std::endl;
0255       }
0256       return 0;
0257     }
0258     std::cout << PHWHERE << " Error from Init() method by "
0259               << subsystem->Name() << ", return code: " << iret << std::endl;
0260     return iret;
0261   }
0262   if (Verbosity() >= VERBOSITY_SOME)
0263   {
0264     std::cout << "Registering Subsystem " << subsystem->Name() << std::endl;
0265   }
0266   Subsystems.push_back(newsubsyspair);
0267   std::string timer_name;
0268   timer_name = subsystem->Name() + "_" + topnodename;
0269   PHTimer timer(timer_name);
0270   if (timer_map.find(timer_name) == timer_map.end())
0271   {
0272     timer_map.insert(make_pair(timer_name, timer));
0273   }
0274   RetCodes.push_back(iret);  // vector with return codes
0275   return 0;
0276 }
0277 
0278 int Fun4AllServer::unregisterSubsystem(SubsysReco *subsystem)
0279 {
0280   std::pair<SubsysReco *, PHCompositeNode *> subsyspair(subsystem, 0);
0281   DeleteSubsystems.push_back(subsyspair);
0282   unregistersubsystem = 1;
0283   return 0;
0284 }
0285 
0286 int Fun4AllServer::unregisterSubsystemsNow()
0287 {
0288   std::vector<std::pair<SubsysReco *, PHCompositeNode *>>::iterator sysiter;
0289   std::vector<std::pair<SubsysReco *, PHCompositeNode *>>::iterator removeiter;
0290   for (removeiter = DeleteSubsystems.begin();
0291        removeiter != DeleteSubsystems.end();
0292        ++removeiter)
0293   {
0294     int index = 0;
0295     int foundit = 0;
0296     for (sysiter = Subsystems.begin(); sysiter != Subsystems.end(); ++sysiter)
0297     {
0298       if ((*sysiter).first == (*removeiter).first)
0299       {
0300         foundit = 1;
0301         break;
0302       }
0303       index++;
0304     }
0305     if (!foundit)
0306     {
0307       std::cout << "unregisterSubsystem: Could not find SubsysReco "
0308                 << (*removeiter).first->Name()
0309                 << " in Fun4All Reco Module list" << std::endl;
0310       delete (*removeiter).first;
0311       continue;
0312     }
0313     if (Verbosity() >= VERBOSITY_MORE)
0314     {
0315       std::cout << "Removing Subsystem: " << (*removeiter).first->Name()
0316                 << " at index " << index << std::endl;
0317     }
0318     Subsystems.erase(Subsystems.begin() + index);
0319     delete (*removeiter).first;
0320     // also update the vector with return codes
0321     RetCodes.erase(RetCodes.begin() + index);
0322     std::vector<Fun4AllOutputManager *>::iterator outiter;
0323     for (outiter = OutputManager.begin(); outiter != OutputManager.end(); ++outiter)
0324     {
0325       UpdateEventSelector(*outiter);
0326     }
0327   }
0328   unregistersubsystem = 0;
0329   DeleteSubsystems.clear();
0330   return 0;
0331 }
0332 
0333 SubsysReco *
0334 Fun4AllServer::getSubsysReco(const std::string &name)
0335 {
0336   std::vector<std::pair<SubsysReco *, PHCompositeNode *>>::iterator sysiter;
0337   for (sysiter = Subsystems.begin(); sysiter != Subsystems.end(); ++sysiter)
0338   {
0339     if ((*sysiter).first->Name() == name)
0340     {
0341       if (Verbosity() >= VERBOSITY_EVEN_MORE)
0342       {
0343         std::cout << "Found Subsystem " << name << std::endl;
0344       }
0345       return (*sysiter).first;
0346     }
0347   }
0348   std::cout << "Could not find SubsysReco " << name << std::endl;
0349   return nullptr;
0350 }
0351 
0352 int Fun4AllServer::AddComplaint(const std::string &complaint, const std::string &remedy)
0353 {
0354   ScreamEveryEvent++;
0355   std::string separatorstring = "------------------------------";
0356   std::ostringstream complaintno;
0357   complaintno << "Problem No " << ScreamEveryEvent;
0358 
0359   ComplaintList.push_back(separatorstring);
0360   ComplaintList.push_back(complaintno.str());
0361   ComplaintList.push_back(complaint);
0362   ComplaintList.emplace_back(" ");
0363   ComplaintList.emplace_back("Remedy:");
0364   ComplaintList.push_back(remedy);
0365   ComplaintList.push_back(separatorstring);
0366   return 0;
0367 }
0368 
0369 int Fun4AllServer::registerOutputManager(Fun4AllOutputManager *manager)
0370 {
0371   std::vector<Fun4AllOutputManager *>::iterator iter;
0372   for (iter = OutputManager.begin(); iter != OutputManager.end(); ++iter)
0373   {
0374     if ((*iter)->Name() == manager->Name())
0375     {
0376       std::cout << "OutputManager " << manager->Name() << " allready in list" << std::endl;
0377       return -1;
0378     }
0379   }
0380   if (Verbosity() >= VERBOSITY_SOME)
0381   {
0382     std::cout << "Registering OutputManager " << manager->Name() << std::endl;
0383   }
0384   UpdateEventSelector(manager);
0385   OutputManager.push_back(manager);
0386   return 0;
0387 }
0388 
0389 int Fun4AllServer::UpdateEventSelector(Fun4AllOutputManager *manager)
0390 {
0391   std::vector<std::string>::iterator striter;
0392   std::vector<std::pair<SubsysReco *, PHCompositeNode *>>::const_iterator subsysiter;
0393 
0394 tryagain:
0395   manager->RecoModuleIndex()->clear();
0396   for (striter = manager->EventSelector()->begin(); striter != manager->EventSelector()->end(); ++striter)
0397   {
0398     if (Verbosity() >= VERBOSITY_EVEN_MORE)
0399     {
0400       std::cout << PHWHERE << "striter: " << *striter << std::endl;
0401     }
0402     unsigned index = 0;
0403     int found = 0;
0404     for (subsysiter = Subsystems.begin(); subsysiter != Subsystems.end(); ++subsysiter)
0405     {
0406       if (*striter == (*subsysiter).first->Name())
0407       {
0408         manager->RecoModuleIndex()->push_back(index);
0409         if (Verbosity() >= VERBOSITY_EVEN_MORE)
0410         {
0411           std::cout << PHWHERE << "setting RecoModuleIndex to " << index << std::endl;
0412         }
0413         found = 1;
0414         break;
0415       }
0416       index++;
0417     }
0418     if (!found)
0419     {
0420       std::cout << "Could not find module " << *striter
0421                 << ", removing it from list of event selector modules" << std::endl;
0422       manager->EventSelector()->erase(striter);
0423       // NOLINTNEXTLINE(hicpp-avoid-goto)
0424       goto tryagain;
0425     }
0426   }
0427   return 0;
0428 }
0429 
0430 Fun4AllOutputManager *
0431 Fun4AllServer::getOutputManager(const std::string &name)
0432 {
0433   std::vector<Fun4AllOutputManager *>::iterator iter;
0434   for (iter = OutputManager.begin(); iter != OutputManager.end(); ++iter)
0435   {
0436     if (name == (*iter)->Name())
0437     {
0438       if (Verbosity() >= VERBOSITY_EVEN_MORE)
0439       {
0440         std::cout << "Found OutputManager " << name << std::endl;
0441       }
0442       return *iter;
0443     }
0444   }
0445   std::cout << "Could not find OutputManager" << name << std::endl;
0446   return nullptr;
0447 }
0448 
0449 Fun4AllHistoManager *
0450 Fun4AllServer::getHistoManager(const std::string &name)
0451 {
0452   std::vector<Fun4AllHistoManager *>::iterator iter;
0453   for (iter = HistoManager.begin(); iter != HistoManager.end(); ++iter)
0454   {
0455     if ((*iter)->Name() == name)
0456     {
0457       if (Verbosity() >= VERBOSITY_EVEN_MORE)
0458       {
0459         std::cout << "Found HistoManager " << name << std::endl;
0460       }
0461       return *iter;
0462     }
0463   }
0464   if (Verbosity() >= VERBOSITY_MORE)
0465   {
0466     std::cout << "Could not find HistoManager " << name << std::endl;
0467   }
0468   return nullptr;
0469 }
0470 
0471 int Fun4AllServer::registerHistoManager(Fun4AllHistoManager *manager)
0472 {
0473   std::vector<Fun4AllHistoManager *>::iterator iter;
0474   for (iter = HistoManager.begin(); iter != HistoManager.end(); ++iter)
0475   {
0476     if ((*iter)->Name() == manager->Name())
0477     {
0478       std::cout << "HistoManager " << manager->Name() << " allready in list" << std::endl;
0479       return -1;
0480     }
0481   }
0482   if (Verbosity() >= VERBOSITY_SOME)
0483   {
0484     std::cout << "Registering HistoManager " << manager->Name() << std::endl;
0485   }
0486   HistoManager.push_back(manager);
0487   return 0;
0488 }
0489 
0490 TNamed *
0491 Fun4AllServer::getHisto(const unsigned int ihisto) const
0492 {
0493   return ServerHistoManager->getHisto(ihisto);
0494 }
0495 
0496 std::string
0497 Fun4AllServer::getHistoName(const unsigned int ihisto) const
0498 {
0499   return (ServerHistoManager->getHistoName(ihisto));
0500 }
0501 
0502 TNamed *Fun4AllServer::getHisto(const std::string &hname) const
0503 {
0504   return (ServerHistoManager->getHisto(hname));
0505 }
0506 
0507 int Fun4AllServer::process_event()
0508 {
0509   eventcounter++;
0510   unsigned icnt = 0;
0511   int eventbad = 0;
0512   if (ScreamEveryEvent)
0513   {
0514     std::cout << "*******************************************************************************" << std::endl;
0515     std::cout << "*******************************************************************************" << std::endl;
0516     std::cout << "*******************************************************************************" << std::endl;
0517     std::cout << "Now that I have your attention, please fix the following "
0518               << ScreamEveryEvent << " problem(s):" << std::endl;
0519     std::vector<std::string>::const_iterator viter;
0520     for (viter = ComplaintList.begin(); viter != ComplaintList.end(); ++viter)
0521     {
0522       std::cout << *viter << std::endl;
0523     }
0524     std::cout << " " << std::endl;
0525     std::cout << "*******************************************************************************" << std::endl;
0526     std::cout << "*******************************************************************************" << std::endl;
0527     std::cout << "*******************************************************************************" << std::endl;
0528   }
0529   if (unregistersubsystem)
0530   {
0531     unregisterSubsystemsNow();
0532   }
0533   gROOT->cd(default_Tdirectory.c_str());
0534   std::string currdir = gDirectory->GetPath();
0535   for (auto &Subsystem : Subsystems)
0536   {
0537     if (Verbosity() >= VERBOSITY_MORE)
0538     {
0539       std::cout << "Fun4AllServer::process_event processing " << Subsystem.first->Name() << std::endl;
0540     }
0541     std::string newdirname = Subsystem.second->getName() + "/" + Subsystem.first->Name();
0542     if (!gROOT->cd(newdirname.c_str()))
0543     {
0544       std::cout << PHWHERE << "Unexpected TDirectory Problem cd'ing to "
0545                 << Subsystem.second->getName()
0546                 << " - send e-mail to off-l with your macro" << std::endl;
0547       exit(1);
0548     }
0549     else
0550     {
0551       if (Verbosity() >= VERBOSITY_EVEN_MORE)
0552       {
0553         std::cout << "process_event: cded to " << newdirname << std::endl;
0554       }
0555     }
0556 
0557     PHTimer subsystem_timer("SubsystemTimer");
0558     subsystem_timer.restart();
0559 
0560     try
0561     {
0562       std::string timer_name;
0563       timer_name = Subsystem.first->Name() + "_" + Subsystem.second->getName();
0564       std::map<const std::string, PHTimer>::iterator titer = timer_map.find(timer_name);
0565       bool timer_found = false;
0566       if (titer != timer_map.end())
0567       {
0568         timer_found = true;
0569         titer->second.restart();
0570       }
0571       else
0572       {
0573         std::cout << "could not find timer for " << timer_name << std::endl;
0574       }
0575 #ifdef FFAMEMTRACKER
0576       ffamemtracker->Start(timer_name, "SubsysReco");
0577       ffamemtracker->Snapshot("Fun4AllServerProcessEvent");
0578 #endif
0579       int retcode = Subsystem.first->process_event(Subsystem.second);
0580 #ifdef FFAMEMTRACKER
0581       ffamemtracker->Snapshot("Fun4AllServerProcessEvent");
0582 #endif
0583       // we have observed an index overflow in RetCodes. I assume it is some
0584       // memory corruption elsewhere which hits the icnt variable. Rather than
0585       // the previous [], use at() which does bounds checking and throws an
0586       // exception which will allow us to catch this and print out icnt and the size
0587       try
0588       {
0589         RetCodes.at(icnt) = retcode;
0590       }
0591       catch (const std::exception &e)
0592       {
0593         std::cout << PHWHERE << " caught exception thrown during RetCodes.at(icnt)" << std::endl;
0594         std::cout << "RetCodes.size(): " << RetCodes.size() << ", icnt: " << icnt << std::endl;
0595         std::cout << "error: " << e.what() << std::endl;
0596         gSystem->Exit(1);
0597       }
0598       if (timer_found)
0599       {
0600         titer->second.stop();
0601       }
0602 #ifdef FFAMEMTRACKER
0603       ffamemtracker->Stop(timer_name, "SubsysReco");
0604 #endif
0605     }
0606     catch (const std::exception &e)
0607     {
0608       std::cout << PHWHERE << " caught exception thrown during process_event from "
0609                 << Subsystem.first->Name() << std::endl;
0610       std::cout << "error: " << e.what() << std::endl;
0611       gSystem->Exit(1);
0612     }
0613     catch (...)
0614     {
0615       std::cout << PHWHERE << " caught unknown type exception thrown during process_event from "
0616                 << Subsystem.first->Name() << std::endl;
0617       exit(1);
0618     }
0619     if (RetCodes[icnt])
0620     {
0621       if (RetCodes[icnt] == Fun4AllReturnCodes::DISCARDEVENT)
0622       {
0623         if (Verbosity() >= VERBOSITY_EVEN_MORE)
0624         {
0625           std::cout << "Fun4AllServer::Discard Event by " << Subsystem.first->Name() << std::endl;
0626         }
0627       }
0628       else if (RetCodes[icnt] == Fun4AllReturnCodes::ABORTEVENT)
0629       {
0630         retcodesmap[Fun4AllReturnCodes::ABORTEVENT]++;
0631         eventbad = 1;
0632         if (Verbosity() >= VERBOSITY_MORE)
0633         {
0634           std::cout << "Fun4AllServer::Abort Event by " << Subsystem.first->Name() << std::endl;
0635         }
0636         break;
0637       }
0638       else if (RetCodes[icnt] == Fun4AllReturnCodes::ABORTRUN)
0639       {
0640         retcodesmap[Fun4AllReturnCodes::ABORTRUN]++;
0641         std::cout << "Fun4AllServer::Abort Run by " << Subsystem.first->Name() << std::endl;
0642         return Fun4AllReturnCodes::ABORTRUN;
0643       }
0644       else if (RetCodes[icnt] == Fun4AllReturnCodes::ABORTPROCESSING)
0645       {
0646         eventbad = 1;
0647         retcodesmap[Fun4AllReturnCodes::ABORTPROCESSING]++;
0648         std::cout << "Fun4AllServer::Abort Processing by " << Subsystem.first->Name() << std::endl;
0649         return Fun4AllReturnCodes::ABORTPROCESSING;
0650       }
0651       else
0652       {
0653         std::cout << "Fun4AllServer::Unknown return code: "
0654                   << RetCodes[icnt] << " from process_event method of "
0655                   << Subsystem.first->Name() << std::endl;
0656         std::cout << "This smells like an uninitialized return code and" << std::endl;
0657         std::cout << "it is too dangerous to continue, this Run will be aborted" << std::endl;
0658         std::cout << "If you do not know how to fix this please send mail to" << std::endl;
0659         std::cout << "phenix-off-l with this message" << std::endl;
0660         return Fun4AllReturnCodes::ABORTRUN;
0661       }
0662     }
0663     subsystem_timer.stop();
0664     double TimeSubsystem = subsystem_timer.elapsed();
0665     if (Verbosity() >= VERBOSITY_MORE)
0666     {
0667       std::cout << "Fun4AllServer::process_event processing " << Subsystem.first->Name()
0668                 << " processing total time: " << TimeSubsystem << " ms" << std::endl;
0669     }
0670     icnt++;
0671   }
0672   if (!eventbad)
0673   {
0674     retcodesmap[Fun4AllReturnCodes::EVENT_OK]++;
0675   }
0676 
0677   gROOT->cd(currdir.c_str());
0678   bool writing = false;
0679   int segment = std::numeric_limits<int>::min();
0680   //  mainIter.print();
0681   if (!OutputManager.empty() && !eventbad)  // there are registered IO managers and
0682   // the event is not flagged bad
0683   {
0684     PHNodeIterator iter(TopNode);
0685     PHCompositeNode *dstNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "DST"));
0686 
0687     if (dstNode)
0688     {
0689       // check if we have same number of nodes. After first event is
0690       // written out root I/O doesn't permit adding nodes, otherwise
0691       // events get out of sync
0692       static int first = 1;
0693       int newcount = CountOutNodes(dstNode);
0694       if (first)
0695       {
0696         first = 0;
0697         OutNodeCount = newcount;      // save number of nodes before first write
0698         MakeNodesTransient(dstNode);  // make all nodes transient before 1st write in case someone sneaked a node in at the first event
0699       }
0700 
0701       if (OutNodeCount != newcount)
0702       {
0703         iter.print();
0704         std::cout << PHWHERE << " FATAL: Someone changed the number of Output Nodes on the fly, from " << OutNodeCount << " to " << newcount << std::endl;
0705         exit(1);
0706       }
0707       std::vector<Fun4AllOutputManager *>::iterator iterOutMan;
0708 
0709       for (iterOutMan = OutputManager.begin(); iterOutMan != OutputManager.end(); ++iterOutMan)
0710       {
0711         if (!(*iterOutMan)->DoNotWriteEvent(&RetCodes))
0712         {
0713           if (Verbosity() >= VERBOSITY_MORE)
0714           {
0715             std::cout << "Writing Event for " << (*iterOutMan)->Name() << std::endl;
0716           }
0717 #ifdef FFAMEMTRACKER
0718           ffamemtracker->Snapshot("Fun4AllServerOutputManager");
0719           ffamemtracker->Start((*iterOutMan)->Name(), "OutputManager");
0720 #endif
0721           (*iterOutMan)->WriteGeneric(dstNode);
0722 #ifdef FFAMEMTRACKER
0723           ffamemtracker->Stop((*iterOutMan)->Name(), "OutputManager");
0724           ffamemtracker->Snapshot("Fun4AllServerOutputManager");
0725 #endif
0726           if ((*iterOutMan)->EventsWritten() >= (*iterOutMan)->GetNEvents())
0727           {
0728             if (Verbosity() > 0)
0729             {
0730               std::cout << PHWHERE << (*iterOutMan)->Name() << " wrote " << (*iterOutMan)->EventsWritten()
0731                         << " events, closing " << (*iterOutMan)->OutFileName() << std::endl;
0732             }
0733             PHNodeIterator nodeiter(TopNode);
0734             PHCompositeNode *runNode = dynamic_cast<PHCompositeNode *>(nodeiter.findFirst("PHCompositeNode", "RUN"));
0735             MakeNodesTransient(runNode);  // make all nodes transient by default
0736             (*iterOutMan)->WriteNode(runNode);
0737             (*iterOutMan)->RunAfterClosing();
0738             segment = (*iterOutMan)->Segment();
0739             writing = true;
0740           }
0741         }
0742         else
0743         {
0744           if (Verbosity() >= VERBOSITY_MORE)
0745           {
0746             std::cout << "Not Writing Event for " << (*iterOutMan)->Name() << std::endl;
0747           }
0748         }
0749       }
0750     }
0751   }
0752   if (!HistoManager.empty() && !eventbad && writing)
0753   {
0754     for (const auto &histit : HistoManager)
0755     {
0756       if ((*histit).dumpHistoSegments())
0757       {
0758         if (Verbosity() > 0)
0759         {
0760           std::cout << PHWHERE << (*histit).Name() << " wrote events, closing " << (*histit).OutFileName() << std::endl;
0761         }
0762         // This is -1 because the segment is initially determined in the first event of a
0763         // segment from the DST, then incremented. So it is always 1 ahead of the histos
0764         (*histit).segment(segment - 1);
0765         (*histit).dumpHistos();
0766         (*histit).RunAfterClosing();
0767         (*histit).Reset();
0768       }
0769     }
0770   }
0771   for (auto &Subsystem : Subsystems)
0772   {
0773     if (Verbosity() >= VERBOSITY_EVEN_MORE)
0774     {
0775       std::cout << "Fun4AllServer::process_event Resetting Event " << Subsystem.first->Name() << std::endl;
0776     }
0777     Subsystem.first->ResetEvent(Subsystem.second);
0778   }
0779   for (auto &syncman : SyncManagers)
0780   {
0781     if (Verbosity() >= VERBOSITY_EVEN_MORE)
0782     {
0783       std::cout << "Fun4AllServer::process_event Resetting Event for Sync Manager " << syncman->Name() << std::endl;
0784     }
0785     syncman->ResetEvent();
0786   }
0787   Fun4AllMonitoring::instance()->Snapshot("Event");
0788   ResetNodeTree();
0789   return 0;
0790 }
0791 
0792 int Fun4AllServer::ResetNodeTree()
0793 {
0794   std::vector<std::string> ResetNodeList;
0795   ResetNodeList.emplace_back("DST");
0796   PHNodeReset reset;
0797   reset.Verbosity(Verbosity() > 2 ? Verbosity() - 2 : 0);  // one lower verbosity level than Fun4AllServer
0798   std::map<std::string, PHCompositeNode *>::const_iterator iter;
0799   for (iter = topnodemap.begin(); iter != topnodemap.end(); ++iter)
0800   {
0801     PHNodeIterator mainIter((*iter).second);
0802     for (const auto &nodename : ResetNodeList)
0803     {
0804       if (mainIter.cd(nodename))
0805       {
0806         mainIter.forEach(reset);
0807         mainIter.cd();
0808       }
0809     }
0810   }
0811   return 0;  // anything except 0 would abort the event loop in pmonitor
0812 }
0813 
0814 int Fun4AllServer::Reset()
0815 {
0816   int i = 0;
0817   std::vector<std::pair<SubsysReco *, PHCompositeNode *>>::iterator iter;
0818   for (iter = Subsystems.begin(); iter != Subsystems.end(); ++iter)
0819   {
0820     if (Verbosity() >= VERBOSITY_EVEN_MORE)
0821     {
0822       std::cout << "Fun4AllServer::Reset Resetting " << (*iter).first->Name() << std::endl;
0823     }
0824     i += (*iter).first->Reset((*iter).second);
0825   }
0826   std::vector<Fun4AllHistoManager *>::iterator hiter;
0827   for (hiter = HistoManager.begin(); hiter != HistoManager.end(); ++hiter)
0828   {
0829     (*hiter)->Reset();
0830   }
0831   return i;
0832 }
0833 
0834 int Fun4AllServer::BeginRunTimeStamp(PHTimeStamp &TimeStp)
0835 {
0836   beginruntimestamp = new PHTimeStamp(TimeStp);
0837   std::cout << "Setting BOR timestamp to ";
0838   beginruntimestamp->print();
0839   std::cout << std::endl;
0840   bortime_override = 1;
0841   return 0;
0842 }
0843 
0844 int Fun4AllServer::BeginRun(const int runno)
0845 {
0846   eventcounter = 0;  // reset event counter for every new run
0847 #ifdef FFAMEMTRACKER
0848   ffamemtracker->Snapshot("Fun4AllServerBeginRun");
0849 #endif
0850   if (!bortime_override)
0851   {
0852     delete beginruntimestamp;
0853 
0854     beginruntimestamp = new PHTimeStamp();
0855   }
0856   else
0857   {
0858     std::cout << "overriding BOR timestamp by ";
0859     beginruntimestamp->print();
0860     std::cout << std::endl;
0861     // rc->set_TimeStamp(*beginruntimestamp);
0862   }
0863   if (Verbosity() >= VERBOSITY_SOME)
0864   {
0865     std::cout << "Fun4AllServer::BeginRun: Run number " << runno << " uses RECO TIMESTAMP: ";
0866     beginruntimestamp->print();
0867     std::cout << std::endl;
0868   }
0869   std::vector<std::pair<SubsysReco *, PHCompositeNode *>>::iterator iter;
0870   int iret = 0;
0871 
0872   // check if any registered SubsysReco wants to be dropped and
0873   // remove it from the list before its BeginRun is executed
0874   if (unregistersubsystem)
0875   {
0876     unregisterSubsystemsNow();
0877   }
0878 
0879   // we have to do the same TDirectory games as in the Init methods
0880   // save the current dir, cd to the subsystem name dir (which was
0881   // created in init) call the InitRun of the module and cd back
0882 
0883   gROOT->cd(default_Tdirectory.c_str());
0884   std::string currdir = gDirectory->GetPath();
0885 
0886   for (iter = Subsystems.begin(); iter != Subsystems.end(); ++iter)
0887   {
0888     iret = BeginRunSubsystem(*iter);
0889   }
0890   for (; !NewSubsystems.empty(); NewSubsystems.pop_front())
0891   {
0892     registerSubsystem((NewSubsystems.front()).first, (NewSubsystems.front()).second);
0893     BeginRunSubsystem(std::make_pair(NewSubsystems.front().first, topNode(NewSubsystems.front().second)));
0894   }
0895   gROOT->cd(currdir.c_str());
0896   // print out all node trees
0897   Print("NODETREE");
0898 #ifdef FFAMEMTRACKER
0899   ffamemtracker->Snapshot("Fun4AllServerBeginRun");
0900 #endif
0901   return iret;
0902 }
0903 
0904 int Fun4AllServer::BeginRunSubsystem(const std::pair<SubsysReco *, PHCompositeNode *> &subsys)
0905 {
0906   int iret = 0;
0907   std::string newdirname = subsys.second->getName() + "/" + subsys.first->Name();
0908   if (!gROOT->cd(newdirname.c_str()))
0909   {
0910     std::cout << PHWHERE << "Unexpected TDirectory Problem cd'ing to "
0911               << subsys.second->getName()
0912               << " - send e-mail to off-l with your macro" << std::endl;
0913     exit(1);
0914   }
0915   else
0916   {
0917     if (Verbosity() >= VERBOSITY_EVEN_MORE)
0918     {
0919       std::cout << "BeginRun: cded to " << newdirname << std::endl;
0920     }
0921   }
0922 
0923   if (Verbosity() >= VERBOSITY_SOME)
0924   {
0925     std::cout << "Fun4AllServer::BeginRun: InitRun for " << subsys.first->Name() << std::endl;
0926   }
0927   try
0928   {
0929 #ifdef FFAMEMTRACKER
0930     ffamemtracker->Start(subsys.first->Name(), "SubsysReco");
0931 #endif
0932     iret = subsys.first->InitRun(subsys.second);
0933 #ifdef FFAMEMTRACKER
0934     ffamemtracker->Stop(subsys.first->Name(), "SubsysReco");
0935 #endif
0936   }
0937   catch (const std::exception &e)
0938   {
0939     std::cout << PHWHERE << " caught exception thrown during SubsysReco::InitRun() from "
0940               << subsys.first->Name() << std::endl;
0941     std::cout << "error: " << e.what() << std::endl;
0942     exit(1);
0943   }
0944   catch (...)
0945   {
0946     std::cout << PHWHERE << " caught unknown type exception thrown during SubsysReco::InitRun() from "
0947               << subsys.first->Name() << std::endl;
0948     exit(1);
0949   }
0950 
0951   if (iret == Fun4AllReturnCodes::ABORTRUN)
0952   {
0953     std::cout << PHWHERE << "Module " << subsys.first->Name() << " issued Abort Run, exiting" << std::endl;
0954     exit(-1);
0955   }
0956   else if (iret != Fun4AllReturnCodes::EVENT_OK)
0957   {
0958     std::cout << PHWHERE << "Module " << subsys.first->Name() << " issued non Fun4AllReturnCodes::EVENT_OK return code " << iret << " in InitRun()" << std::endl;
0959     exit(-2);
0960   }
0961   return iret;
0962 }
0963 
0964 int Fun4AllServer::CountOutNodes(PHCompositeNode *startNode)
0965 {
0966   int icount = 0;
0967   icount = CountOutNodesRecursive(startNode, icount);
0968   return icount;
0969 }
0970 
0971 // NOLINTNEXTLINE(misc-no-recursion)
0972 int Fun4AllServer::CountOutNodesRecursive(PHCompositeNode *startNode, const int icount)
0973 {
0974   PHNodeIterator nodeiter(startNode);
0975   PHPointerListIterator<PHNode> iterat(nodeiter.ls());
0976   PHNode *thisNode;
0977   int icnt = icount;
0978   while ((thisNode = iterat()))
0979   {
0980     if ((thisNode->getType() == "PHCompositeNode"))
0981     {
0982       // NOLINTNEXTLINE(cppcoreguidelines-pro-type-static-cast-downcast)
0983       icnt = CountOutNodesRecursive(static_cast<PHCompositeNode *>(thisNode), icnt);  // if this is a CompositeNode do this trick again
0984     }
0985     else
0986     {
0987       icnt++;
0988       if (Verbosity() >= VERBOSITY_EVEN_MORE)
0989       {
0990         std::cout << thisNode->getName() << ", Node Count: " << icnt << std::endl;
0991       }
0992     }
0993   }
0994   return icnt;
0995 }
0996 
0997 // NOLINTNEXTLINE(misc-no-recursion)
0998 int Fun4AllServer::MakeNodesTransient(PHCompositeNode *startNode)
0999 {
1000   PHNodeIterator nodeiter(startNode);
1001   PHPointerListIterator<PHNode> iterat(nodeiter.ls());
1002   PHNode *thisNode;
1003   while ((thisNode = iterat()))
1004   {
1005     if ((thisNode->getType() == "PHCompositeNode"))
1006     {
1007       //NOLINTNEXTLINE(cppcoreguidelines-pro-type-static-cast-downcast)
1008       MakeNodesTransient(static_cast<PHCompositeNode *>(thisNode));  // if this is a CompositeNode do this trick again
1009     }
1010     else
1011     {
1012       thisNode->makeTransient();
1013     }
1014   }
1015   return 0;
1016 }
1017 
1018 int Fun4AllServer::MakeNodesPersistent(PHCompositeNode *startNode) // NOLINT(misc-no-recursion)
1019 {
1020   PHNodeIterator nodeiter(startNode);
1021   PHPointerListIterator<PHNode> iterat(nodeiter.ls());
1022   PHNode *thisNode;
1023   while ((thisNode = iterat()))
1024   {
1025     if ((thisNode->getType() == "PHCompositeNode"))
1026     {
1027       // NOLINTNEXTLINE(cppcoreguidelines-pro-type-static-cast-downcast)
1028       MakeNodesPersistent(static_cast<PHCompositeNode *>(thisNode));  // if this is a CompositeNode do this trick again
1029     }
1030     else
1031     {
1032       thisNode->makePersistent();
1033     }
1034   }
1035   return 0;
1036 }
1037 
1038 int Fun4AllServer::EndRun(const int runno)
1039 {
1040   std::vector<std::pair<SubsysReco *, PHCompositeNode *>>::iterator iter;
1041   gROOT->cd(default_Tdirectory.c_str());
1042   std::string currdir = gDirectory->GetPath();
1043   for (iter = Subsystems.begin(); iter != Subsystems.end(); ++iter)
1044   {
1045     if (Verbosity() >= VERBOSITY_MORE)
1046     {
1047       std::cout << "Fun4AllServer::EndRun: EndRun("
1048                 << runno << ") for " << (*iter).first->Name() << std::endl;
1049     }
1050     std::string newdirname = (*iter).second->getName() + "/" + (*iter).first->Name();
1051     if (!gROOT->cd(newdirname.c_str()))
1052     {
1053       std::cout << PHWHERE << "Unexpected TDirectory Problem cd'ing to "
1054                 << (*iter).second->getName()
1055                 << " - send e-mail to off-l with your macro" << std::endl;
1056       exit(1);
1057     }
1058     else
1059     {
1060       if (Verbosity() >= VERBOSITY_EVEN_MORE)
1061       {
1062         std::cout << "EndRun: cded to " << newdirname << std::endl;
1063       }
1064     }
1065     try
1066     {
1067       (*iter).first->EndRun(runno);
1068     }
1069     catch (const std::exception &e)
1070     {
1071       std::cout << PHWHERE << " caught exception thrown during SubsysReco::EndRun() from "
1072                 << (*iter).first->Name() << std::endl;
1073       std::cout << "error: " << e.what() << std::endl;
1074       exit(1);
1075     }
1076     catch (...)
1077     {
1078       std::cout << PHWHERE << " caught unknown type exception thrown during SubsysReco::EndRun() from "
1079                 << (*iter).first->Name() << std::endl;
1080       exit(1);
1081     }
1082   }
1083   gROOT->cd(currdir.c_str());
1084 
1085   return 0;
1086 }
1087 
1088 int Fun4AllServer::End()
1089 {
1090   recoConsts *rc = recoConsts::instance();
1091   EndRun(rc->get_IntFlag("RUNNUMBER"));  // call SubsysReco EndRun methods for current run
1092   int i = 0;
1093   std::vector<std::pair<SubsysReco *, PHCompositeNode *>>::iterator iter;
1094   gROOT->cd(default_Tdirectory.c_str());
1095   std::string currdir = gDirectory->GetPath();
1096   for (iter = Subsystems.begin(); iter != Subsystems.end(); ++iter)
1097   {
1098     if (Verbosity() >= VERBOSITY_SOME)
1099     {
1100       std::cout << "Fun4AllServer::End: End for " << (*iter).first->Name() << std::endl;
1101     }
1102     std::string newdirname = (*iter).second->getName() + "/" + (*iter).first->Name();
1103     if (!gROOT->cd(newdirname.c_str()))
1104     {
1105       std::cout << PHWHERE << "Unexpected TDirectory Problem cd'ing to "
1106                 << (*iter).second->getName()
1107                 << " - send e-mail to off-l with your macro" << std::endl;
1108       exit(1);
1109     }
1110     else
1111     {
1112       if (Verbosity() >= VERBOSITY_EVEN_MORE)
1113       {
1114         std::cout << "End: cded to " << newdirname << std::endl;
1115       }
1116     }
1117     try
1118     {
1119       i += (*iter).first->End((*iter).second);
1120     }
1121     catch (const std::exception &e)
1122     {
1123       std::cout << PHWHERE << " caught exception thrown during SusbsysReco::End() from "
1124                 << (*iter).first->Name() << std::endl;
1125       std::cout << "error: " << e.what() << std::endl;
1126       exit(1);
1127     }
1128     catch (...)
1129     {
1130       std::cout << PHWHERE << " caught unknown type exception thrown during SubsysReco::End() from "
1131                 << (*iter).first->Name() << std::endl;
1132       exit(1);
1133     }
1134   }
1135   gROOT->cd(currdir.c_str());
1136   PHNodeIterator nodeiter(TopNode);
1137   PHCompositeNode *runNode = dynamic_cast<PHCompositeNode *>(nodeiter.findFirst("PHCompositeNode", "RUN"));
1138   if (!runNode)
1139   {
1140     std::cout << "No Run Node, not writing Runwise info" << std::endl;
1141   }
1142   else
1143   {
1144     if (!OutputManager.empty())  // there are registered IO managers
1145     {
1146       MakeNodesTransient(runNode);  // make all nodes transient by default
1147       std::vector<Fun4AllOutputManager *>::iterator IOiter;
1148       for (IOiter = OutputManager.begin(); IOiter != OutputManager.end(); ++IOiter)
1149       {
1150         (*IOiter)->WriteNode(runNode);
1151       }
1152     }
1153   }
1154   // close output files (check for existing output managers is
1155   // done inside outfileclose())
1156   outfileclose();
1157 
1158   if (ScreamEveryEvent)
1159   {
1160     std::cout << "*******************************************************************************" << std::endl;
1161     std::cout << "*******************************************************************************" << std::endl;
1162     std::cout << "*******************************************************************************" << std::endl;
1163     std::cout << "Now that we are at the End(), please fix the following "
1164               << ScreamEveryEvent << " problem(s):" << std::endl;
1165     std::vector<std::string>::const_iterator viter;
1166     for (viter = ComplaintList.begin(); viter != ComplaintList.end(); ++viter)
1167     {
1168       std::cout << *viter << std::endl;
1169     }
1170     std::cout << " " << std::endl;
1171     std::cout << "*******************************************************************************" << std::endl;
1172     std::cout << "*******************************************************************************" << std::endl;
1173     std::cout << "*******************************************************************************" << std::endl;
1174   }
1175 
1176   return i;
1177 }
1178 
1179 void Fun4AllServer::Print(const std::string &what) const
1180 {
1181   if (what == "ALL" || what == "HISTOS")
1182   {
1183     // loop over the map and print out the content (name and location in memory)
1184     for (const auto &histoman : HistoManager)
1185     {
1186       histoman->Print(what);
1187     }
1188   }
1189   if (what == "ALL" || what == "SUBSYSTEMS")
1190   {
1191     // loop over the map and print out the content (name and location in memory)
1192     std::cout << "--------------------------------------" << std::endl
1193               << std::endl;
1194     std::cout << "List of Subsystems in Fun4AllServer:" << std::endl;
1195 
1196     std::vector<std::pair<SubsysReco *, PHCompositeNode *>>::const_iterator miter;
1197     for (miter = Subsystems.begin(); miter != Subsystems.end(); ++miter)
1198     {
1199       std::cout << (*miter).first->Name()
1200                 << " running under topNode " << (*miter).second->getName() << std::endl;
1201     }
1202     std::cout << std::endl;
1203   }
1204 
1205   if (what == "ALL" || what == "INPUTMANAGER")
1206   {
1207     // the input managers are managed by the input singleton
1208     for (const auto &syncman : SyncManagers)
1209     {
1210       std::cout << "SyncManager: " << syncman->Name() << std::endl;
1211       syncman->Print(what);
1212     }
1213   }
1214 
1215   if (what == "ALL" || what.find("OUTPUTMANAGER") != std::string::npos)
1216   {
1217     // loop over the map and print out the content (name and location in memory)
1218     std::string pass_on = what;
1219     if (pass_on == "ALL" || pass_on == "OUTPUTMANAGER")
1220     {
1221       std::cout << "--------------------------------------" << std::endl
1222                 << std::endl;
1223       std::cout << "List of OutputManagers in Fun4AllServer:" << std::endl;
1224       pass_on = "ALL";
1225     }
1226     else
1227     {
1228       std::string::size_type pos = pass_on.find('%');
1229       pass_on = pass_on.substr(pos + 1, pass_on.size());
1230     }
1231     for (const auto &outman : OutputManager)
1232     {
1233       outman->Print(pass_on);
1234     }
1235     std::cout << std::endl;
1236   }
1237   if (what == "ALL" || what == "TOPNODES")
1238   {
1239     // loop over the map and print out the content (name and location in memory)
1240     std::cout << "--------------------------------------" << std::endl
1241               << std::endl;
1242     std::cout << "List of TopNodes in Fun4AllServer:" << std::endl;
1243 
1244     std::map<std::string, PHCompositeNode *>::const_iterator iter;
1245     for (iter = topnodemap.begin(); iter != topnodemap.end(); ++iter)
1246     {
1247       std::cout << iter->first << " is at " << std::hex
1248                 << iter->second << std::dec << std::endl;
1249     }
1250     std::cout << std::endl;
1251   }
1252   if (what == "ALL" || what == "NODETREE")
1253   {
1254     // loop over the map and print out the content (name and location in memory)
1255     std::cout << "--------------------------------------" << std::endl
1256               << std::endl;
1257     std::cout << "List of Nodes in Fun4AllServer:" << std::endl;
1258 
1259     std::map<std::string, PHCompositeNode *>::const_iterator iter;
1260     for (iter = topnodemap.begin(); iter != topnodemap.end(); ++iter)
1261     {
1262       std::cout << "Node Tree under TopNode " << iter->first << std::endl;
1263       PHNodeIterator nodeiter(iter->second);
1264       nodeiter.print();
1265       std::cout << std::endl;
1266     }
1267     std::cout << std::endl;
1268   }
1269   return;
1270 }
1271 
1272 void Fun4AllServer::identify(std::ostream &out) const
1273 {
1274   out << "Fun4AllServer Name: " << Name() << std::endl;
1275   return;
1276 }
1277 
1278 int Fun4AllServer::outfileclose()
1279 {
1280   while (!OutputManager.empty())
1281   {
1282     if (Verbosity() >= VERBOSITY_MORE)
1283     {
1284       std::cout << "Erasing OutputManager "
1285                 << (*OutputManager.begin())->Name()
1286                 << " at memory location " << *(OutputManager.begin()) << std::endl;
1287     }
1288     delete *(OutputManager.begin());
1289     OutputManager.erase(OutputManager.begin());
1290   }
1291   return 0;
1292 }
1293 
1294 int Fun4AllServer::InitNodeTree(PHCompositeNode *topNode)
1295 {
1296   PHCompositeNode *dstNode;
1297   PHCompositeNode *runNode;
1298   PHCompositeNode *parNode;
1299   dstNode = new PHCompositeNode("DST");
1300   topNode->addNode(dstNode);
1301   runNode = new PHCompositeNode("RUN");
1302   topNode->addNode(runNode);
1303   parNode = new PHCompositeNode("PAR");
1304   topNode->addNode(parNode);
1305   return 0;
1306 }
1307 
1308 PHCompositeNode *
1309 Fun4AllServer::topNode(const std::string &name)
1310 {
1311   std::map<std::string, PHCompositeNode *>::const_iterator iter;
1312   iter = topnodemap.find(name);
1313   if (iter != topnodemap.end())
1314   {
1315     return iter->second;
1316   }
1317   AddTopNode(name);
1318   iter = topnodemap.find(name);
1319   if (iter != topnodemap.end())
1320   {
1321     InitNodeTree(iter->second);
1322     return iter->second;
1323   }
1324   std::cout << PHWHERE << " Could not create new topNode " << name
1325             << " send email to off-l with the following printout: " << std::endl;
1326   for (iter = topnodemap.begin(); iter != topnodemap.end(); ++iter)
1327   {
1328     std::cout << iter->first << " is at " << std::hex << iter->second << std::dec << std::endl;
1329   }
1330   exit(1);
1331 }
1332 
1333 int Fun4AllServer::AddTopNode(const std::string &name)
1334 {
1335   std::map<std::string, PHCompositeNode *>::const_iterator iter;
1336   iter = topnodemap.find(name);
1337   if (iter != topnodemap.end())
1338   {
1339     return -1;
1340   }
1341   PHCompositeNode *newNode = new PHCompositeNode(name);
1342   topnodemap[name] = newNode;
1343   return 0;
1344 }
1345 
1346 PHCompositeNode *Fun4AllServer::getNode(const std::string &name, const std::string &topnodename)
1347 {
1348   PHNodeIterator iter(topNode(topnodename));
1349   PHCompositeNode *thisNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", name));
1350   if (!thisNode)
1351   {
1352     thisNode = new PHCompositeNode(name);
1353     topNode(topnodename)->addNode(thisNode);
1354   }
1355   return thisNode;
1356 }
1357 
1358 int Fun4AllServer::registerInputManager(Fun4AllInputManager *InManager)
1359 {
1360   int iret = defaultSyncManager->registerInputManager(InManager);
1361   return iret;
1362 }
1363 
1364 Fun4AllInputManager *
1365 Fun4AllServer::getInputManager(const std::string &name)
1366 {
1367   std::vector<Fun4AllSyncManager *>::const_iterator iter;
1368   for (iter = SyncManagers.begin(); iter != SyncManagers.end(); ++iter)
1369   {
1370     if ((*iter)->getInputManager(name))
1371     {
1372       return (*iter)->getInputManager(name);
1373     }
1374   }
1375   std::cout << "Could not locate input manager " << name << std::endl;
1376   return nullptr;
1377 }
1378 
1379 int Fun4AllServer::PrdfEvents() const
1380 {
1381   return (defaultSyncManager->PrdfEvents());
1382 }
1383 
1384 int Fun4AllServer::DstEvents() const
1385 {
1386   return (defaultSyncManager->TotalEvents());
1387 }
1388 
1389 //_________________________________________________________________
1390 int Fun4AllServer::run(const int nevnts, const bool require_nevents)
1391 {
1392   recoConsts *rc = recoConsts::instance();
1393   static bool run_number_forced = rc->FlagExist("RUNNUMBER");
1394   static int ifirst = 1;
1395   if (ifirst && run_number_forced)
1396   {
1397     runnumber = rc->get_IntFlag("RUNNUMBER");
1398     std::cout << "Fun4AllServer: Runnumber forced to " << runnumber << " by RUNNUMBER IntFlag" << std::endl;
1399   }
1400   int iret = 0;
1401   int icnt = 0;
1402   int icnt_good = 0;
1403   std::vector<Fun4AllSyncManager *>::const_iterator iter;
1404   while (!iret)
1405   {
1406     int resetnodetree = 0;
1407     for (iter = SyncManagers.begin(); iter != SyncManagers.end(); ++iter)
1408     {
1409       if (Verbosity() >= VERBOSITY_MORE)
1410       {
1411         std::cout << "executing run for input master " << (*iter)->Name() << std::endl;
1412       }
1413       int retval = (*iter)->run(1);
1414       // if a new input file is opened during syncing and it contains
1415       // different nodes
1416       // as the previous one, the info in the nodes which are only in
1417       // the previous file will be carried to another event. We also
1418       // do not know under which topNode the input managers put
1419       // their data. This is why
1420       // the whole node tree is resetted whenever one of the Sync Managers
1421       // requires it.
1422       if (retval == Fun4AllReturnCodes::RESET_NODE_TREE)
1423       {
1424         resetnodetree = 1;
1425       }
1426       else
1427       {
1428         iret += retval;
1429       }
1430     }
1431     if (resetnodetree)
1432     {
1433       // if the node tree needs resetting, we just push the current
1434       // event(s) (which are all properly synced at this point)
1435       // back into the input managers and just read again.
1436       for (iter = SyncManagers.begin(); iter != SyncManagers.end(); ++iter)
1437       {
1438         (*iter)->PushBackInputMgrsEvents(1);
1439       }
1440       ResetNodeTree();
1441       continue;  // go back to run loop
1442     }
1443     if (iret)
1444     {
1445       break;
1446     }
1447     int currentrun = 0;
1448     for (iter = SyncManagers.begin(); iter != SyncManagers.end(); ++iter)
1449     {
1450       int runno = (*iter)->CurrentRun();
1451       //      std::cout << (*iter)->Name() << " run no: " << runno << std::endl;
1452       if (runno != 0)
1453       {
1454         if (currentrun == 0)
1455         {
1456           currentrun = runno;
1457         }
1458         else
1459         {
1460           if (currentrun != runno)
1461           {
1462             if (!(*iter)->MixRunsOk())
1463             {
1464               std::cout << "Mixing of Runs within same event is not supported" << std::endl;
1465               std::cout << "Here is the list of Sync Managers and their runnumbers:" << std::endl;
1466               std::vector<Fun4AllSyncManager *>::const_iterator syiter;
1467               for (syiter = SyncManagers.begin(); syiter != SyncManagers.end(); ++syiter)
1468               {
1469                 std::cout << (*syiter)->Name() << " run number: " << (*syiter)->CurrentRun() << std::endl;
1470               }
1471               std::cout << "Exiting now" << std::endl;
1472               exit(1);
1473             }
1474           }
1475         }
1476       }
1477     }
1478     if (ifirst)
1479     {
1480       if (currentrun != runnumber && !run_number_forced)  // use real run if not forced
1481       {
1482         runnumber = currentrun;
1483       }
1484       setRun(runnumber);
1485       BeginRun(runnumber);
1486       ifirst = 0;
1487     }
1488     else if (!run_number_forced)
1489     {
1490       if (currentrun != runnumber)
1491       {
1492         EndRun(runnumber);
1493         runnumber = currentrun;
1494         setRun(runnumber);
1495         BeginRun(runnumber);
1496       }
1497     }
1498     if (Verbosity() >= 1 && ((icnt + 1) % VerbosityDownscale() == 0))
1499     {
1500       std::cout << "Fun4AllServer::run - processing event "
1501                 << (icnt + 1) << " from run " << runnumber << std::endl;
1502     }
1503 
1504     if (icnt == 0 && Verbosity() > VERBOSITY_QUIET)
1505     {
1506       // increase verbosity for the first event in verbose modes
1507       int iverb = Verbosity();
1508       Verbosity(++iverb);
1509     }
1510 
1511     iret = process_event();
1512 
1513     if (icnt == 0 && Verbosity() > VERBOSITY_QUIET)
1514     {
1515       // increase verbosity for the first event in verbose modes
1516       int iverb = Verbosity();
1517       Verbosity(--iverb);
1518     }
1519 
1520     ++icnt;  // completed one event processing
1521 
1522     if (require_nevents)
1523     {
1524       if (std::find(RetCodes.begin(),
1525                     RetCodes.end(),
1526                     static_cast<int>(Fun4AllReturnCodes::ABORTEVENT)) == RetCodes.end())
1527       {
1528         icnt_good++;
1529       }
1530       if (iret || (nevnts > 0 && icnt_good >= nevnts))
1531       {
1532         break;
1533       }
1534     }
1535     else if (iret || (nevnts > 0 && icnt >= nevnts))
1536     {
1537       break;
1538     }
1539   }
1540   return iret;
1541 }
1542 
1543 //_________________________________________________________________
1544 int Fun4AllServer::skip(const int nevnts)
1545 {
1546   int iret = 0;
1547   if (nevnts > 0)  // do not execute for nevnts <= 0
1548   {
1549     std::vector<Fun4AllSyncManager *>::const_iterator iter;
1550     for (iter = SyncManagers.begin(); iter != SyncManagers.end(); ++iter)
1551     {
1552       iret += (*iter)->skip(nevnts);
1553     }
1554     eventcounter += nevnts;  // update event counter so it reflects the number of events in the input
1555   }
1556   return iret;
1557 }
1558 
1559 //_________________________________________________________________
1560 int Fun4AllServer::fileopen(const std::string &managername, const std::string &filename)
1561 {
1562   int iret = 0;
1563   std::vector<Fun4AllSyncManager *>::const_iterator iter;
1564   for (iter = SyncManagers.begin(); iter != SyncManagers.end(); ++iter)
1565   {
1566     iret += (*iter)->fileopen(managername, filename);
1567   }
1568   return iret;
1569 }
1570 
1571 int Fun4AllServer::BranchSelect(const std::string &managername, const std::string &branch, int iflag)
1572 {
1573   int iret = 0;
1574   std::vector<Fun4AllSyncManager *>::const_iterator iter;
1575   for (iter = SyncManagers.begin(); iter != SyncManagers.end(); ++iter)
1576   {
1577     iret += (*iter)->BranchSelect(managername, branch, iflag);
1578   }
1579   return iret;
1580 }
1581 
1582 int Fun4AllServer::BranchSelect(const std::string &branch, int iflag)
1583 {
1584   int iret = 0;
1585   std::vector<Fun4AllSyncManager *>::const_iterator iter;
1586   for (iter = SyncManagers.begin(); iter != SyncManagers.end(); ++iter)
1587   {
1588     iret += (*iter)->BranchSelect(branch, iflag);
1589   }
1590   return iret;
1591 }
1592 
1593 int Fun4AllServer::setBranches(const std::string &managername)
1594 {
1595   int iret = 0;
1596   std::vector<Fun4AllSyncManager *>::const_iterator iter;
1597   for (iter = SyncManagers.begin(); iter != SyncManagers.end(); ++iter)
1598   {
1599     iret += (*iter)->setBranches(managername);
1600   }
1601   return iret;
1602 }
1603 
1604 int Fun4AllServer::setBranches()
1605 {
1606   int iret = 0;
1607   std::vector<Fun4AllSyncManager *>::const_iterator iter;
1608   for (iter = SyncManagers.begin(); iter != SyncManagers.end(); ++iter)
1609   {
1610     iret += (*iter)->setBranches();
1611   }
1612   return iret;
1613 }
1614 
1615 int Fun4AllServer::fileclose(const std::string &managername)
1616 {
1617   int iret = 0;
1618   std::vector<Fun4AllSyncManager *>::const_iterator iter;
1619   for (iter = SyncManagers.begin(); iter != SyncManagers.end(); ++iter)
1620   {
1621     iret += (*iter)->fileclose(managername);
1622   }
1623   return iret;
1624 }
1625 
1626 int Fun4AllServer::SegmentNumber()
1627 {
1628   int iret = defaultSyncManager->SegmentNumber();
1629   return iret;
1630 }
1631 
1632 void Fun4AllServer::GetInputFullFileList(std::vector<std::string> &fnames) const
1633 {
1634   defaultSyncManager->GetInputFullFileList(fnames);
1635   return;
1636 }
1637 
1638 unsigned
1639 Fun4AllServer::GetTopNodes(std::vector<std::string> &names) const
1640 {
1641   std::map<std::string, PHCompositeNode *>::const_iterator iter;
1642   for (iter = topnodemap.begin(); iter != topnodemap.end(); ++iter)
1643   {
1644     names.push_back(iter->first);
1645   }
1646   return names.size();
1647 }
1648 
1649 void Fun4AllServer::GetOutputManagerList(std::vector<std::string> &names) const
1650 {
1651   names.clear();
1652   std::vector<Fun4AllOutputManager *>::const_iterator iter;
1653   for (iter = OutputManager.begin(); iter != OutputManager.end(); ++iter)
1654   {
1655     names.push_back((*iter)->Name());
1656   }
1657   return;
1658 }
1659 
1660 void Fun4AllServer::GetModuleList(std::vector<std::string> &names) const
1661 {
1662   names.clear();
1663   std::vector<std::pair<SubsysReco *, PHCompositeNode *>>::const_iterator iter;
1664   for (iter = Subsystems.begin(); iter != Subsystems.end(); ++iter)
1665   {
1666     names.push_back((*iter).first->Name());
1667   }
1668   return;
1669 }
1670 
1671 int Fun4AllServer::registerSyncManager(Fun4AllSyncManager *newmaster)
1672 {
1673   for (auto &syncman : SyncManagers)
1674   {
1675     if (syncman->Name() == newmaster->Name())
1676     {
1677       std::cout << "Input Master " << newmaster->Name()
1678                 << " already registered" << std::endl;
1679       return -1;
1680     }
1681   }
1682   if (Verbosity() >= VERBOSITY_SOME)
1683   {
1684     std::cout << "Registering Input Master " << newmaster->Name() << std::endl;
1685   }
1686   SyncManagers.push_back(newmaster);
1687   return 0;
1688 }
1689 
1690 Fun4AllSyncManager *
1691 Fun4AllServer::getSyncManager(const std::string &name)
1692 {
1693   if (name == "DefaultSyncManager")
1694   {
1695     return defaultSyncManager;
1696   }
1697   std::vector<Fun4AllSyncManager *>::iterator iter;
1698 
1699   for (iter = SyncManagers.begin(); iter != SyncManagers.end(); ++iter)
1700   {
1701     if ((*iter)->Name() == name)
1702     {
1703       return *iter;
1704     }
1705   }
1706   std::cout << "Could not find Input Master " << name << std::endl;
1707   return nullptr;
1708 }
1709 
1710 int Fun4AllServer::setRun(const int runno)
1711 {
1712   recoConsts *rc = recoConsts::instance();
1713   rc->set_IntFlag("RUNNUMBER", runno);
1714   if (!rc->FlagExist("TIMESTAMP"))
1715   {
1716     rc->set_uint64Flag("TIMESTAMP", runno);
1717   }
1718   std::cout << "Fun4AllServer::setRun(): run " << runno
1719             << " uses CDB TIMESTAMP " << rc->get_uint64Flag("TIMESTAMP")
1720             << std::endl;
1721   FrameWorkVars->SetBinContent(RUNNUMBERBIN, (Stat_t) runno);
1722   return 0;
1723 }
1724 
1725 void Fun4AllServer::NodeIdentify(const std::string &name)
1726 {
1727   PHObject *obj = findNode::getClass<PHObject>(TopNode, name);
1728   if (obj)
1729   {
1730     obj->identify();
1731   }
1732   else
1733   {
1734     std::cout << "Could not locate node " << name
1735               << " or no PHObject Node" << std::endl;
1736   }
1737   return;
1738 }
1739 
1740 void Fun4AllServer::PrintTimer(const std::string &name)
1741 {
1742   std::map<const std::string, PHTimer>::const_iterator iter;
1743   PHTimer::PRINT(std::cout, "**");
1744   if (name.empty())
1745   {
1746     for (iter = timer_map.begin(); iter != timer_map.end(); ++iter)
1747     {
1748       iter->second.print_stat();
1749     }
1750   }
1751   else
1752   {
1753     iter = timer_map.find(name);
1754     if (iter != timer_map.end())
1755     {
1756       iter->second.print_stat();
1757     }
1758     else
1759     {
1760       std::cout << "No timer with name " << name << " found" << std::endl;
1761       std::cout << "Existing timers:" << std::endl;
1762       for (iter = timer_map.begin(); iter != timer_map.end(); ++iter)
1763       {
1764         std::cout << iter->first << std::endl;
1765       }
1766     }
1767   }
1768   return;
1769 }
1770 
1771 void Fun4AllServer::PrintMemoryTracker(const std::string &name)
1772 {
1773 #ifdef FFAMEMTRACKER
1774   ffamemtracker->PrintMemoryTracker(name);
1775 #else
1776   std::cout << "PrintMemoryTracker called with " << name << " is disabled" << std::endl;
1777 #endif
1778   return;
1779 }