Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-05 08:16:16

0001 #include "SinglePrdfInput.h"
0002 
0003 #include "Fun4AllPrdfInputPoolManager.h"
0004 
0005 #include <frog/FROG.h>
0006 
0007 #include <phool/phool.h>
0008 
0009 #include <Event/Event.h>
0010 #include <Event/EventTypes.h>
0011 #include <Event/Eventiterator.h>
0012 #include <Event/fileEventiterator.h>
0013 
0014 #include <limits>
0015 
0016 SinglePrdfInput::SinglePrdfInput(const std::string &name, Fun4AllPrdfInputPoolManager *inman)
0017   : Fun4AllBase(name)
0018   , m_InputMgr(inman)
0019 {
0020   plist = new Packet *[100];
0021   m_PacketEventNumberOffset = new int[100]{};
0022   rollover.fill(0);
0023   previous_eventnumber.fill(std::numeric_limits<int>::min());
0024   //  std::fill_n(m_PacketEventNumberOffset, 100, 0);
0025 }
0026 
0027 SinglePrdfInput::~SinglePrdfInput()
0028 {
0029   delete m_EventIterator;
0030   delete[] plist;
0031   delete[] m_PacketEventNumberOffset;
0032 }
0033 
0034 void SinglePrdfInput::FillPool(const unsigned int nevents)
0035 {
0036   if (AllDone())  // no more files and all events read
0037   {
0038     return;
0039   }
0040   while (m_EventIterator == nullptr)  // at startup this is a null pointer
0041   {
0042     if (!OpenNextFile())
0043     {
0044       AllDone(1);
0045       return;
0046     }
0047   }
0048   for (unsigned int ievt = 0; ievt < nevents; ievt++)
0049   {
0050     Event *evt = m_EventIterator->getNextEvent();
0051     if (!evt)
0052     {
0053       fileclose();
0054       if (!OpenNextFile())
0055       {
0056         AllDone(1);
0057         return;
0058       }
0059       evt = m_EventIterator->getNextEvent();
0060       if (!evt)
0061       {
0062         std::cout << PHWHERE << "Event is nullptr" << std::endl;
0063         AllDone(1);
0064         return;
0065       }
0066     }
0067     m_RunNumber = evt->getRunNumber();
0068     if (Verbosity() > 1)
0069     {
0070       evt->identify();
0071     }
0072     if (evt->getEvtType() != DATAEVENT)
0073     {
0074       m_NumSpecialEvents++;
0075       delete evt;
0076       continue;  // need handling for non data events
0077     }
0078     //    int EventSequence = evt->getEvtSequence();
0079     int npackets = evt->getPacketList(plist, 100);
0080     if (npackets == 100)
0081     {
0082       exit(1);
0083     }
0084     for (int i = 0; i < npackets; i++)
0085     {
0086       if (plist[i]->iValue(0, "CHECKSUMOK") != 0)
0087       {
0088         int evtno = plist[i]->iValue(0, "EVTNR") + rollover[i];
0089         if (evtno < previous_eventnumber[i])
0090         {
0091           if (Verbosity() > 1)
0092           {
0093             std::cout << "rolling over, event " << std::hex << evtno
0094                       << ", prev: " << previous_eventnumber[i]
0095                       << ", rollover counter: " << (rollover[i] << 16U)
0096                       << std::dec << std::endl;
0097           }
0098           rollover[i]++;
0099         }
0100         previous_eventnumber[i] = evtno;
0101         evtno += (rollover[i] << 16U);
0102         unsigned int bclk = plist[i]->lValue(0, "CLOCK");
0103         if (Verbosity() > 1)
0104         {
0105           std::cout << "packet " << plist[i]->getIdentifier() << " evt: " << evtno
0106                     << std::hex << " clock: 0x" << bclk << std::dec << std::endl;
0107         }
0108         // dummy check for the first event which is the problem for the calorimeters
0109         // it is the last event from the previous run, so it's event number is > 0
0110         // if (evtno > EventSequence)
0111         // {
0112         //   delete plist[i];
0113         //   plist[i] = nullptr;
0114         //   continue;
0115         // }
0116         plist[i]->convert();
0117         // calculate "real" event number
0118         // special events are counted, so the packet event counter is never the
0119         // Event Sequence (bc the begin run event)
0120         // also our packets are just 16bit counters, so we need to add the upper bits
0121         // from the event sequence
0122         // and our packet counters start at 0, while our events start at 1
0123         evtno += m_EventNumberOffset + m_PacketEventNumberOffset[i] + m_NumSpecialEvents;
0124         m_PacketMap[bclk].push_back(plist[i]);
0125         m_EvtSet.insert(evtno);
0126         m_Event.emplace_back(std::make_pair(evtno, bclk));
0127       }
0128       else
0129       {
0130         delete plist[i];
0131       }
0132     }
0133     // here we have all packets of a given event in our maps/vectors
0134     // first pass - check if beam clocks are identical
0135     if (Verbosity() > 1)
0136     {
0137       std::cout << "pktmap size : " << m_PacketMap.size() << std::endl;
0138       std::cout << "evt set size : " << m_EvtSet.size() << std::endl;
0139     }
0140     int common_event_number = *(m_EvtSet.begin());
0141     int common_beam_clock = m_PacketMap.begin()->first;
0142     if (m_PacketMap.size() == 1)  // all packets from the same beam clock
0143     {
0144       if (m_EvtSet.size() == 1)
0145       {
0146         if (Verbosity() > 1)
0147         {
0148           std::cout << "we are good evtno: " << *(m_EvtSet.begin())
0149                     << ", clock: " << m_PacketMap.begin()->first << std::endl;
0150         }
0151       }
0152       else
0153       {
0154         if (Verbosity() > 1)
0155         {
0156           std::cout << "We have multiple event numbers for bclk: 0x" << std::hex
0157                     << m_PacketMap.begin()->first << std::dec << std::endl;
0158           for (auto iter : m_EvtSet)
0159           {
0160             std::cout << "Event " << iter << std::endl;
0161           }
0162         }
0163         common_event_number = majority_eventnumber();
0164         if (Verbosity() > 1)
0165         {
0166           std::cout << "picked event no " << common_event_number << std::endl;
0167         }
0168         adjust_eventnumber_offset(common_event_number);
0169       }
0170       for (auto const &iter : m_PacketMap)
0171       {
0172         for (auto const &pktiter : iter.second)
0173         {
0174           if (m_InputMgr)
0175           {
0176             m_InputMgr->AddPacket(common_event_number, pktiter);
0177           }
0178         }
0179       }
0180     }
0181     else
0182     {
0183       if (Verbosity() > 1)
0184       {
0185         std::cout << "We have multiple beam clocks per event" << std::endl;
0186       }
0187       if (m_EvtSet.size() == 1)
0188       {
0189         if (Verbosity() > 1)
0190         {
0191           std::cout << "we are good evtno: " << *(m_EvtSet.begin())
0192                     << ", clock: " << m_PacketMap.begin()->first << std::endl;
0193         }
0194       }
0195       else
0196       {
0197         if (Verbosity() > 1)
0198         {
0199           std::cout << "We have multiple event numbers for bclk: 0x" << std::hex
0200                     << m_PacketMap.begin()->first << std::dec << std::endl;
0201           for (auto iter : m_EvtSet)
0202           {
0203             std::cout << "Event " << iter << std::endl;
0204           }
0205         }
0206         common_event_number = majority_eventnumber();
0207         if (Verbosity() > 1)
0208         {
0209           std::cout << "picked event no " << common_event_number << std::endl;
0210         }
0211         adjust_eventnumber_offset(common_event_number);
0212       }
0213       common_beam_clock = majority_beamclock();
0214       if (Verbosity() > 1)
0215       {
0216         std::cout << "picked bclk: " << std::hex << common_beam_clock << std::dec << std::endl;
0217       }
0218       // for time being clean out packets which do not match
0219       for (auto const &iter : m_PacketMap)
0220       {
0221         for (auto pktiter : iter.second)
0222         {
0223           if (pktiter->lValue(0, "CLOCK") == common_beam_clock)
0224           {
0225             if (Verbosity() > 1)
0226             {
0227               std::cout << "adding packet " << pktiter->getIdentifier() << " beam clock "
0228                         << std::hex << pktiter->lValue(0, "CLOCK") << std::dec << std::endl;
0229             }
0230             if (m_InputMgr)
0231             {
0232               m_InputMgr->AddPacket(common_event_number, pktiter);
0233             }
0234           }
0235           else
0236           {
0237             if (Verbosity() > 1)
0238             {
0239               std::cout << "Deleting packet " << pktiter->getIdentifier() << " beam clock "
0240                         << std::hex << pktiter->lValue(0, "CLOCK") << " common bclk: "
0241                         << common_beam_clock << std::dec << std::endl;
0242             }
0243             if (m_InputMgr)
0244             {
0245               m_InputMgr->UpdateDroppedPacket(pktiter->getIdentifier());
0246             }
0247             delete pktiter;
0248           }
0249         }
0250       }
0251     }
0252     if (m_InputMgr)
0253     {
0254       m_InputMgr->AddBeamClock(common_event_number, common_beam_clock, this);
0255     }
0256 
0257     if (m_MeReferenceFlag)
0258     {
0259       if (m_InputMgr)
0260       {
0261         m_InputMgr->SetReferenceClock(common_event_number, common_beam_clock);
0262       }
0263     }
0264     m_PacketMap.clear();
0265     m_EvtSet.clear();
0266     m_Event.clear();
0267     delete evt;
0268   }
0269 }
0270 
0271 void SinglePrdfInput::adjust_eventnumber_offset(const int decided_evtno)
0272 {
0273   for (unsigned int i = 0; i < m_Event.size(); i++)
0274   {
0275     if (m_Event[i].first != decided_evtno)
0276     {
0277       m_PacketEventNumberOffset[i] -= (m_Event[i].first - decided_evtno);
0278       if (Verbosity() > 1)
0279       {
0280         std::cout << "my evtno: " << m_Event[i].first << ", decided: " << decided_evtno
0281                   << ", adjustment: " << m_Event[i].first - decided_evtno << std::endl;
0282         std::cout << "adjusting event number offset for " << i << " to " << m_PacketEventNumberOffset[i] << std::endl;
0283       }
0284     }
0285   }
0286 }
0287 
0288 int SinglePrdfInput::majority_eventnumber()
0289 {
0290   std::map<int, int> evtcnt;
0291   for (auto iter : m_Event)
0292   {
0293     evtcnt[iter.first]++;
0294   }
0295   int imax = -1;
0296   int evtno = -1;
0297   for (auto iter : evtcnt)
0298   {
0299     if (iter.second > imax)
0300     {
0301       evtno = iter.first;
0302       imax = iter.second;
0303     }
0304   }
0305   return evtno;
0306 }
0307 
0308 int SinglePrdfInput::majority_beamclock()
0309 {
0310   std::map<int, int> evtcnt;
0311   for (auto iter : m_Event)
0312   {
0313     evtcnt[iter.second]++;
0314     if (Verbosity() > 1)
0315     {
0316       std::cout << "adding clk: " << std::hex << iter.second << std::dec
0317                 << " current counter: " << evtcnt[iter.second] << std::endl;
0318     }
0319   }
0320   int imax = -1;
0321   int bclk = std::numeric_limits<int>::max();
0322   for (auto iter : evtcnt)
0323   {
0324     if (iter.second > imax)
0325     {
0326       bclk = iter.first;
0327       imax = iter.second;
0328     }
0329   }
0330   return bclk;
0331 }
0332 
0333 int SinglePrdfInput::fileopen(const std::string &filenam)
0334 {
0335   std::cout << PHWHERE << Name() << ": trying to open " << filenam << std::endl;
0336   if (IsOpen())
0337   {
0338     std::cout << "Closing currently open file "
0339               << FileName()
0340               << " and opening " << filenam << std::endl;
0341     fileclose();
0342   }
0343   FileName(filenam);
0344   FROG frog;
0345   std::string fname = frog.location(FileName());
0346   if (Verbosity() > 0)
0347   {
0348     std::cout << Name() << ": opening file " << FileName() << std::endl;
0349   }
0350   int status = 0;
0351   m_EventIterator = new fileEventiterator(fname.c_str(), status);
0352   m_EventsThisFile = 0;
0353   if (status)
0354   {
0355     delete m_EventIterator;
0356     m_EventIterator = nullptr;
0357     std::cout << PHWHERE << Name() << ": could not open file " << fname << std::endl;
0358     return -1;
0359   }
0360   IsOpen(1);
0361   AddToFileOpened(fname);  // add file to the list of files which were opened
0362   return 0;
0363 }
0364 
0365 int SinglePrdfInput::fileclose()
0366 {
0367   if (!IsOpen())
0368   {
0369     std::cout << Name() << ": fileclose: No Input file open" << std::endl;
0370     return -1;
0371   }
0372   delete m_EventIterator;
0373   m_EventIterator = nullptr;
0374   IsOpen(0);
0375   // if we have a file list, move next entry to top of the list
0376   // or repeat the same entry again
0377   UpdateFileList();
0378   return 0;
0379 }
0380 
0381 void SinglePrdfInput::MakeReference(const bool b)
0382 {
0383   m_MeReferenceFlag = b;
0384   if (b)
0385   {
0386     if (m_InputMgr)
0387     {
0388       m_InputMgr->SetReferenceInputMgr(this);
0389     }
0390   }
0391   return;
0392 }