Back to home page

sPhenix code displayed by LXR

 
 

    


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

0001 #include "SingleZdcInput.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 SingleZdcInput::SingleZdcInput(const std::string &name, Fun4AllPrdfInputPoolManager *inman)
0017   : SinglePrdfInput(name, inman)
0018 {
0019   plist = new Packet *[100];
0020   m_PacketEventNumberOffset = new int[100]{};
0021   rollover.fill(0);
0022   previous_eventnumber.fill(std::numeric_limits<int>::min());
0023 }
0024 
0025 SingleZdcInput::~SingleZdcInput()
0026 {
0027   delete[] plist;
0028   delete[] m_PacketEventNumberOffset;
0029 }
0030 
0031 void SingleZdcInput::FillPool(const unsigned int nevents)
0032 {
0033   if (AllDone())  // no more files and all events read
0034   {
0035     return;
0036   }
0037   while (GetEventIterator() == nullptr)  // at startup this is a null pointer
0038   {
0039     if (!OpenNextFile())
0040     {
0041       AllDone(1);
0042       return;
0043     }
0044   }
0045   for (unsigned int ievt = 0; ievt < nevents; ievt++)
0046   {
0047     Event *evt = GetEventIterator()->getNextEvent();
0048     if (!evt)
0049     {
0050       fileclose();
0051       if (!OpenNextFile())
0052       {
0053         AllDone(1);
0054         return;
0055       }
0056       evt = GetEventIterator()->getNextEvent();
0057       if (!evt)
0058       {
0059         std::cout << PHWHERE << "Event is nullptr" << std::endl;
0060         AllDone(1);
0061         return;
0062       }
0063     }
0064 
0065     RunNumber(evt->getRunNumber());
0066     if (Verbosity() > 1)
0067     {
0068       evt->identify();
0069     }
0070     if (evt->getEvtType() != DATAEVENT)
0071     {
0072       m_NumSpecialEvents++;
0073       delete evt;
0074       continue;  // need handling for non data events
0075     }
0076 
0077     int EventSequence = evt->getEvtSequence();
0078     int npackets = evt->getPacketList(plist, 100);
0079     if (npackets == 100)
0080     {
0081       exit(1);
0082     }
0083     for (int i = 0; i < npackets; i++)
0084     {
0085       if (plist[i]->iValue(0, "CHECKSUMOK") != 0)
0086       {
0087         int evtno = plist[i]->iValue(0, "EVTNR") + rollover[i];
0088         if (evtno < previous_eventnumber[i])
0089         {
0090           if (Verbosity() > 1)
0091           {
0092             std::cout << "rolling over, event " << std::hex << evtno
0093                       << ", prev: " << previous_eventnumber[i]
0094                       << ", rollover counter: " << (rollover[i] << 16U)
0095                       << std::dec << std::endl;
0096           }
0097           rollover[i]++;
0098         }
0099         previous_eventnumber[i] = evtno;
0100         evtno += (rollover[i] << 16U);
0101         unsigned int bclk = plist[i]->lValue(0, "CLOCK");
0102 
0103         // NOLINTNEXTLINE(hicpp-signed-bitwise)
0104         bool useFEMInfo = ((plist[i]->getIdentifier() / 1000 == 12) && evtno != ((EventSequence - 2) & 0xffff));
0105 
0106         if (useFEMInfo == true)
0107         {
0108           // NOLINTNEXTLINE(hicpp-signed-bitwise)
0109           evtno = ((plist[i]->iValue(0, "FEMEVTNR") - 1) & 0xffff);  // hard coded since FEM event starts at 1 and packet event starts at 0
0110                                                                      // NOLINTNEXTLINE(hicpp-signed-bitwise)
0111           bclk = ((plist[i]->iValue(0, "FEMCLOCK") + 30) & 0xffff);  // hardcoded since level 1 delay for ZDC is 30 beam clocks.
0112         }
0113         if (Verbosity() > 1)
0114         {
0115           std::cout << "packet " << plist[i]->getIdentifier() << " evt: " << evtno
0116                     << std::hex << " clock: 0x" << bclk << std::dec << std::endl;
0117         }
0118         // dummy check for the first event which is the problem for the calorimeters
0119         // it is the last event from the previous run, so it's event number is > 0
0120         // if (evtno > EventSequence)
0121         // {
0122         //   delete plist[i];
0123         //   plist[i] = nullptr;
0124         //   continue;
0125         // }
0126         plist[i]->convert();
0127         // calculate "real" event number
0128         // special events are counted, so the packet event counter is never the
0129         // Event Sequence (bc the begin run event)
0130         // also our packets are just 16bit counters, so we need to add the upper bits
0131         // from the event sequence
0132         // and our packet counters start at 0, while our events start at 1
0133         evtno += EventNumberOffset() + m_PacketEventNumberOffset[i] + m_NumSpecialEvents;
0134         m_PacketMap[bclk].push_back(plist[i]);
0135         m_EvtSet.insert(evtno);
0136         m_Event.emplace_back(std::make_pair(evtno, bclk));
0137       }
0138       else
0139       {
0140         delete plist[i];
0141       }
0142     }
0143     // here we have all packets of a given event in our maps/vectors
0144     // first pass - check if beam clocks are identical
0145     if (Verbosity() > 1)
0146     {
0147       std::cout << "pktmap size : " << m_PacketMap.size() << std::endl;
0148       std::cout << "evt set size : " << m_EvtSet.size() << std::endl;
0149     }
0150     int common_event_number = *(m_EvtSet.begin());
0151     int common_beam_clock = m_PacketMap.begin()->first;
0152     if (m_PacketMap.size() == 1)  // all packets from the same beam clock
0153     {
0154       if (m_EvtSet.size() == 1)
0155       {
0156         if (Verbosity() > 1)
0157         {
0158           std::cout << "we are good evtno: " << *(m_EvtSet.begin())
0159                     << ", clock: " << m_PacketMap.begin()->first << std::endl;
0160         }
0161       }
0162       else
0163       {
0164         if (Verbosity() > 1)
0165         {
0166           std::cout << "We have multiple event numbers for bclk: 0x" << std::hex
0167                     << m_PacketMap.begin()->first << std::dec << std::endl;
0168           for (auto iter : m_EvtSet)
0169           {
0170             std::cout << "Event " << iter << std::endl;
0171           }
0172         }
0173         common_event_number = majority_eventnumber();
0174         if (Verbosity() > 1)
0175         {
0176           std::cout << "picked event no " << common_event_number << std::endl;
0177         }
0178         adjust_eventnumber_offset(common_event_number);
0179       }
0180       for (auto const &iter : m_PacketMap)
0181       {
0182         for (auto const &pktiter : iter.second)
0183         {
0184           if (InputMgr())
0185           {
0186             InputMgr()->AddPacket(common_event_number, pktiter);
0187           }
0188         }
0189       }
0190     }
0191     else
0192     {
0193       if (Verbosity() > 1)
0194       {
0195         std::cout << "We have multiple beam clocks per event" << std::endl;
0196       }
0197       if (m_EvtSet.size() == 1)
0198       {
0199         if (Verbosity() > 1)
0200         {
0201           std::cout << "we are good evtno: " << *(m_EvtSet.begin())
0202                     << ", clock: " << m_PacketMap.begin()->first << std::endl;
0203         }
0204       }
0205       else
0206       {
0207         if (Verbosity() > 1)
0208         {
0209           std::cout << "We have multiple event numbers for bclk: 0x" << std::hex
0210                     << m_PacketMap.begin()->first << std::dec << std::endl;
0211           for (auto iter : m_EvtSet)
0212           {
0213             std::cout << "Event " << iter << std::endl;
0214           }
0215         }
0216         common_event_number = majority_eventnumber();
0217         if (Verbosity() > 1)
0218         {
0219           std::cout << "picked event no " << common_event_number << std::endl;
0220         }
0221         adjust_eventnumber_offset(common_event_number);
0222       }
0223       common_beam_clock = majority_beamclock();
0224       if (Verbosity() > 1)
0225       {
0226         std::cout << "picked bclk: " << std::hex << common_beam_clock << std::dec << std::endl;
0227       }
0228       // for time being clean out packets which do not match
0229       for (auto const &iter : m_PacketMap)
0230       {
0231         for (auto pktiter : iter.second)
0232         {
0233           if (pktiter->lValue(0, "CLOCK") == common_beam_clock)
0234           {
0235             if (Verbosity() > 1)
0236             {
0237               std::cout << "adding packet " << pktiter->getIdentifier() << " beam clock "
0238                         << std::hex << pktiter->lValue(0, "CLOCK") << std::dec << std::endl;
0239             }
0240             if (InputMgr())
0241             {
0242               InputMgr()->AddPacket(common_event_number, pktiter);
0243             }
0244           }
0245           else
0246           {
0247             if (Verbosity() > 1)
0248             {
0249               std::cout << "Deleting packet " << pktiter->getIdentifier() << " beam clock "
0250                         << std::hex << pktiter->lValue(0, "CLOCK") << " common bclk: "
0251                         << common_beam_clock << std::dec << std::endl;
0252             }
0253             if (InputMgr())
0254             {
0255               InputMgr()->UpdateDroppedPacket(pktiter->getIdentifier());
0256             }
0257             delete pktiter;
0258           }
0259         }
0260       }
0261     }
0262     if (InputMgr())
0263     {
0264       InputMgr()->AddBeamClock(common_event_number, common_beam_clock, this);
0265     }
0266     if (ReferenceFlag())
0267     {
0268       if (InputMgr())
0269       {
0270         InputMgr()->SetReferenceClock(common_event_number, common_beam_clock);
0271       }
0272     }
0273     m_PacketMap.clear();
0274     m_EvtSet.clear();
0275     m_Event.clear();
0276     delete evt;
0277   }
0278 }
0279 
0280 void SingleZdcInput::adjust_eventnumber_offset(const int decided_evtno)
0281 {
0282   for (unsigned int i = 0; i < m_Event.size(); i++)
0283   {
0284     if (m_Event[i].first != decided_evtno)
0285     {
0286       m_PacketEventNumberOffset[i] -= (m_Event[i].first - decided_evtno);
0287       if (Verbosity() > 1)
0288       {
0289         std::cout << "my evtno: " << m_Event[i].first << ", decided: " << decided_evtno
0290                   << ", adjustment: " << m_Event[i].first - decided_evtno << std::endl;
0291         std::cout << "adjusting event number offset for " << i << " to " << m_PacketEventNumberOffset[i] << std::endl;
0292       }
0293     }
0294   }
0295 }
0296 
0297 int SingleZdcInput::majority_eventnumber()
0298 {
0299   std::map<int, int> evtcnt;
0300   for (auto iter : m_Event)
0301   {
0302     evtcnt[iter.first]++;
0303   }
0304   int imax = -1;
0305   int evtno = -1;
0306   for (auto iter : evtcnt)
0307   {
0308     if (iter.second > imax)
0309     {
0310       evtno = iter.first;
0311       imax = iter.second;
0312     }
0313   }
0314   return evtno;
0315 }
0316 
0317 int SingleZdcInput::majority_beamclock()
0318 {
0319   std::map<int, int> evtcnt;
0320   for (auto iter : m_Event)
0321   {
0322     evtcnt[iter.second]++;
0323     if (Verbosity() > 1)
0324     {
0325       std::cout << "adding clk: " << std::hex << iter.second << std::dec
0326                 << " current counter: " << evtcnt[iter.second] << std::endl;
0327     }
0328   }
0329   int imax = -1;
0330   int bclk = std::numeric_limits<int>::max();
0331   for (auto iter : evtcnt)
0332   {
0333     if (iter.second > imax)
0334     {
0335       bclk = iter.first;
0336       imax = iter.second;
0337     }
0338   }
0339   return bclk;
0340 }