Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:19:35

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.contains(timer_name))
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       goto tryagain;  // NOLINT(hicpp-avoid-goto)
0424     }
0425   }
0426   return 0;
0427 }
0428 
0429 Fun4AllOutputManager *
0430 Fun4AllServer::getOutputManager(const std::string &name)
0431 {
0432   std::vector<Fun4AllOutputManager *>::iterator iter;
0433   for (iter = OutputManager.begin(); iter != OutputManager.end(); ++iter)
0434   {
0435     if (name == (*iter)->Name())
0436     {
0437       if (Verbosity() >= VERBOSITY_EVEN_MORE)
0438       {
0439         std::cout << "Found OutputManager " << name << std::endl;
0440       }
0441       return *iter;
0442     }
0443   }
0444   std::cout << "Could not find OutputManager" << name << std::endl;
0445   return nullptr;
0446 }
0447 
0448 Fun4AllHistoManager *Fun4AllServer::getHistoManager(const std::string &name)
0449 {
0450   std::vector<Fun4AllHistoManager *>::iterator iter;
0451   for (iter = HistoManager.begin(); iter != HistoManager.end(); ++iter)
0452   {
0453     if ((*iter)->Name() == name)
0454     {
0455       if (Verbosity() >= VERBOSITY_EVEN_MORE)
0456       {
0457         std::cout << "Found HistoManager " << name << std::endl;
0458       }
0459       return *iter;
0460     }
0461   }
0462   if (Verbosity() >= VERBOSITY_MORE)
0463   {
0464     std::cout << "Could not find HistoManager " << name << std::endl;
0465   }
0466   return nullptr;
0467 }
0468 
0469 int Fun4AllServer::registerHistoManager(Fun4AllHistoManager *manager)
0470 {
0471   std::vector<Fun4AllHistoManager *>::iterator iter;
0472   for (iter = HistoManager.begin(); iter != HistoManager.end(); ++iter)
0473   {
0474     if ((*iter)->Name() == manager->Name())
0475     {
0476       std::cout << "HistoManager " << manager->Name() << " allready in list" << std::endl;
0477       return -1;
0478     }
0479   }
0480   if (Verbosity() >= VERBOSITY_SOME)
0481   {
0482     std::cout << "Registering HistoManager " << manager->Name() << std::endl;
0483   }
0484   HistoManager.push_back(manager);
0485   return 0;
0486 }
0487 
0488 TNamed *
0489 Fun4AllServer::getHisto(const unsigned int ihisto) const
0490 {
0491   return ServerHistoManager->getHisto(ihisto);
0492 }
0493 
0494 std::string
0495 Fun4AllServer::getHistoName(const unsigned int ihisto) const
0496 {
0497   return (ServerHistoManager->getHistoName(ihisto));
0498 }
0499 
0500 TNamed *Fun4AllServer::getHisto(const std::string &hname) const
0501 {
0502   return (ServerHistoManager->getHisto(hname));
0503 }
0504 
0505 int Fun4AllServer::process_event()
0506 {
0507   eventcounter++;
0508   unsigned icnt = 0;
0509   int eventbad = 0;
0510   if (ScreamEveryEvent)
0511   {
0512     std::cout << "*******************************************************************************" << std::endl;
0513     std::cout << "*******************************************************************************" << std::endl;
0514     std::cout << "*******************************************************************************" << std::endl;
0515     std::cout << "Now that I have your attention, please fix the following "
0516               << ScreamEveryEvent << " problem(s):" << std::endl;
0517     std::vector<std::string>::const_iterator viter;
0518     for (viter = ComplaintList.begin(); viter != ComplaintList.end(); ++viter)
0519     {
0520       std::cout << *viter << std::endl;
0521     }
0522     std::cout << " " << std::endl;
0523     std::cout << "*******************************************************************************" << std::endl;
0524     std::cout << "*******************************************************************************" << std::endl;
0525     std::cout << "*******************************************************************************" << std::endl;
0526   }
0527   if (unregistersubsystem)
0528   {
0529     unregisterSubsystemsNow();
0530   }
0531   gROOT->cd(default_Tdirectory.c_str());
0532   std::string currdir = gDirectory->GetPath();
0533   for (auto &Subsystem : Subsystems)
0534   {
0535     if (Verbosity() >= VERBOSITY_MORE)
0536     {
0537       std::cout << "Fun4AllServer::process_event processing " << Subsystem.first->Name() << std::endl;
0538     }
0539     std::string newdirname = Subsystem.second->getName() + "/" + Subsystem.first->Name();
0540     if (!gROOT->cd(newdirname.c_str()))
0541     {
0542       std::cout << PHWHERE << "Unexpected TDirectory Problem cd'ing to "
0543                 << Subsystem.second->getName()
0544                 << " - send e-mail to off-l with your macro" << std::endl;
0545       exit(1);
0546     }
0547     else
0548     {
0549       if (Verbosity() >= VERBOSITY_EVEN_MORE)
0550       {
0551         std::cout << "process_event: cded to " << newdirname << std::endl;
0552       }
0553     }
0554 
0555     PHTimer subsystem_timer("SubsystemTimer");
0556     subsystem_timer.restart();
0557 
0558     try
0559     {
0560       std::string timer_name;
0561       timer_name = Subsystem.first->Name() + "_" + Subsystem.second->getName();
0562       std::map<const std::string, PHTimer>::iterator titer = timer_map.find(timer_name);
0563       bool timer_found = false;
0564       if (titer != timer_map.end())
0565       {
0566         timer_found = true;
0567         titer->second.restart();
0568       }
0569       else
0570       {
0571         std::cout << "could not find timer for " << timer_name << std::endl;
0572       }
0573 #ifdef FFAMEMTRACKER
0574       ffamemtracker->Start(timer_name, "SubsysReco");
0575       ffamemtracker->Snapshot("Fun4AllServerProcessEvent");
0576 #endif
0577       int retcode = Subsystem.first->process_event(Subsystem.second);
0578 #ifdef FFAMEMTRACKER
0579       ffamemtracker->Snapshot("Fun4AllServerProcessEvent");
0580 #endif
0581       // we have observed an index overflow in RetCodes. I assume it is some
0582       // memory corruption elsewhere which hits the icnt variable. Rather than
0583       // the previous [], use at() which does bounds checking and throws an
0584       // exception which will allow us to catch this and print out icnt and the size
0585       try
0586       {
0587         RetCodes.at(icnt) = retcode;
0588       }
0589       catch (const std::exception &e)
0590       {
0591         std::cout << PHWHERE << " caught exception thrown during RetCodes.at(icnt)" << std::endl;
0592         std::cout << "RetCodes.size(): " << RetCodes.size() << ", icnt: " << icnt << std::endl;
0593         std::cout << "error: " << e.what() << std::endl;
0594         gSystem->Exit(1);
0595       }
0596       if (timer_found)
0597       {
0598         titer->second.stop();
0599       }
0600 #ifdef FFAMEMTRACKER
0601       ffamemtracker->Stop(timer_name, "SubsysReco");
0602 #endif
0603     }
0604     catch (const std::exception &e)
0605     {
0606       std::cout << PHWHERE << " caught exception thrown during process_event from "
0607                 << Subsystem.first->Name() << std::endl;
0608       std::cout << "error: " << e.what() << std::endl;
0609       gSystem->Exit(1);
0610     }
0611     catch (...)
0612     {
0613       std::cout << PHWHERE << " caught unknown type exception thrown during process_event from "
0614                 << Subsystem.first->Name() << std::endl;
0615       exit(1);
0616     }
0617     if (RetCodes[icnt])
0618     {
0619       if (RetCodes[icnt] == Fun4AllReturnCodes::DISCARDEVENT)
0620       {
0621         if (Verbosity() >= VERBOSITY_EVEN_MORE)
0622         {
0623           std::cout << "Fun4AllServer::Discard Event by " << Subsystem.first->Name() << std::endl;
0624         }
0625       }
0626       else if (RetCodes[icnt] == Fun4AllReturnCodes::ABORTEVENT)
0627       {
0628         retcodesmap[Fun4AllReturnCodes::ABORTEVENT]++;
0629         eventbad = 1;
0630         if (Verbosity() >= VERBOSITY_MORE)
0631         {
0632           std::cout << "Fun4AllServer::Abort Event by " << Subsystem.first->Name() << std::endl;
0633         }
0634         break;
0635       }
0636       else if (RetCodes[icnt] == Fun4AllReturnCodes::ABORTRUN)
0637       {
0638         retcodesmap[Fun4AllReturnCodes::ABORTRUN]++;
0639         std::cout << "Fun4AllServer::Abort Run by " << Subsystem.first->Name() << std::endl;
0640         return Fun4AllReturnCodes::ABORTRUN;
0641       }
0642       else if (RetCodes[icnt] == Fun4AllReturnCodes::ABORTPROCESSING)
0643       {
0644         eventbad = 1;
0645         retcodesmap[Fun4AllReturnCodes::ABORTPROCESSING]++;
0646         std::cout << "Fun4AllServer::Abort Processing by " << Subsystem.first->Name() << std::endl;
0647         return Fun4AllReturnCodes::ABORTPROCESSING;
0648       }
0649       else
0650       {
0651         std::cout << "Fun4AllServer::Unknown return code: "
0652                   << RetCodes[icnt] << " from process_event method of "
0653                   << Subsystem.first->Name() << std::endl;
0654         std::cout << "This smells like an uninitialized return code and" << std::endl;
0655         std::cout << "it is too dangerous to continue, this Run will be aborted" << std::endl;
0656         std::cout << "If you do not know how to fix this please send mail to" << std::endl;
0657         std::cout << "phenix-off-l with this message" << std::endl;
0658         return Fun4AllReturnCodes::ABORTRUN;
0659       }
0660     }
0661     subsystem_timer.stop();
0662     double TimeSubsystem = subsystem_timer.elapsed();
0663     if (Verbosity() >= VERBOSITY_MORE)
0664     {
0665       std::cout << "Fun4AllServer::process_event processing " << Subsystem.first->Name()
0666                 << " processing total time: " << TimeSubsystem << " ms" << std::endl;
0667     }
0668     icnt++;
0669   }
0670   if (!eventbad)
0671   {
0672     retcodesmap[Fun4AllReturnCodes::EVENT_OK]++;
0673   }
0674 
0675   gROOT->cd(currdir.c_str());
0676   //  mainIter.print();
0677   if (!OutputManager.empty() && !eventbad)  // there are registered IO managers and
0678   // the event is not flagged bad
0679   {
0680     PHNodeIterator iter(TopNode);
0681     PHCompositeNode *dstNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "DST"));
0682 
0683     if (dstNode)
0684     {
0685       // check if we have same number of nodes. After first event is
0686       // written out root I/O doesn't permit adding nodes, otherwise
0687       // events get out of sync
0688       static int first = 1;
0689       int newcount = CountOutNodes(dstNode);
0690       if (first)
0691       {
0692         first = 0;
0693         OutNodeCount = newcount;      // save number of nodes before first write
0694         MakeNodesTransient(dstNode);  // make all nodes transient before 1st write in case someone sneaked a node in at the first event
0695       }
0696 
0697       if (OutNodeCount != newcount)
0698       {
0699         iter.print();
0700         std::cout << PHWHERE << " FATAL: Someone changed the number of Output Nodes on the fly, from " << OutNodeCount << " to " << newcount << std::endl;
0701         exit(1);
0702       }
0703       for (auto *iterOutMan : OutputManager)
0704       {
0705         if (!iterOutMan->DoNotWriteEvent(&RetCodes))
0706         {
0707           if (Verbosity() >= VERBOSITY_MORE)
0708           {
0709             std::cout << "Writing Event for " << iterOutMan->Name() << std::endl;
0710           }
0711 #ifdef FFAMEMTRACKER
0712           ffamemtracker->Snapshot("Fun4AllServerOutputManager");
0713           ffamemtracker->Start(iterOutMan->Name(), "OutputManager");
0714 #endif
0715       iterOutMan->InitializeLastEvent(eventnumber); // only executed once, returns immediately for all subsequent calls
0716           if (eventnumber > iterOutMan->LastEventNumber())
0717           {
0718             if (Verbosity() > 0)
0719             {
0720               std::cout << PHWHERE << iterOutMan->Name() << " wrote " << iterOutMan->EventsWritten()
0721                         << " events, closing " << iterOutMan->OutFileName() << std::endl;
0722             }
0723             UpdateRunNode();
0724             PHNodeIterator nodeiter(TopNode);
0725             PHCompositeNode *runNode = dynamic_cast<PHCompositeNode *>(nodeiter.findFirst("PHCompositeNode", "RUN"));
0726             MakeNodesTransient(runNode);  // make all nodes transient by default
0727             iterOutMan->WriteNode(runNode);
0728             iterOutMan->RunAfterClosing();
0729             iterOutMan->UpdateLastEvent();
0730           }
0731           // save runnode, open new file, write
0732           iterOutMan->WriteGeneric(dstNode);
0733 #ifdef FFAMEMTRACKER
0734           ffamemtracker->Stop(iterOutMan->Name(), "OutputManager");
0735           ffamemtracker->Snapshot("Fun4AllServerOutputManager");
0736 #endif
0737           if (iterOutMan->EventsWritten() >= iterOutMan->GetNEvents())
0738           {
0739             if (Verbosity() > 0)
0740             {
0741               std::cout << PHWHERE << iterOutMan->Name() << " wrote " << iterOutMan->EventsWritten()
0742                         << " events, closing " << iterOutMan->OutFileName() << std::endl;
0743             }
0744             UpdateRunNode();
0745             PHNodeIterator nodeiter(TopNode);
0746             PHCompositeNode *runNode = dynamic_cast<PHCompositeNode *>(nodeiter.findFirst("PHCompositeNode", "RUN"));
0747             MakeNodesTransient(runNode);  // make all nodes transient by default
0748             iterOutMan->WriteNode(runNode);
0749             iterOutMan->RunAfterClosing();
0750           }
0751         }
0752         else
0753         {
0754           if (Verbosity() >= VERBOSITY_MORE)
0755           {
0756             std::cout << "Not Writing Event for " << iterOutMan->Name() << std::endl;
0757           }
0758         }
0759       }
0760     }
0761   }
0762   // saving the histograms using the same scheme as the DSTs
0763   if (!HistoManager.empty() && !eventbad)
0764   {
0765     // kludge to save at the correct event. This is called after the event processing. Normally it would be fine to check for == eventnumber
0766     // but if that event is missing we would overshoot. If there is more than one event missing this will overshoot, but there is only so much
0767     // one can do
0768     int eventnumber_plus1 = eventnumber+1;
0769     
0770     for (auto &histit : HistoManager)
0771     {
0772       histit->InitializeLastEvent(eventnumber_plus1);
0773       if (eventnumber_plus1 > histit->LastEventNumber())
0774       {
0775     histit->dumpHistos();
0776 //  histit->RunAfterClosing();
0777         histit->UpdateLastEvent();
0778     histit->Reset();
0779     if (Verbosity() > 0)
0780     {
0781       std::cout << PHWHERE << "saving " << histit->Name() << " wrote events, closing " << histit->LastClosedFileName() << std::endl;
0782     }
0783       }
0784     }
0785   }
0786   for (auto &Subsystem : Subsystems)
0787   {
0788     if (Verbosity() >= VERBOSITY_EVEN_MORE)
0789     {
0790       std::cout << "Fun4AllServer::process_event Resetting Event " << Subsystem.first->Name() << std::endl;
0791     }
0792     Subsystem.first->ResetEvent(Subsystem.second);
0793   }
0794   for (auto &syncman : SyncManagers)
0795   {
0796     if (Verbosity() >= VERBOSITY_EVEN_MORE)
0797     {
0798       std::cout << "Fun4AllServer::process_event Resetting Event for Sync Manager " << syncman->Name() << std::endl;
0799     }
0800     syncman->ResetEvent();
0801   }
0802   Fun4AllMonitoring::instance()->Snapshot("Event");
0803   ResetNodeTree();
0804   return 0;
0805 }
0806 
0807 int Fun4AllServer::ResetNodeTree()
0808 {
0809   PHNodeReset reset;
0810   reset.Verbosity(Verbosity() > 2 ? Verbosity() - 2 : 0);  // one lower verbosity level than Fun4AllServer
0811   std::map<std::string, PHCompositeNode *>::const_iterator iter;
0812   for (iter = topnodemap.begin(); iter != topnodemap.end(); ++iter)
0813   {
0814     PHNodeIterator mainIter((*iter).second);
0815     for (const auto &nodename : ResetNodeList)
0816     {
0817       if (mainIter.cd(nodename))
0818       {
0819         mainIter.forEach(reset);
0820         mainIter.cd();
0821       }
0822     }
0823   }
0824   return 0;  // anything except 0 would abort the event loop in pmonitor
0825 }
0826 
0827 int Fun4AllServer::Reset()
0828 {
0829   int i = 0;
0830   std::vector<std::pair<SubsysReco *, PHCompositeNode *>>::iterator iter;
0831   for (iter = Subsystems.begin(); iter != Subsystems.end(); ++iter)
0832   {
0833     if (Verbosity() >= VERBOSITY_EVEN_MORE)
0834     {
0835       std::cout << "Fun4AllServer::Reset Resetting " << (*iter).first->Name() << std::endl;
0836     }
0837     i += (*iter).first->Reset((*iter).second);
0838   }
0839   for (auto *hiter : HistoManager)
0840   {
0841     hiter->Reset();
0842   }
0843   return i;
0844 }
0845 
0846 int Fun4AllServer::BeginRunTimeStamp(PHTimeStamp &TimeStp)
0847 {
0848   beginruntimestamp = new PHTimeStamp(TimeStp);
0849   std::cout << "Setting BOR timestamp to ";
0850   beginruntimestamp->print();
0851   std::cout << std::endl;
0852   bortime_override = 1;
0853   return 0;
0854 }
0855 
0856 int Fun4AllServer::BeginRun(const int runno)
0857 {
0858   eventcounter = 0;  // reset event counter for every new run
0859 #ifdef FFAMEMTRACKER
0860   ffamemtracker->Snapshot("Fun4AllServerBeginRun");
0861 #endif
0862   if (!bortime_override)
0863   {
0864     delete beginruntimestamp;
0865 
0866     beginruntimestamp = new PHTimeStamp();
0867   }
0868   else
0869   {
0870     std::cout << "overriding BOR timestamp by ";
0871     beginruntimestamp->print();
0872     std::cout << std::endl;
0873     // rc->set_TimeStamp(*beginruntimestamp);
0874   }
0875   if (Verbosity() >= VERBOSITY_SOME)
0876   {
0877     std::cout << "Fun4AllServer::BeginRun: Run number " << runno << " uses RECO TIMESTAMP: ";
0878     beginruntimestamp->print();
0879     std::cout << std::endl;
0880   }
0881   std::vector<std::pair<SubsysReco *, PHCompositeNode *>>::iterator iter;
0882   int iret = 0;
0883 
0884   // check if any registered SubsysReco wants to be dropped and
0885   // remove it from the list before its BeginRun is executed
0886   if (unregistersubsystem)
0887   {
0888     unregisterSubsystemsNow();
0889   }
0890 
0891   // we have to do the same TDirectory games as in the Init methods
0892   // save the current dir, cd to the subsystem name dir (which was
0893   // created in init) call the InitRun of the module and cd back
0894 
0895   gROOT->cd(default_Tdirectory.c_str());
0896   std::string currdir = gDirectory->GetPath();
0897 
0898   for (iter = Subsystems.begin(); iter != Subsystems.end(); ++iter)
0899   {
0900     iret = BeginRunSubsystem(*iter);
0901   }
0902   for (; !NewSubsystems.empty(); NewSubsystems.pop_front())
0903   {
0904     registerSubsystem((NewSubsystems.front()).first, (NewSubsystems.front()).second);
0905     BeginRunSubsystem(std::make_pair(NewSubsystems.front().first, topNode(NewSubsystems.front().second)));
0906   }
0907   gROOT->cd(currdir.c_str());
0908   // print out all node trees
0909   Print("NODETREE");
0910 #ifdef FFAMEMTRACKER
0911   ffamemtracker->Snapshot("Fun4AllServerBeginRun");
0912 #endif
0913   return iret;
0914 }
0915 
0916 int Fun4AllServer::BeginRunSubsystem(const std::pair<SubsysReco *, PHCompositeNode *> &subsys)
0917 {
0918   int iret = 0;
0919   std::string newdirname = subsys.second->getName() + "/" + subsys.first->Name();
0920   if (!gROOT->cd(newdirname.c_str()))
0921   {
0922     std::cout << PHWHERE << "Unexpected TDirectory Problem cd'ing to "
0923               << subsys.second->getName()
0924               << " - send e-mail to off-l with your macro" << std::endl;
0925     exit(1);
0926   }
0927   else
0928   {
0929     if (Verbosity() >= VERBOSITY_EVEN_MORE)
0930     {
0931       std::cout << "BeginRun: cded to " << newdirname << std::endl;
0932     }
0933   }
0934 
0935   if (Verbosity() >= VERBOSITY_SOME)
0936   {
0937     std::cout << "Fun4AllServer::BeginRun: InitRun for " << subsys.first->Name() << std::endl;
0938   }
0939   try
0940   {
0941 #ifdef FFAMEMTRACKER
0942     ffamemtracker->Start(subsys.first->Name(), "SubsysReco");
0943 #endif
0944     iret = subsys.first->InitRun(subsys.second);
0945 #ifdef FFAMEMTRACKER
0946     ffamemtracker->Stop(subsys.first->Name(), "SubsysReco");
0947 #endif
0948   }
0949   catch (const std::exception &e)
0950   {
0951     std::cout << PHWHERE << " caught exception thrown during SubsysReco::InitRun() from "
0952               << subsys.first->Name() << std::endl;
0953     std::cout << "error: " << e.what() << std::endl;
0954     exit(1);
0955   }
0956   catch (...)
0957   {
0958     std::cout << PHWHERE << " caught unknown type exception thrown during SubsysReco::InitRun() from "
0959               << subsys.first->Name() << std::endl;
0960     exit(1);
0961   }
0962 
0963   if (iret == Fun4AllReturnCodes::ABORTRUN)
0964   {
0965     std::cout << PHWHERE << "Module " << subsys.first->Name() << " issued Abort Run, exiting" << std::endl;
0966     exit(-1);
0967   }
0968   else if (iret != Fun4AllReturnCodes::EVENT_OK)
0969   {
0970     std::cout << PHWHERE << "Module " << subsys.first->Name() << " issued non Fun4AllReturnCodes::EVENT_OK return code " << iret << " in InitRun()" << std::endl;
0971     exit(-2);
0972   }
0973   return iret;
0974 }
0975 
0976 int Fun4AllServer::CountOutNodes(PHCompositeNode *startNode)
0977 {
0978   int icount = 0;
0979   icount = CountOutNodesRecursive(startNode, icount);
0980   return icount;
0981 }
0982 
0983 // NOLINTNEXTLINE(misc-no-recursion)
0984 int Fun4AllServer::CountOutNodesRecursive(PHCompositeNode *startNode, const int icount)
0985 {
0986   PHNodeIterator nodeiter(startNode);
0987   PHPointerListIterator<PHNode> iterat(nodeiter.ls());
0988   PHNode *thisNode;
0989   int icnt = icount;
0990   while ((thisNode = iterat()))
0991   {
0992     if ((thisNode->getType() == "PHCompositeNode"))
0993     {
0994       // NOLINTNEXTLINE(cppcoreguidelines-pro-type-static-cast-downcast)
0995       icnt = CountOutNodesRecursive(static_cast<PHCompositeNode *>(thisNode), icnt);  // if this is a CompositeNode do this trick again
0996     }
0997     else
0998     {
0999       icnt++;
1000       if (Verbosity() >= VERBOSITY_EVEN_MORE)
1001       {
1002         std::cout << thisNode->getName() << ", Node Count: " << icnt << std::endl;
1003       }
1004     }
1005   }
1006   return icnt;
1007 }
1008 
1009 // NOLINTNEXTLINE(misc-no-recursion)
1010 int Fun4AllServer::MakeNodesTransient(PHCompositeNode *startNode)
1011 {
1012   PHNodeIterator nodeiter(startNode);
1013   PHPointerListIterator<PHNode> iterat(nodeiter.ls());
1014   PHNode *thisNode;
1015   while ((thisNode = iterat()))
1016   {
1017     if ((thisNode->getType() == "PHCompositeNode"))
1018     {
1019       // NOLINTNEXTLINE(cppcoreguidelines-pro-type-static-cast-downcast)
1020       MakeNodesTransient(static_cast<PHCompositeNode *>(thisNode));  // if this is a CompositeNode do this trick again
1021     }
1022     else
1023     {
1024       thisNode->makeTransient();
1025     }
1026   }
1027   return 0;
1028 }
1029 
1030 int Fun4AllServer::MakeNodesPersistent(PHCompositeNode *startNode)  // NOLINT(misc-no-recursion)
1031 {
1032   PHNodeIterator nodeiter(startNode);
1033   PHPointerListIterator<PHNode> iterat(nodeiter.ls());
1034   PHNode *thisNode;
1035   while ((thisNode = iterat()))
1036   {
1037     if ((thisNode->getType() == "PHCompositeNode"))
1038     {
1039       // NOLINTNEXTLINE(cppcoreguidelines-pro-type-static-cast-downcast)
1040       MakeNodesPersistent(static_cast<PHCompositeNode *>(thisNode));  // if this is a CompositeNode do this trick again
1041     }
1042     else
1043     {
1044       thisNode->makePersistent();
1045     }
1046   }
1047   return 0;
1048 }
1049 
1050 int Fun4AllServer::EndRun(const int runno)
1051 {
1052   std::vector<std::pair<SubsysReco *, PHCompositeNode *>>::iterator iter;
1053   gROOT->cd(default_Tdirectory.c_str());
1054   std::string currdir = gDirectory->GetPath();
1055   for (iter = Subsystems.begin(); iter != Subsystems.end(); ++iter)
1056   {
1057     if (Verbosity() >= VERBOSITY_MORE)
1058     {
1059       std::cout << "Fun4AllServer::EndRun: EndRun("
1060                 << runno << ") for " << (*iter).first->Name() << std::endl;
1061     }
1062     std::string newdirname = (*iter).second->getName() + "/" + (*iter).first->Name();
1063     if (!gROOT->cd(newdirname.c_str()))
1064     {
1065       std::cout << PHWHERE << "Unexpected TDirectory Problem cd'ing to "
1066                 << (*iter).second->getName()
1067                 << " - send e-mail to off-l with your macro" << std::endl;
1068       exit(1);
1069     }
1070     else
1071     {
1072       if (Verbosity() >= VERBOSITY_EVEN_MORE)
1073       {
1074         std::cout << "EndRun: cded to " << newdirname << std::endl;
1075       }
1076     }
1077     try
1078     {
1079       (*iter).first->EndRun(runno);
1080     }
1081     catch (const std::exception &e)
1082     {
1083       std::cout << PHWHERE << " caught exception thrown during SubsysReco::EndRun() from "
1084                 << (*iter).first->Name() << std::endl;
1085       std::cout << "error: " << e.what() << std::endl;
1086       exit(1);
1087     }
1088     catch (...)
1089     {
1090       std::cout << PHWHERE << " caught unknown type exception thrown during SubsysReco::EndRun() from "
1091                 << (*iter).first->Name() << std::endl;
1092       exit(1);
1093     }
1094   }
1095   gROOT->cd(currdir.c_str());
1096 
1097   return 0;
1098 }
1099 
1100 int Fun4AllServer::End()
1101 {
1102   recoConsts *rc = recoConsts::instance();
1103   EndRun(rc->get_IntFlag("RUNNUMBER"));  // call SubsysReco EndRun methods for current run
1104   int i = 0;
1105   std::vector<std::pair<SubsysReco *, PHCompositeNode *>>::iterator iter;
1106   gROOT->cd(default_Tdirectory.c_str());
1107   std::string currdir = gDirectory->GetPath();
1108   for (iter = Subsystems.begin(); iter != Subsystems.end(); ++iter)
1109   {
1110     if (Verbosity() >= VERBOSITY_SOME)
1111     {
1112       std::cout << "Fun4AllServer::End: End for " << (*iter).first->Name() << std::endl;
1113     }
1114     std::string newdirname = (*iter).second->getName() + "/" + (*iter).first->Name();
1115     if (!gROOT->cd(newdirname.c_str()))
1116     {
1117       std::cout << PHWHERE << "Unexpected TDirectory Problem cd'ing to "
1118                 << (*iter).second->getName()
1119                 << " - send e-mail to off-l with your macro" << std::endl;
1120       exit(1);
1121     }
1122     else
1123     {
1124       if (Verbosity() >= VERBOSITY_EVEN_MORE)
1125       {
1126         std::cout << "End: cded to " << newdirname << std::endl;
1127       }
1128     }
1129     try
1130     {
1131       i += (*iter).first->End((*iter).second);
1132     }
1133     catch (const std::exception &e)
1134     {
1135       std::cout << PHWHERE << " caught exception thrown during SusbsysReco::End() from "
1136                 << (*iter).first->Name() << std::endl;
1137       std::cout << "error: " << e.what() << std::endl;
1138       exit(1);
1139     }
1140     catch (...)
1141     {
1142       std::cout << PHWHERE << " caught unknown type exception thrown during SubsysReco::End() from "
1143                 << (*iter).first->Name() << std::endl;
1144       exit(1);
1145     }
1146   }
1147   gROOT->cd(currdir.c_str());
1148   PHNodeIterator nodeiter(TopNode);
1149   PHCompositeNode *runNode = dynamic_cast<PHCompositeNode *>(nodeiter.findFirst("PHCompositeNode", "RUN"));
1150   if (!runNode)
1151   {
1152     std::cout << "No Run Node, not writing Runwise info" << std::endl;
1153   }
1154   else
1155   {
1156     if (!OutputManager.empty())  // there are registered IO managers
1157     {
1158       MakeNodesTransient(runNode);  // make all nodes transient by default
1159       std::vector<Fun4AllOutputManager *>::iterator IOiter;
1160       for (IOiter = OutputManager.begin(); IOiter != OutputManager.end(); ++IOiter)
1161       {
1162         (*IOiter)->WriteNode(runNode);
1163       }
1164     }
1165   }
1166   // close output files (check for existing output managers is
1167   // done inside outfileclose())
1168   outfileclose();
1169   for (auto &histit : HistoManager)
1170   {
1171     if (histit->ApplyFileRule())
1172     {
1173       if (! histit->isEmpty())
1174       {
1175     histit->dumpHistos();
1176       }
1177       else
1178       {
1179     if (Verbosity() > 0)
1180     {
1181       std::cout << "only empty histos in " << histit->Name() << std::endl;
1182     }
1183       }
1184     }
1185   }
1186   if (ScreamEveryEvent)
1187   {
1188     std::cout << "*******************************************************************************" << std::endl;
1189     std::cout << "*******************************************************************************" << std::endl;
1190     std::cout << "*******************************************************************************" << std::endl;
1191     std::cout << "Now that we are at the End(), please fix the following "
1192               << ScreamEveryEvent << " problem(s):" << std::endl;
1193     std::vector<std::string>::const_iterator viter;
1194     for (viter = ComplaintList.begin(); viter != ComplaintList.end(); ++viter)
1195     {
1196       std::cout << *viter << std::endl;
1197     }
1198     std::cout << " " << std::endl;
1199     std::cout << "*******************************************************************************" << std::endl;
1200     std::cout << "*******************************************************************************" << std::endl;
1201     std::cout << "*******************************************************************************" << std::endl;
1202   }
1203 
1204   return i;
1205 }
1206 
1207 void Fun4AllServer::Print(const std::string &what) const
1208 {
1209   if (what == "ALL" || what == "HISTOS")
1210   {
1211     // loop over the map and print out the content (name and location in memory)
1212     for (const auto &histoman : HistoManager)
1213     {
1214       histoman->Print(what);
1215     }
1216   }
1217   if (what == "ALL" || what == "SUBSYSTEMS")
1218   {
1219     // loop over the map and print out the content (name and location in memory)
1220     std::cout << "--------------------------------------" << std::endl
1221               << std::endl;
1222     std::cout << "List of Subsystems in Fun4AllServer:" << std::endl;
1223 
1224     std::vector<std::pair<SubsysReco *, PHCompositeNode *>>::const_iterator miter;
1225     for (miter = Subsystems.begin(); miter != Subsystems.end(); ++miter)
1226     {
1227       std::cout << (*miter).first->Name()
1228                 << " running under topNode " << (*miter).second->getName() << std::endl;
1229     }
1230     std::cout << std::endl;
1231   }
1232 
1233   if (what == "ALL" || what == "INPUTMANAGER")
1234   {
1235     // the input managers are managed by the input singleton
1236     for (const auto &syncman : SyncManagers)
1237     {
1238       std::cout << "SyncManager: " << syncman->Name() << std::endl;
1239       syncman->Print(what);
1240     }
1241   }
1242 
1243   if (what == "ALL" || what.find("OUTPUTMANAGER") != std::string::npos)
1244   {
1245     // loop over the map and print out the content (name and location in memory)
1246     std::string pass_on = what;
1247     if (pass_on == "ALL" || pass_on == "OUTPUTMANAGER")
1248     {
1249       std::cout << "--------------------------------------" << std::endl
1250                 << std::endl;
1251       std::cout << "List of OutputManagers in Fun4AllServer:" << std::endl;
1252       pass_on = "ALL";
1253     }
1254     else
1255     {
1256       std::string::size_type pos = pass_on.find('%');
1257       pass_on = pass_on.substr(pos + 1, pass_on.size());
1258     }
1259     for (const auto &outman : OutputManager)
1260     {
1261       outman->Print(pass_on);
1262     }
1263     std::cout << std::endl;
1264   }
1265   if (what == "ALL" || what == "TOPNODES")
1266   {
1267     // loop over the map and print out the content (name and location in memory)
1268     std::cout << "--------------------------------------" << std::endl
1269               << std::endl;
1270     std::cout << "List of TopNodes in Fun4AllServer:" << std::endl;
1271 
1272     std::map<std::string, PHCompositeNode *>::const_iterator iter;
1273     for (iter = topnodemap.begin(); iter != topnodemap.end(); ++iter)
1274     {
1275       std::cout << iter->first << " is at " << std::hex
1276                 << iter->second << std::dec << std::endl;
1277     }
1278     std::cout << std::endl;
1279   }
1280   if (what == "ALL" || what == "NODETREE")
1281   {
1282     // loop over the map and print out the content (name and location in memory)
1283     std::cout << "--------------------------------------" << std::endl
1284               << std::endl;
1285     std::cout << "List of Nodes in Fun4AllServer:" << std::endl;
1286 
1287     std::map<std::string, PHCompositeNode *>::const_iterator iter;
1288     for (iter = topnodemap.begin(); iter != topnodemap.end(); ++iter)
1289     {
1290       std::cout << "Node Tree under TopNode " << iter->first << std::endl;
1291       PHNodeIterator nodeiter(iter->second);
1292       nodeiter.print();
1293       std::cout << std::endl;
1294     }
1295     std::cout << std::endl;
1296   }
1297   return;
1298 }
1299 
1300 void Fun4AllServer::identify(std::ostream &out) const
1301 {
1302   out << "Fun4AllServer Name: " << Name() << std::endl;
1303   return;
1304 }
1305 
1306 int Fun4AllServer::outfileclose()
1307 {
1308   while (!OutputManager.empty())
1309   {
1310     if (Verbosity() >= VERBOSITY_MORE)
1311     {
1312       std::cout << "Erasing OutputManager "
1313                 << (*OutputManager.begin())->Name()
1314                 << " at memory location " << *(OutputManager.begin()) << std::endl;
1315     }
1316     delete *(OutputManager.begin());
1317     OutputManager.erase(OutputManager.begin());
1318   }
1319   return 0;
1320 }
1321 
1322 int Fun4AllServer::InitNodeTree(PHCompositeNode *topNode)
1323 {
1324   PHCompositeNode *dstNode;
1325   PHCompositeNode *runNode;
1326   PHCompositeNode *parNode;
1327   dstNode = new PHCompositeNode("DST");
1328   topNode->addNode(dstNode);
1329   runNode = new PHCompositeNode("RUN");
1330   topNode->addNode(runNode);
1331   parNode = new PHCompositeNode("PAR");
1332   topNode->addNode(parNode);
1333   return 0;
1334 }
1335 
1336 PHCompositeNode *
1337 Fun4AllServer::topNode(const std::string &name)
1338 {
1339   std::map<std::string, PHCompositeNode *>::const_iterator iter;
1340   iter = topnodemap.find(name);
1341   if (iter != topnodemap.end())
1342   {
1343     return iter->second;
1344   }
1345   AddTopNode(name);
1346   iter = topnodemap.find(name);
1347   if (iter != topnodemap.end())
1348   {
1349     InitNodeTree(iter->second);
1350     return iter->second;
1351   }
1352   std::cout << PHWHERE << " Could not create new topNode " << name
1353             << " send email to off-l with the following printout: " << std::endl;
1354   for (iter = topnodemap.begin(); iter != topnodemap.end(); ++iter)
1355   {
1356     std::cout << iter->first << " is at " << std::hex << iter->second << std::dec << std::endl;
1357   }
1358   exit(1);
1359 }
1360 
1361 int Fun4AllServer::AddTopNode(const std::string &name)
1362 {
1363   std::map<std::string, PHCompositeNode *>::const_iterator iter;
1364   iter = topnodemap.find(name);
1365   if (iter != topnodemap.end())
1366   {
1367     return -1;
1368   }
1369   PHCompositeNode *newNode = new PHCompositeNode(name);
1370   topnodemap[name] = newNode;
1371   return 0;
1372 }
1373 
1374 PHCompositeNode *Fun4AllServer::getNode(const std::string &name, const std::string &topnodename)
1375 {
1376   PHNodeIterator iter(topNode(topnodename));
1377   PHCompositeNode *thisNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", name));
1378   if (!thisNode)
1379   {
1380     thisNode = new PHCompositeNode(name);
1381     topNode(topnodename)->addNode(thisNode);
1382   }
1383   return thisNode;
1384 }
1385 
1386 int Fun4AllServer::registerInputManager(Fun4AllInputManager *InManager)
1387 {
1388   int iret = defaultSyncManager->registerInputManager(InManager);
1389   return iret;
1390 }
1391 
1392 Fun4AllInputManager *
1393 Fun4AllServer::getInputManager(const std::string &name)
1394 {
1395   std::vector<Fun4AllSyncManager *>::const_iterator iter;
1396   for (iter = SyncManagers.begin(); iter != SyncManagers.end(); ++iter)
1397   {
1398     if ((*iter)->getInputManager(name))
1399     {
1400       return (*iter)->getInputManager(name);
1401     }
1402   }
1403   std::cout << "Could not locate input manager " << name << std::endl;
1404   return nullptr;
1405 }
1406 
1407 int Fun4AllServer::PrdfEvents() const
1408 {
1409   return (defaultSyncManager->PrdfEvents());
1410 }
1411 
1412 int Fun4AllServer::DstEvents() const
1413 {
1414   return (defaultSyncManager->TotalEvents());
1415 }
1416 
1417 //_________________________________________________________________
1418 int Fun4AllServer::run(const int nevnts, const bool require_nevents)
1419 {
1420   recoConsts *rc = recoConsts::instance();
1421   static bool run_number_forced = rc->FlagExist("RUNNUMBER");
1422   static int ifirst = 1;
1423   if (ifirst && run_number_forced)
1424   {
1425     runnumber = rc->get_IntFlag("RUNNUMBER");
1426     std::cout << "Fun4AllServer: Runnumber forced to " << runnumber << " by RUNNUMBER IntFlag" << std::endl;
1427   }
1428   int iret = 0;
1429   int icnt = 0;
1430   int icnt_good = 0;
1431   std::vector<Fun4AllSyncManager *>::const_iterator iter;
1432   while (!iret)
1433   {
1434     int resetnodetree = 0;
1435     for (iter = SyncManagers.begin(); iter != SyncManagers.end(); ++iter)
1436     {
1437       if (Verbosity() >= VERBOSITY_MORE)
1438       {
1439         std::cout << "executing run for input master " << (*iter)->Name() << std::endl;
1440       }
1441       int retval = (*iter)->run(1);
1442       // if a new input file is opened during syncing and it contains
1443       // different nodes
1444       // as the previous one, the info in the nodes which are only in
1445       // the previous file will be carried to another event. We also
1446       // do not know under which topNode the input managers put
1447       // their data. This is why
1448       // the whole node tree is resetted whenever one of the Sync Managers
1449       // requires it.
1450       if (retval == Fun4AllReturnCodes::RESET_NODE_TREE)
1451       {
1452         resetnodetree = 1;
1453       }
1454       else
1455       {
1456         iret += retval;
1457       }
1458     }
1459     if (resetnodetree)
1460     {
1461       // if the node tree needs resetting, we just push the current
1462       // event(s) (which are all properly synced at this point)
1463       // back into the input managers and just read again.
1464       for (iter = SyncManagers.begin(); iter != SyncManagers.end(); ++iter)
1465       {
1466         (*iter)->PushBackInputMgrsEvents(1);
1467       }
1468       ResetNodeTree();
1469       continue;  // go back to run loop
1470     }
1471     if (iret)
1472     {
1473       break;
1474     }
1475     int currentrun = 0;
1476     for (iter = SyncManagers.begin(); iter != SyncManagers.end(); ++iter)
1477     {
1478       int runno = (*iter)->CurrentRun();
1479       //      std::cout << (*iter)->Name() << " run no: " << runno << std::endl;
1480       if (runno != 0)
1481       {
1482         if (currentrun == 0)
1483         {
1484           currentrun = runno;
1485         }
1486         else
1487         {
1488           if (currentrun != runno)
1489           {
1490             if (!(*iter)->MixRunsOk())
1491             {
1492               std::cout << "Mixing of Runs within same event is not supported" << std::endl;
1493               std::cout << "Here is the list of Sync Managers and their runnumbers:" << std::endl;
1494               std::vector<Fun4AllSyncManager *>::const_iterator syiter;
1495               for (syiter = SyncManagers.begin(); syiter != SyncManagers.end(); ++syiter)
1496               {
1497                 std::cout << (*syiter)->Name() << " run number: " << (*syiter)->CurrentRun() << std::endl;
1498               }
1499               std::cout << "Exiting now" << std::endl;
1500               exit(1);
1501             }
1502           }
1503         }
1504       }
1505     }
1506     if (ifirst)
1507     {
1508       if (currentrun != runnumber && !run_number_forced)  // use real run if not forced
1509       {
1510         runnumber = currentrun;
1511       }
1512       setRun(runnumber);
1513       BeginRun(runnumber);
1514       ifirst = 0;
1515     }
1516     else if (!run_number_forced)
1517     {
1518       if (currentrun != runnumber)
1519       {
1520         EndRun(runnumber);
1521         runnumber = currentrun;
1522         setRun(runnumber);
1523         BeginRun(runnumber);
1524       }
1525     }
1526     if (Verbosity() >= 1 && ((icnt + 1) % VerbosityDownscale() == 0))
1527     {
1528       std::cout << "Fun4AllServer::run - processing event "
1529                 << (icnt + 1) << " from run " << runnumber << std::endl;
1530     }
1531 
1532     if (icnt == 0 && Verbosity() > VERBOSITY_QUIET)
1533     {
1534       // increase verbosity for the first event in verbose modes
1535       int iverb = Verbosity();
1536       Verbosity(++iverb);
1537     }
1538 
1539     iret = process_event();
1540 
1541     if (icnt == 0 && Verbosity() > VERBOSITY_QUIET)
1542     {
1543       // increase verbosity for the first event in verbose modes
1544       int iverb = Verbosity();
1545       Verbosity(--iverb);
1546     }
1547 
1548     ++icnt;  // completed one event processing
1549 
1550     if (require_nevents)
1551     {
1552       if (std::find(RetCodes.begin(),
1553                     RetCodes.end(),
1554                     static_cast<int>(Fun4AllReturnCodes::ABORTEVENT)) == RetCodes.end())
1555       {
1556         icnt_good++;
1557       }
1558       if (iret || (nevnts > 0 && icnt_good >= nevnts))
1559       {
1560         break;
1561       }
1562     }
1563     else if (iret || (nevnts > 0 && icnt >= nevnts))
1564     {
1565       break;
1566     }
1567   }
1568   return iret;
1569 }
1570 
1571 //_________________________________________________________________
1572 int Fun4AllServer::skip(const int nevnts)
1573 {
1574   int iret = 0;
1575   if (nevnts > 0)  // do not execute for nevnts <= 0
1576   {
1577     std::vector<Fun4AllSyncManager *>::const_iterator iter;
1578     for (iter = SyncManagers.begin(); iter != SyncManagers.end(); ++iter)
1579     {
1580       iret += (*iter)->skip(nevnts);
1581     }
1582     eventcounter += nevnts;  // update event counter so it reflects the number of events in the input
1583   }
1584   return iret;
1585 }
1586 
1587 //_________________________________________________________________
1588 int Fun4AllServer::fileopen(const std::string &managername, const std::string &filename)
1589 {
1590   int iret = 0;
1591   std::vector<Fun4AllSyncManager *>::const_iterator iter;
1592   for (iter = SyncManagers.begin(); iter != SyncManagers.end(); ++iter)
1593   {
1594     iret += (*iter)->fileopen(managername, filename);
1595   }
1596   return iret;
1597 }
1598 
1599 int Fun4AllServer::BranchSelect(const std::string &managername, const std::string &branch, int iflag)
1600 {
1601   int iret = 0;
1602   std::vector<Fun4AllSyncManager *>::const_iterator iter;
1603   for (iter = SyncManagers.begin(); iter != SyncManagers.end(); ++iter)
1604   {
1605     iret += (*iter)->BranchSelect(managername, branch, iflag);
1606   }
1607   return iret;
1608 }
1609 
1610 int Fun4AllServer::BranchSelect(const std::string &branch, int iflag)
1611 {
1612   int iret = 0;
1613   std::vector<Fun4AllSyncManager *>::const_iterator iter;
1614   for (iter = SyncManagers.begin(); iter != SyncManagers.end(); ++iter)
1615   {
1616     iret += (*iter)->BranchSelect(branch, iflag);
1617   }
1618   return iret;
1619 }
1620 
1621 int Fun4AllServer::setBranches(const std::string &managername)
1622 {
1623   int iret = 0;
1624   std::vector<Fun4AllSyncManager *>::const_iterator iter;
1625   for (iter = SyncManagers.begin(); iter != SyncManagers.end(); ++iter)
1626   {
1627     iret += (*iter)->setBranches(managername);
1628   }
1629   return iret;
1630 }
1631 
1632 int Fun4AllServer::setBranches()
1633 {
1634   int iret = 0;
1635   std::vector<Fun4AllSyncManager *>::const_iterator iter;
1636   for (iter = SyncManagers.begin(); iter != SyncManagers.end(); ++iter)
1637   {
1638     iret += (*iter)->setBranches();
1639   }
1640   return iret;
1641 }
1642 
1643 int Fun4AllServer::fileclose(const std::string &managername)
1644 {
1645   int iret = 0;
1646   std::vector<Fun4AllSyncManager *>::const_iterator iter;
1647   for (iter = SyncManagers.begin(); iter != SyncManagers.end(); ++iter)
1648   {
1649     iret += (*iter)->fileclose(managername);
1650   }
1651   return iret;
1652 }
1653 
1654 int Fun4AllServer::SegmentNumber()
1655 {
1656   int iret = defaultSyncManager->SegmentNumber();
1657   return iret;
1658 }
1659 
1660 void Fun4AllServer::GetInputFullFileList(std::vector<std::string> &fnames) const
1661 {
1662   defaultSyncManager->GetInputFullFileList(fnames);
1663   return;
1664 }
1665 
1666 unsigned
1667 Fun4AllServer::GetTopNodes(std::vector<std::string> &names) const
1668 {
1669   std::map<std::string, PHCompositeNode *>::const_iterator iter;
1670   for (iter = topnodemap.begin(); iter != topnodemap.end(); ++iter)
1671   {
1672     names.push_back(iter->first);
1673   }
1674   return names.size();
1675 }
1676 
1677 void Fun4AllServer::GetOutputManagerList(std::vector<std::string> &names) const
1678 {
1679   names.clear();
1680   std::vector<Fun4AllOutputManager *>::const_iterator iter;
1681   for (iter = OutputManager.begin(); iter != OutputManager.end(); ++iter)
1682   {
1683     names.push_back((*iter)->Name());
1684   }
1685   return;
1686 }
1687 
1688 void Fun4AllServer::GetModuleList(std::vector<std::string> &names) const
1689 {
1690   names.clear();
1691   std::vector<std::pair<SubsysReco *, PHCompositeNode *>>::const_iterator iter;
1692   for (iter = Subsystems.begin(); iter != Subsystems.end(); ++iter)
1693   {
1694     names.push_back((*iter).first->Name());
1695   }
1696   return;
1697 }
1698 
1699 int Fun4AllServer::registerSyncManager(Fun4AllSyncManager *newmaster)
1700 {
1701   for (auto &syncman : SyncManagers)
1702   {
1703     if (syncman->Name() == newmaster->Name())
1704     {
1705       std::cout << "Input Master " << newmaster->Name()
1706                 << " already registered" << std::endl;
1707       return -1;
1708     }
1709   }
1710   if (Verbosity() >= VERBOSITY_SOME)
1711   {
1712     std::cout << "Registering Input Master " << newmaster->Name() << std::endl;
1713   }
1714   SyncManagers.push_back(newmaster);
1715   return 0;
1716 }
1717 
1718 Fun4AllSyncManager *
1719 Fun4AllServer::getSyncManager(const std::string &name)
1720 {
1721   if (name == "DefaultSyncManager")
1722   {
1723     return defaultSyncManager;
1724   }
1725   std::vector<Fun4AllSyncManager *>::iterator iter;
1726 
1727   for (iter = SyncManagers.begin(); iter != SyncManagers.end(); ++iter)
1728   {
1729     if ((*iter)->Name() == name)
1730     {
1731       return *iter;
1732     }
1733   }
1734   std::cout << "Could not find Input Master " << name << std::endl;
1735   return nullptr;
1736 }
1737 
1738 int Fun4AllServer::setRun(const int runno)
1739 {
1740   recoConsts *rc = recoConsts::instance();
1741   rc->set_IntFlag("RUNNUMBER", runno);
1742   if (!rc->FlagExist("TIMESTAMP"))
1743   {
1744     rc->set_uint64Flag("TIMESTAMP", runno);
1745   }
1746   std::cout << "Fun4AllServer::setRun(): run " << runno
1747             << " uses CDB TIMESTAMP " << rc->get_uint64Flag("TIMESTAMP")
1748             << std::endl;
1749   FrameWorkVars->SetBinContent(RUNNUMBERBIN, (Stat_t) runno);
1750   return 0;
1751 }
1752 
1753 void Fun4AllServer::NodeIdentify(const std::string &name)
1754 {
1755   PHObject *obj = findNode::getClass<PHObject>(TopNode, name);
1756   if (obj)
1757   {
1758     obj->identify();
1759   }
1760   else
1761   {
1762     std::cout << "Could not locate node " << name
1763               << " or no PHObject Node" << std::endl;
1764   }
1765   return;
1766 }
1767 
1768 void Fun4AllServer::PrintTimer(const std::string &name)
1769 {
1770   std::map<const std::string, PHTimer>::const_iterator iter;
1771   PHTimer::PRINT(std::cout, "**");
1772   if (name.empty())
1773   {
1774     for (iter = timer_map.begin(); iter != timer_map.end(); ++iter)
1775     {
1776       iter->second.print_stat();
1777     }
1778   }
1779   else
1780   {
1781     iter = timer_map.find(name);
1782     if (iter != timer_map.end())
1783     {
1784       iter->second.print_stat();
1785     }
1786     else
1787     {
1788       std::cout << "No timer with name " << name << " found" << std::endl;
1789       std::cout << "Existing timers:" << std::endl;
1790       for (iter = timer_map.begin(); iter != timer_map.end(); ++iter)
1791       {
1792         std::cout << iter->first << std::endl;
1793       }
1794     }
1795   }
1796   return;
1797 }
1798 
1799 void Fun4AllServer::PrintMemoryTracker(const std::string &name)
1800 {
1801 #ifdef FFAMEMTRACKER
1802   ffamemtracker->PrintMemoryTracker(name);
1803 #else
1804   std::cout << "PrintMemoryTracker called with " << name << " is disabled" << std::endl;
1805 #endif
1806   return;
1807 }
1808 
1809 int Fun4AllServer::UpdateRunNode()
1810 {
1811   int iret{Fun4AllReturnCodes::EVENT_OK};
1812   for (auto &Subsystem : Subsystems)
1813   {
1814     iret += Subsystem.first->UpdateRunNode(Subsystem.second);
1815   }
1816   return iret;
1817 }