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())
0034 {
0035 return;
0036 }
0037 while (GetEventIterator() == nullptr)
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;
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
0104 bool useFEMInfo = ((plist[i]->getIdentifier() / 1000 == 12) && evtno != ((EventSequence - 2) & 0xffff));
0105
0106 if (useFEMInfo == true)
0107 {
0108
0109 evtno = ((plist[i]->iValue(0, "FEMEVTNR") - 1) & 0xffff);
0110
0111 bclk = ((plist[i]->iValue(0, "FEMCLOCK") + 30) & 0xffff);
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
0119
0120
0121
0122
0123
0124
0125
0126 plist[i]->convert();
0127
0128
0129
0130
0131
0132
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
0144
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)
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
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 }