Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-12-17 09:19:43

0001 #include "Fun4AllSyncManager.h"
0002 
0003 #include "Fun4AllInputManager.h"
0004 #include "Fun4AllReturnCodes.h"  // for EVENT_OK, RESET_NODE_TREE
0005 #include "Fun4AllServer.h"
0006 
0007 #include <ffaobjects/SyncObject.h>
0008 
0009 #include <phool/phool.h>  // for PHWHERE
0010 
0011 #include <TSystem.h>
0012 
0013 #include <cstdlib>
0014 #include <iostream>  // for operator<<, endl, basic_ostream
0015 #include <list>      // for list<>::const_iterator, _List_con...
0016 #include <string>
0017 #include <utility>  // for pair
0018 #include <vector>
0019 
0020 Fun4AllSyncManager::Fun4AllSyncManager(const std::string &name)
0021   : Fun4AllBase(name)
0022 {
0023   return;
0024 }
0025 
0026 Fun4AllSyncManager::~Fun4AllSyncManager()
0027 {
0028   delete m_MasterSync;
0029   while (m_InManager.begin() != m_InManager.end())
0030   {
0031     if (Verbosity())
0032     {
0033       m_InManager.back()->Verbosity(Verbosity());
0034     }
0035     delete m_InManager.back();
0036     m_InManager.pop_back();
0037   }
0038   return;
0039 }
0040 
0041 int Fun4AllSyncManager::registerInputManager(Fun4AllInputManager *InputManager)
0042 {
0043   for (Fun4AllInputManager *inman : m_InManager)
0044   {
0045     if (inman->Name() == InputManager->Name())
0046     {
0047       std::cout << "InputManager " << InputManager->Name() << " allready in list" << std::endl;
0048       return -1;
0049     }
0050   }
0051 
0052   if (Verbosity() > 0)
0053   {
0054     std::cout << "Registering InputManager " << InputManager->Name() << std::endl;
0055   }
0056   m_InManager.push_back(InputManager);
0057   m_iretInManager.push_back(0);
0058   InputManager->setSyncManager(this);
0059   return 0;
0060 }
0061 
0062 Fun4AllInputManager *
0063 Fun4AllSyncManager::getInputManager(const std::string &name)
0064 {
0065   for (Fun4AllInputManager *inman : m_InManager)
0066   {
0067     if (name == inman->Name())
0068     {
0069       return inman;
0070     }
0071   }
0072   std::cout << Name() << ": Could not find InputManager" << name << std::endl;
0073   return nullptr;
0074 }
0075 
0076 //_________________________________________________________________
0077 int Fun4AllSyncManager::run(const int nevnts)
0078 {
0079   int iret = 0;
0080   int icnt = 0;
0081   int iretsync = 0;
0082   int resetnodetree = 0;
0083   // on read errors (assumed to be caused that a file is empty and we need to open the next one)
0084   // we have to go through this 3 times
0085   // 1st pass: The error is detected (for all input mgrs), for the failed input manager(s) a fileclose(), fileopen() is executed, if this fails control goes back to Fun4All since we are done. For input managers without errors, the event is pushed back, so it is read again in the next pass
0086   // 2nd pass: Events are read from all input managers. If no errors all input managers are pushed back
0087   // The reason for this is that we opened a new files with maybe different content and we need to clean
0088   // the node tree so we do not propagate old objects from the previous event
0089   // The node tree reset is done by the Fun4AllServer so we give control back and signal via resetnodetree return code
0090   // 3rd pass: read from every input manager and go back to Fun4All
0091 
0092   while (!iret)
0093   {
0094     unsigned iman = 0;
0095     int ifirst = 0;
0096     int hassync = 0;
0097     for (auto &iter : m_InManager)
0098     {
0099       m_iretInManager[iman] = iter->run(1);
0100       iret += m_iretInManager[iman];
0101       // one can run DSTs without sync object via the DST input manager
0102       // this only poses a problem if one runs two of them and expects the syncing to work
0103       // or mix DSTs with sync object and without
0104       if (!hassync && iter->HasSyncObject())  // only update if hassync is 0 and input mgr is non zero
0105       {
0106         hassync = iter->HasSyncObject();
0107       }
0108       else
0109       {
0110         if (iter->HasSyncObject())  // if zero (no syncing) no need to go further
0111         {
0112           if (hassync != iter->HasSyncObject())  // we have sync and no sync mixed
0113           // NOLINTNEXTLINE(bugprone-branch-clone)
0114           {
0115             PrintSyncProblem();
0116             gSystem->Exit(1);
0117             exit(1);
0118           }
0119           else if (hassync < 0)  // we have more than one nosync input
0120           {
0121             PrintSyncProblem();
0122             gSystem->Exit(1);
0123             exit(1);
0124           }
0125         }
0126       }
0127       if (!ifirst)
0128       {
0129         if (!m_iretInManager[iman])
0130         {
0131           if (!(iter->GetSyncObject(&m_MasterSync)))  // NoSync managers return non zero
0132           {
0133         if (Verbosity() > 2)
0134         {
0135           std::cout << "got sync object from " << iter->Name() << std::endl;
0136           m_MasterSync->identify();
0137         }
0138             ifirst = 1;
0139           }
0140         }
0141       }
0142       else
0143       {
0144         iretsync = CheckSync(iman);
0145         if (iretsync)
0146         {
0147           break;
0148         }
0149       }
0150       iman++;
0151     }
0152 
0153     // check event reading, synchronisation
0154     if (iret || iretsync)
0155     {
0156       // tell the server to reset the node tree
0157       resetnodetree = Fun4AllReturnCodes::RESET_NODE_TREE;
0158 
0159       // if there was an io error (file exhausted) we nee to push back
0160       // the events from files which are not exhausted yet into the root files
0161       // here we check the return codes for each input manager and if the
0162       // read was successful (iret = 0) we push the event back
0163       if (iret)
0164       {
0165         unsigned inputmgr_cnt = 0;
0166         std::vector<Fun4AllInputManager *>::const_iterator InIter;
0167         // set in the macro for Sync Manager. Permanently enabled (default when using syncman->Repeat(),
0168         // m_Repeat = -1 so the m_Repeat--; is not called, this is used when you give it a positive number of
0169         // repetitions
0170         if (m_Repeat)
0171         {
0172           for (InIter = m_InManager.begin(); InIter != m_InManager.end(); ++InIter)
0173           {
0174             if (m_iretInManager[inputmgr_cnt] == Fun4AllReturnCodes::EVENT_OK)
0175             {
0176               (*InIter)->PushBackEvents(1);
0177             }
0178             else
0179             {
0180               if ((*InIter)->IsOpen())
0181               {
0182                 (*InIter)->fileclose();
0183               }
0184               int ireset = (*InIter)->ResetFileList();
0185               if (ireset)
0186               {
0187                 std::cout << "Resetting input manager " << (*InIter)->Name() << " failed during Repeat" << std::endl;
0188                 exit(1);
0189               }
0190               inputmgr_cnt++;
0191             }
0192           }
0193           if (m_Repeat > 0)
0194           {
0195             m_Repeat--;
0196           }
0197           iret = 0;
0198           continue;  // got back and run again
0199         }
0200         // push back events where the Imanager did not report an error
0201         InIter = m_InManager.begin();
0202         for (int iter : m_iretInManager)
0203         {
0204           if (Verbosity() > 0)
0205           {
0206             std::cout << (*InIter)->Name() << ": return code: " << iter << std::endl;
0207           }
0208           if (!iter)
0209           {
0210             (*InIter)->PushBackEvents(1);
0211             if (Verbosity() > 0)
0212             {
0213               std::cout << (*InIter)->Name() << ": push evts: " << iter << std::endl;
0214             }
0215           }
0216           ++InIter;
0217         }
0218         // NOLINTNEXTLINE(hicpp-avoid-goto)
0219         goto readerror;
0220       }
0221       else
0222       {
0223         // just read the next event and hope it syncs
0224         // this won't update the event counter
0225         for (unsigned nman = 0; nman < iman; nman++)
0226         {
0227           m_InManager[nman]->NoSyncPushBackEvents(1);
0228         }
0229         continue;
0230       }
0231     }
0232     if (!resetnodetree)
0233     {
0234       m_EventsTotal++;
0235     }
0236     // this check is meaningless nowadays since we call this method with 1 event every time
0237     // so we can just break here but maybe this changes in the future
0238     if (nevnts > 0 && ++icnt >= nevnts)
0239     {
0240       break;
0241     }
0242   }
0243 readerror:
0244   if (iret == 0)
0245   {
0246     if (resetnodetree == 0)  // all syncing is done and no read errors --> we have a good event in memory
0247     {
0248       m_CurrentRun = 0;  // reset current run to 0
0249       for (auto &iter : m_InManager)
0250       {
0251         int runno = iter->RunNumber();
0252         if (Verbosity() > 2)
0253         {
0254           std::cout << Name() << " input mgr " << iter->Name() << " run: " << runno << std::endl;
0255         }
0256         if (runno != 0)
0257         {
0258           if (m_CurrentRun == 0)
0259           {
0260             m_CurrentRun = runno;
0261             continue;
0262           }
0263 
0264           if (m_CurrentRun != runno && !m_MixRunsOkFlag)
0265           {
0266             std::cout << PHWHERE << "Mixing run numbers (except runnumber=0 which means no valid runnumber) is not supported" << std::endl;
0267             std::cout << "Here are the list of input managers and runnumbers:" << std::endl;
0268             for (Fun4AllInputManager *inman : m_InManager)
0269             {
0270               std::cout << inman->Name() << " runno: " << inman->RunNumber() << std::endl;
0271             }
0272             std::cout << "Exiting now" << std::endl;
0273             exit(1);
0274           }
0275         }
0276       }
0277 // at the point all sync objects contain the same event number as does our
0278 // local sync object copy which serves as reference for all sync objects
0279 // NB: if we run Fun4AllNoSyncDstInputManager.h they will not update this
0280 // if there is no master sync the event number will stay at 0 (from the Reset())
0281       if (m_MasterSync)
0282       {
0283     CurrentEvent(m_MasterSync->EventNumber());
0284       }
0285     }
0286     return resetnodetree;
0287   }
0288   return iret;
0289 }
0290 
0291 //_________________________________________________________________
0292 int Fun4AllSyncManager::skip(const int nevnts)
0293 {
0294   if (!m_InManager.empty())
0295   {
0296     int Npushback = -nevnts;
0297     // the PushBackEvents(const int nevents) "pushes back" events events into the root file
0298     // (technically it just decrements the local counter in the PHNodeIOManager)
0299     // giving it a negative argument will skip events
0300     // this is much faster than actually reading the events in
0301     int iret = 0;
0302     bool first = true;
0303     for (auto &iman : m_InManager)
0304     {
0305       if (iman->HasSyncObject())
0306       {
0307         if (first)
0308         {
0309           iret += iman->PushBackEvents(Npushback);
0310           first = false;
0311         }
0312       }
0313       else
0314       {
0315         iret += iman->SkipForThisManager(nevnts);
0316       }
0317     }
0318     if (!iret)
0319     {
0320       return 0;
0321     }
0322 
0323     std::cout << PHWHERE << " Error during skipping events" << std::endl;
0324     return iret;
0325   }
0326   std::cout << PHWHERE << " Cannot skip events: No Input Managers registered?" << std::endl;
0327   Print("INPUTMANAGER");
0328   std::cout << "If there are Input Managers in this list, send mail with this" << std::endl;
0329   std::cout << "error message to off-l" << std::endl;
0330   std::cout << "and include the macro you used" << std::endl;
0331   return -1;
0332 }
0333 
0334 //_________________________________________________________________
0335 int Fun4AllSyncManager::fileopen(const std::string &managername, const std::string &filename)
0336 {
0337   for (Fun4AllInputManager *inman : m_InManager)
0338   {
0339     if (managername == inman->Name())
0340     {
0341       int iret = inman->fileopen(filename);
0342       return iret;
0343     }
0344   }
0345   std::cout << "No Input Manager " << managername << " registered" << std::endl;
0346   return -1;
0347 }
0348 
0349 int Fun4AllSyncManager::BranchSelect(const std::string &managername, const std::string &branch, const int iflag)
0350 {
0351   for (Fun4AllInputManager *inman : m_InManager)
0352   {
0353     if (managername == inman->Name())
0354     {
0355       int iret = inman->BranchSelect(branch, iflag);
0356       return iret;
0357     }
0358   }
0359   std::cout << "No Input Manager " << managername << " registered" << std::endl;
0360   return -1;
0361 }
0362 
0363 int Fun4AllSyncManager::BranchSelect(const std::string &branch, const int iflag)
0364 {
0365   int iret = 0;
0366   for (Fun4AllInputManager *inman : m_InManager)
0367   {
0368     iret += inman->BranchSelect(branch, iflag);
0369   }
0370   return iret;
0371 }
0372 
0373 int Fun4AllSyncManager::setBranches(const std::string &managername)
0374 {
0375   for (Fun4AllInputManager *inman : m_InManager)
0376   {
0377     if (managername == inman->Name())
0378     {
0379       int iret = inman->setBranches();
0380       return iret;
0381     }
0382   }
0383   std::cout << "No Input Manager " << managername << " registered" << std::endl;
0384   return -1;
0385 }
0386 
0387 int Fun4AllSyncManager::setBranches()
0388 {
0389   int iret = 0;
0390   for (Fun4AllInputManager *inman : m_InManager)
0391   {
0392     iret += inman->setBranches();
0393   }
0394   return iret;
0395 }
0396 
0397 int Fun4AllSyncManager::fileclose(const std::string &managername)
0398 {
0399   int foundIt = 0;
0400   for (Fun4AllInputManager *inman : m_InManager)
0401   {
0402     if (managername == inman->Name() || managername.empty())
0403     {
0404       inman->fileclose();
0405       foundIt = 1;
0406     }
0407   }
0408   if (foundIt)
0409   {
0410     return 0;
0411   }
0412   std::cout << "No Input Manager " << managername << " registered" << std::endl;
0413   return -1;
0414 }
0415 
0416 void Fun4AllSyncManager::Print(const std::string &what) const
0417 {
0418   if (what == "ALL" || what == "INPUTMANAGER")
0419   {
0420     // loop over the map and print out the content (name and location in memory)
0421     std::cout << "--------------------------------------" << std::endl
0422               << std::endl;
0423     std::cout << "List of InputManagers in Fun4AllSyncManager "
0424               << Name() << ":" << std::endl;
0425 
0426     for (Fun4AllInputManager *inman : m_InManager)
0427     {
0428       std::cout << inman->Name() << std::endl;
0429     }
0430     std::cout << std::endl;
0431   }
0432   return;
0433 }
0434 
0435 int Fun4AllSyncManager::CheckSync(const unsigned i)
0436 {
0437   int iret;
0438   iret = m_InManager[i]->SyncIt(m_MasterSync);
0439   return iret;
0440 }
0441 
0442 void Fun4AllSyncManager::GetInputFullFileList(std::vector<std::string> &fnames) const
0443 {
0444   for (Fun4AllInputManager *InMan : m_InManager)
0445   {
0446     std::pair<std::list<std::string>::const_iterator, std::list<std::string>::const_iterator> beginend = InMan->FileOpenListBeginEnd();
0447     for (auto iter = beginend.first; iter != beginend.second; ++iter)
0448     {
0449       fnames.push_back(*iter);
0450     }
0451   }
0452   return;
0453 }
0454 
0455 void Fun4AllSyncManager::PushBackInputMgrsEvents(const int i)
0456 {
0457   for (Fun4AllInputManager *inman : m_InManager)
0458   {
0459     inman->PushBackEvents(i);
0460   }
0461   return;
0462 }
0463 
0464 int Fun4AllSyncManager::ResetEvent()
0465 {
0466   int iret = 0;
0467   for (Fun4AllInputManager *inman : m_InManager)
0468   {
0469     if (Verbosity() > 0)
0470     {
0471       std::cout << "Resetting Event for Input Manager " << inman->Name() << std::endl;
0472     }
0473     iret += inman->ResetEvent();
0474   }
0475   m_CurrentEvent = 0;
0476   return iret;
0477 }
0478 
0479 void Fun4AllSyncManager::CurrentEvent(const int evt)
0480 {
0481   m_CurrentEvent = evt;
0482   Fun4AllServer *se = Fun4AllServer::instance();
0483   se->EventNumber(evt);
0484   return;
0485 }
0486 
0487 void Fun4AllSyncManager::PrintSyncProblem() const
0488 {
0489   std::cout << "Bad use of Fun4AllDstInputManager for file(s) which do not have a synchronization object" << std::endl;
0490   std::cout << "This works for single streams but if you run with multiple input streams this might lead to event mixing" << std::endl;
0491   std::cout << "If you insist to run this (you take full responsibility), change the following in your macro: " << std::endl;
0492   for (auto *iter : m_InManager)
0493   {
0494     if (iter->HasSyncObject() < 0)
0495     {
0496       std::cout << "File " << iter->FileName() << " does not contain a sync object" << std::endl;
0497       std::cout << "Change its Fun4AllDstInputManager with name " << iter->Name() << " from Fun4AllDstInputManager to Fun4AllNoSyncDstInputManager" << std::endl;
0498     }
0499   }
0500   return;
0501 }