Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:21:56

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