Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-06 08:19:20

0001 /*!
0002  * \file Fun4AllSingleDstPileupInputManager.cc
0003  * \author Hugo Pereira Da Costa <hugo.pereira-da-costa@cea.fr>
0004  */
0005 
0006 #include "Fun4AllSingleDstPileupInputManager.h"
0007 #include "Fun4AllDstPileupMerger.h"
0008 
0009 #include <fun4all/Fun4AllReturnCodes.h>
0010 #include <fun4all/Fun4AllServer.h>
0011 
0012 #include <ffaobjects/RunHeader.h>
0013 
0014 #include <frog/FROG.h>
0015 
0016 #include <phool/PHCompositeNode.h>
0017 #include <phool/PHNodeIOManager.h>
0018 #include <phool/PHNodeIntegrate.h>
0019 #include <phool/PHNodeIterator.h>  // for PHNodeIterator
0020 #include <phool/PHRandomSeed.h>
0021 #include <phool/getClass.h>
0022 #include <phool/phool.h>  // for PHWHERE, PHReadOnly, PHRunTree
0023 
0024 #include <TSystem.h>
0025 
0026 #include <gsl/gsl_randist.h>
0027 
0028 #include <cassert>
0029 #include <iostream>  // for operator<<, basic_ostream, endl
0030 #include <utility>   // for pair
0031 
0032 //_____________________________________________________________________________
0033 Fun4AllSingleDstPileupInputManager::Fun4AllSingleDstPileupInputManager(const std::string &name, const std::string &nodename, const std::string &topnodename)
0034   : Fun4AllInputManager(name, nodename, topnodename)
0035 {
0036   // initialize random generator
0037   const uint seed = PHRandomSeed();
0038   m_rng.reset(gsl_rng_alloc(gsl_rng_mt19937));
0039   gsl_rng_set(m_rng.get(), seed);
0040 }
0041 
0042 //_____________________________________________________________________________
0043 int Fun4AllSingleDstPileupInputManager::fileopen(const std::string &filenam)
0044 {
0045   /*
0046   this is largely copied from fun4all/Fun4AllDstInputManager::fileopen
0047   with additional code to handle the background IManager
0048   */
0049 
0050   auto se = Fun4AllServer::instance();
0051   if (IsOpen())
0052   {
0053     std::cout << "Closing currently open file "
0054               << FileName()
0055               << " and opening " << filenam << std::endl;
0056     fileclose();
0057   }
0058   FileName(filenam);
0059   FROG frog;
0060   m_fullfilename = frog.location(FileName());
0061   if (Verbosity() > 0)
0062   {
0063     std::cout << Name() << ": opening file " << m_fullfilename << std::endl;
0064   }
0065   // sanity check - the IManager must be nullptr when this method is executed
0066   // if not something is very very wrong and we must not continue
0067   assert(!m_IManager);
0068 
0069   // first read the runnode if not disabled
0070   if (m_ReadRunTTree)
0071   {
0072     m_IManager.reset(new PHNodeIOManager(m_fullfilename, PHReadOnly, PHRunTree));
0073     if (m_IManager->isFunctional())
0074     {
0075       m_runNode = se->getNode(m_RunNode, TopNodeName());
0076       m_IManager->read(m_runNode);
0077 
0078       // get the current run number
0079       auto runheader = findNode::getClass<RunHeader>(m_runNode, "RunHeader");
0080       if (runheader)
0081       {
0082         SetRunNumber(runheader->get_RunNumber());
0083       }
0084       // delete our internal copy of the runnode when opening subsequent files
0085       assert(!m_runNodeCopy);
0086       m_runNodeCopy.reset(new PHCompositeNode("RUNNODECOPY"));
0087       if (!m_runNodeSum)
0088       {
0089         m_runNodeSum.reset(new PHCompositeNode("RUNNODESUM"));
0090       }
0091 
0092       {
0093         // read run node using temporary node iomanager
0094         PHNodeIOManager(m_fullfilename, PHReadOnly, PHRunTree).read(m_runNodeCopy.get());
0095       }
0096 
0097       PHNodeIntegrate integrate;
0098       integrate.RunNode(m_runNode);
0099       integrate.RunSumNode(m_runNodeSum.get());
0100       // run recursively over internal run node copy and integrate objects
0101       PHNodeIterator mainIter(m_runNodeCopy.get());
0102       mainIter.forEach(integrate);
0103       // we do not need to keep the internal copy, keeping it would crate
0104       // problems in case a subsequent file does not contain all the
0105       // runwise objects from the previous file. Keeping this copy would then
0106       // integrate the missing object again with the old copy
0107       m_runNodeCopy.reset();
0108     }
0109     // DLW: move the delete outside the if block to cover the case where isFunctional() fails
0110     m_IManager.reset();
0111   }
0112 
0113   // create internal dst node
0114   if (!m_dstNodeInternal)
0115   {
0116     m_dstNodeInternal.reset(new PHCompositeNode("DST_INTERNAL"));
0117   }
0118 
0119   // update dst node from fun4all server
0120   m_dstNode = se->getNode(InputNode(), TopNodeName());
0121 
0122   // open file in both active and background input manager
0123   m_IManager.reset(new PHNodeIOManager(m_fullfilename, PHReadOnly));
0124   m_IManager_background.reset(new PHNodeIOManager(m_fullfilename, PHReadOnly));
0125   if (m_IManager->isFunctional())
0126   {
0127     IsOpen(1);
0128     m_ievent_thisfile = 0;
0129     setBranches();                // set branch selections
0130     AddToFileOpened(FileName());  // add file to the list of files which were opened
0131     return 0;
0132   }
0133   else
0134   {
0135     std::cout << PHWHERE << ": " << Name() << " Could not open file " << FileName() << std::endl;
0136     m_IManager.reset();
0137     m_IManager_background.reset();
0138     return -1;
0139   }
0140 }
0141 
0142 //_____________________________________________________________________________
0143 int Fun4AllSingleDstPileupInputManager::run(const int nevents)
0144 {
0145   if (!IsOpen())
0146   {
0147     if (FileListEmpty())
0148     {
0149       if (Verbosity() > 0)
0150       {
0151         std::cout << Name() << ": No Input file open" << std::endl;
0152       }
0153       return -1;
0154     }
0155     else
0156     {
0157       if (OpenNextFile())
0158       {
0159         std::cout << Name() << ": No Input file from filelist opened" << std::endl;
0160         return -1;
0161       }
0162     }
0163   }
0164 
0165   if (Verbosity() > 3)
0166   {
0167     std::cout << "Getting Event from " << Name() << std::endl;
0168   }
0169 
0170 readagain:
0171 
0172   // read main event to dstNode
0173   auto dummy = m_IManager->read(m_dstNode);
0174   int ncount = 0;
0175   while (dummy)
0176   {
0177     ++ncount;
0178     if (nevents > 0 && ncount >= nevents)
0179     {
0180       break;
0181     }
0182     dummy = m_IManager->read(m_dstNode);
0183   }
0184 
0185   if (!dummy)
0186   {
0187     fileclose();
0188     if (!OpenNextFile())
0189     {
0190       // NOLINTNEXTLINE(hicpp-avoid-goto)
0191       goto readagain;
0192     }
0193     else
0194     {
0195       return -1;
0196     }
0197   }
0198 
0199   m_ievent_total += ncount;
0200   m_ievent_thisfile += ncount;
0201 
0202   // check events consistency
0203   if (m_ievent_thisfile != static_cast<int>(m_IManager->getEventNumber()))
0204   {
0205     std::cout << PHWHERE
0206               << " inconsistent event counters between inputmanager and ionode manager: "
0207               << " m_ievent_thisfile: " << m_ievent_thisfile
0208               << " m_IManager->getEventNumber(): " << m_IManager->getEventNumber()
0209               << std::endl;
0210     gSystem->Exit(1);
0211   }
0212 
0213   // check if the local SubsysReco discards this event
0214   if (RejectEvent() != Fun4AllReturnCodes::EVENT_OK)
0215   {
0216     std::cout << "Fun4AllSingleDstPileupInputManager::run - skipped event " << m_ievent_thisfile - 1 << std::endl;
0217     // NOLINTNEXTLINE(hicpp-avoid-goto)
0218     goto readagain;
0219   }
0220 
0221   // load relevant DST nodes to internal pointers
0222   if (Verbosity() > 0)
0223   {
0224     std::cout << "Fun4AllSingleDstPileupInputManager::run - loaded event " << m_ievent_thisfile - 1 << std::endl;
0225   }
0226 
0227   Fun4AllDstPileupMerger merger;
0228   merger.load_nodes(m_dstNode);
0229 
0230   // generate background collisions
0231   const double mu = m_collision_rate * m_time_between_crossings * 1e-9;
0232 
0233   const int min_crossing = m_tmin / m_time_between_crossings;
0234   const int max_crossing = m_tmax / m_time_between_crossings;
0235   int ievent_thisfile = m_ievent_thisfile;
0236   int neventsbackground = 0;
0237   for (int icrossing = min_crossing; icrossing <= max_crossing; ++icrossing)
0238   {
0239     const double crossing_time = m_time_between_crossings * icrossing;
0240     const int ncollisions = gsl_ran_poisson(m_rng.get(), mu);
0241     for (int icollision = 0; icollision < ncollisions; ++icollision)
0242     {
0243       // try read
0244       if (!m_IManager_background->read(m_dstNodeInternal.get(), ievent_thisfile))
0245       {
0246         break;
0247       }
0248 
0249       // merge
0250 
0251       if (Verbosity() > 0)
0252       {
0253         std::cout << "Fun4AllSingleDstPileupInputManager::run - merged background event " << ievent_thisfile << " time: " << crossing_time << std::endl;
0254       }
0255       merger.copy_background_event(m_dstNodeInternal.get(), crossing_time);
0256 
0257       ++neventsbackground;
0258       ++ievent_thisfile;
0259     }
0260   }
0261 
0262   // jump event counter to the last background accepted event
0263   if (neventsbackground > 0)
0264   {
0265     PushBackEvents(-neventsbackground);
0266   }
0267   return 0;
0268 }
0269 
0270 //_____________________________________________________________________________
0271 int Fun4AllSingleDstPileupInputManager::fileclose()
0272 {
0273   if (!IsOpen())
0274   {
0275     std::cout << Name() << ": fileclose: No Input file open" << std::endl;
0276     return -1;
0277   }
0278   m_IManager.reset();
0279   m_IManager_background.reset();
0280   IsOpen(0);
0281   UpdateFileList();
0282   return 0;
0283 }
0284 
0285 //_____________________________________________________________________________
0286 int Fun4AllSingleDstPileupInputManager::BranchSelect(const std::string &branch, const int iflag)
0287 {
0288   int myflag = iflag;
0289   // if iflag > 0 the branch is set to read
0290   // if iflag = 0, the branch is set to NOT read
0291   // if iflag < 0 the branchname is erased from our internal branch read map
0292   // this does not have any effect on phool yet
0293   if (myflag < 0)
0294   {
0295     std::map<const std::string, int>::iterator branchiter;
0296     branchiter = m_branchread.find(branch);
0297     if (branchiter != m_branchread.end())
0298     {
0299       m_branchread.erase(branchiter);
0300     }
0301     return 0;
0302   }
0303 
0304   if (myflag > 0)
0305   {
0306     if (Verbosity() > 1)
0307     {
0308       std::cout << "Setting Root Tree Branch: " << branch << " to read" << std::endl;
0309     }
0310     myflag = 1;
0311   }
0312   else
0313   {
0314     if (Verbosity() > 1)
0315     {
0316       std::cout << "Setting Root Tree Branch: " << branch << " to NOT read" << std::endl;
0317     }
0318   }
0319   m_branchread[branch] = myflag;
0320   return 0;
0321 }
0322 
0323 //_____________________________________________________________________________
0324 int Fun4AllSingleDstPileupInputManager::setBranches()
0325 {
0326   if (m_IManager)
0327   {
0328     if (!m_branchread.empty())
0329     {
0330       std::map<const std::string, int>::const_iterator branchiter;
0331       for (branchiter = m_branchread.begin(); branchiter != m_branchread.end(); ++branchiter)
0332       {
0333         m_IManager->selectObjectToRead(branchiter->first.c_str(), branchiter->second);
0334         if (m_IManager_background)
0335         {
0336           m_IManager_background->selectObjectToRead(branchiter->first.c_str(), branchiter->second);
0337         }
0338         if (Verbosity() > 0)
0339         {
0340           std::cout << branchiter->first << " set to " << branchiter->second << std::endl;
0341         }
0342       }
0343     }
0344   }
0345   else
0346   {
0347     std::cout << PHWHERE << " " << Name() << ": You can only call this function after a file has been opened" << std::endl;
0348     std::cout << "Do not worry, the branches will be set as soon as you open a file" << std::endl;
0349     return -1;
0350   }
0351   return 0;
0352 }
0353 
0354 //_____________________________________________________________________________
0355 void Fun4AllSingleDstPileupInputManager::Print(const std::string &what) const
0356 {
0357   if (what == "ALL" || what == "BRANCH")
0358   {
0359     // loop over the map and print out the content (name and location in memory)
0360     std::cout << "--------------------------------------" << std::endl
0361               << std::endl;
0362     std::cout << "List of selected branches in Fun4AllSingleDstPileupInputManager " << Name() << ":" << std::endl;
0363 
0364     std::map<const std::string, int>::const_iterator iter;
0365     for (iter = m_branchread.begin(); iter != m_branchread.end(); ++iter)
0366     {
0367       std::cout << iter->first << " is switched ";
0368       if (iter->second)
0369       {
0370         std::cout << "ON";
0371       }
0372       else
0373       {
0374         std::cout << "OFF";
0375       }
0376       std::cout << std::endl;
0377     }
0378   }
0379   if ((what == "ALL" || what == "PHOOL") && m_IManager)
0380   {
0381     // loop over the map and print out the content (name and location in memory)
0382     std::cout << "--------------------------------------" << std::endl
0383               << std::endl;
0384     std::cout << "PHNodeIOManager print in Fun4AllSingleDstPileupInputManager " << Name() << ":" << std::endl;
0385     m_IManager->print();
0386   }
0387   Fun4AllInputManager::Print(what);
0388   return;
0389 }
0390 
0391 //_____________________________________________________________________________
0392 int Fun4AllSingleDstPileupInputManager::PushBackEvents(const int i)
0393 {
0394   if (m_IManager)
0395   {
0396     unsigned EventOnDst = m_IManager->getEventNumber();
0397     EventOnDst -= static_cast<unsigned>(i);
0398     m_ievent_thisfile -= i;
0399     m_ievent_total -= i;
0400     m_IManager->setEventNumber(EventOnDst);
0401     return 0;
0402   }
0403   std::cout << PHWHERE << Name() << ": could not push back events, Imanager is NULL"
0404             << " probably the dst is not open yet (you need to call fileopen or run 1 event for lists)" << std::endl;
0405   return -1;
0406 }