File indexing completed on 2025-12-17 09:19:47
0001 #include "SingleInttEventInput.h"
0002 #include "intt_pool.h"
0003
0004 #include "Fun4AllStreamingInputManager.h"
0005 #include "InputManagerType.h"
0006
0007 #include <ffarawobjects/InttRawHitContainerv2.h>
0008 #include <ffarawobjects/InttRawHitv2.h>
0009
0010 #include <phool/PHCompositeNode.h>
0011 #include <phool/PHIODataNode.h> // for PHIODataNode
0012 #include <phool/PHNodeIterator.h> // for PHNodeIterator
0013 #include <phool/getClass.h>
0014
0015 #include <Event/Event.h>
0016 #include <Event/EventTypes.h>
0017 #include <Event/Eventiterator.h>
0018
0019 #include <algorithm> // for max
0020 #include <cstdint> // for uint64_t
0021 #include <cstdlib> // for exit
0022 #include <iostream> // for operator<<, basic_o...
0023 #include <set>
0024 #include <utility> // for pair
0025
0026 SingleInttEventInput::SingleInttEventInput(const std::string &name)
0027 : SingleStreamingInput(name)
0028 , plist(new Packet *[1])
0029 {
0030 SubsystemEnum(InputManagerType::INTT);
0031
0032 m_rawHitContainerName = "INTTRAWHIT";
0033 }
0034
0035 SingleInttEventInput::~SingleInttEventInput()
0036 {
0037 delete[] plist;
0038 for (auto iter : poolmap)
0039 {
0040 if (Verbosity() > 2)
0041 {
0042 std::cout << "deleting intt pool for id " << (iter.second)->getIdentifier() << std::endl;
0043 }
0044 delete (iter.second);
0045 }
0046 }
0047
0048 void SingleInttEventInput::FillPool(const uint64_t minBCO)
0049 {
0050 if (AllDone())
0051 {
0052 return;
0053 }
0054 while (GetEventiterator() == nullptr)
0055 {
0056 if (!OpenNextFile())
0057 {
0058 AllDone(1);
0059 return;
0060 }
0061 }
0062
0063
0064 while (GetSomeMoreEvents(0))
0065 {
0066 Event *evt = GetEventiterator()->getNextEvent();
0067 while (!evt)
0068 {
0069 fileclose();
0070 if (!OpenNextFile())
0071 {
0072 AllDone(1);
0073 return;
0074 }
0075 evt = GetEventiterator()->getNextEvent();
0076 }
0077 if (Verbosity() > 2)
0078 {
0079 std::cout << "Fetching next Event" << evt->getEvtSequence() << std::endl;
0080 }
0081 RunNumber(evt->getRunNumber());
0082 if (GetVerbosity() > 1)
0083 {
0084 evt->identify();
0085 }
0086
0087 if (evt->getEvtType() != DATAEVENT)
0088 {
0089 m_NumSpecialEvents++;
0090 if (evt->getEvtType() == ENDRUNEVENT)
0091 {
0092 std::cout << "End run flag for INTT found, remaining INTT data is corrupted" << std::endl;
0093 delete evt;
0094 AllDone(1);
0095 return;
0096 }
0097 delete evt;
0098 continue;
0099 }
0100
0101 int EventSequence = evt->getEvtSequence();
0102 int npackets = evt->getPacketList(plist, 1);
0103
0104 if (npackets > 1)
0105 {
0106 exit(1);
0107 }
0108
0109 for (int i = 0; i < npackets; i++)
0110 {
0111 int packet_id = plist[i]->getIdentifier();
0112 int num_hits = plist[i]->iValue(0, "NR_HITS");
0113 if (Verbosity() > 1)
0114 {
0115 std::cout << "Number of Hits: " << num_hits << " for packet "
0116 << plist[i]->getIdentifier() << std::endl;
0117 }
0118
0119 int numBCOs = plist[i]->iValue(0, "NR_BCOS");
0120 bool skipthis = true;
0121 uint64_t largest_bco = 0;
0122 for (int j = 0; j < numBCOs; j++)
0123 {
0124 uint64_t bco = plist[i]->lValue(j, "BCOLIST");
0125 largest_bco = std::max(largest_bco, bco);
0126 if (bco < minBCO)
0127 {
0128 continue;
0129 }
0130 skipthis = false;
0131 m_BclkStack.insert(bco);
0132 m_BclkStackPacketMap[packet_id].insert(bco);
0133 }
0134 if (skipthis)
0135 {
0136 if (Verbosity() > 1)
0137 {
0138 std::cout << "largest bco: 0x" << std::hex << largest_bco << ", minbco 0x" << minBCO
0139 << std::dec << ", evtno: " << EventSequence << std::endl;
0140 }
0141 }
0142 else
0143 {
0144 if (bfirst)
0145 {
0146 std::cout << Name() << ": Found first event with bco > minbco, " << std::endl;
0147 std::cout << "rcdaq Event " << EventSequence << ", largest bco: 0x"
0148 << std::hex << largest_bco << ", minimum requested bco: 0x"
0149 << minBCO << std::dec << std::endl;
0150 bfirst = false;
0151 }
0152 for (int j = 0; j < num_hits; j++)
0153 {
0154 uint64_t gtm_bco = plist[i]->lValue(j, "BCO");
0155 if (gtm_bco < minBCO)
0156 {
0157
0158
0159
0160 continue;
0161 }
0162 InttRawHit *newhit = new InttRawHitv2();
0163 int FEE = plist[i]->iValue(j, "FEE");
0164 newhit->set_packetid(plist[i]->getIdentifier());
0165 newhit->set_fee(FEE);
0166 newhit->set_bco(gtm_bco);
0167 newhit->set_adc(plist[i]->iValue(j, "ADC"));
0168 newhit->set_amplitude(plist[i]->iValue(j, "AMPLITUDE"));
0169 newhit->set_chip_id(plist[i]->iValue(j, "CHIP_ID"));
0170 newhit->set_channel_id(plist[i]->iValue(j, "CHANNEL_ID"));
0171 newhit->set_word(plist[i]->iValue(j, "DATAWORD"));
0172 newhit->set_FPHX_BCO(plist[i]->iValue(j, "FPHX_BCO"));
0173 newhit->set_full_FPHX(plist[i]->iValue(j, "FULL_FPHX"));
0174 newhit->set_full_ROC(plist[i]->iValue(j, "FULL_ROC"));
0175 newhit->set_event_counter(plist[i]->iValue(j, "EVENT_COUNTER"));
0176
0177 gtm_bco += m_Rollover[FEE];
0178
0179 if (gtm_bco < m_PreviousClock[FEE])
0180 {
0181 m_Rollover[FEE] += 0x10000000000;
0182 gtm_bco += 0x10000000000;
0183 }
0184 m_PreviousClock[FEE] = gtm_bco;
0185 m_BeamClockFEE[gtm_bco].insert(FEE);
0186 m_FEEBclkMap[FEE] = gtm_bco;
0187 if (Verbosity() > 2)
0188 {
0189 std::cout << "evtno: " << EventSequence
0190 << ", hits: " << j
0191 << ", nr_hits: " << num_hits
0192 << ", FEE: " << FEE
0193 << ", bco: 0x" << std::hex << gtm_bco << std::dec
0194 << ", min bco: 0x" << std::hex << minBCO << std::dec
0195 << ", channel: " << newhit->get_channel_id()
0196 << ", evt_counter: " << newhit->get_event_counter() << std::endl;
0197 }
0198 if (StreamingInputManager())
0199 {
0200 StreamingInputManager()->AddInttRawHit(gtm_bco, newhit);
0201 }
0202 m_InttRawHitMap[gtm_bco].push_back(newhit);
0203 }
0204 }
0205 delete plist[i];
0206
0207 }
0208 delete evt;
0209 }
0210 }
0211
0212 void SingleInttEventInput::Print(const std::string &what) const
0213 {
0214 if (what == "ALL" || what == "FEE")
0215 {
0216 for (const auto &bcliter : m_BeamClockFEE)
0217 {
0218 std::cout << "Beam clock 0x" << std::hex << bcliter.first << std::dec << std::endl;
0219 for (auto feeiter : bcliter.second)
0220 {
0221 std::cout << "FEM: " << feeiter << std::endl;
0222 }
0223 }
0224 }
0225 if (what == "ALL" || what == "FEEBCLK")
0226 {
0227 std::cout << "Printing last beamclock for every FEE" << std::endl;
0228 for (auto bcliter : m_FEEBclkMap)
0229 {
0230 std::cout << "FEE" << bcliter.first << " bclk: 0x"
0231 << std::hex << bcliter.second << std::dec << std::endl;
0232 }
0233 }
0234 if (what == "ALL" || what == "STORAGE")
0235 {
0236 for (const auto &bcliter : m_InttRawHitMap)
0237 {
0238 std::cout << "Beam clock 0x" << std::hex << bcliter.first << std::dec << std::endl;
0239 for (auto *feeiter : bcliter.second)
0240 {
0241 std::cout << "fee: " << feeiter->get_fee()
0242 << " at " << std::hex << feeiter << std::dec << std::endl;
0243 }
0244 }
0245 }
0246 if (what == "ALL" || what == "STACK")
0247 {
0248 for (const auto &[packetid, bclkstack] : m_BclkStackPacketMap)
0249 {
0250 for (const auto &bclk : bclkstack)
0251 {
0252 std::cout << "stacked bclk: 0x" << std::hex << bclk << std::dec << std::endl;
0253 }
0254 }
0255 for (auto iter : m_BclkStack)
0256 {
0257 std::cout << "stacked bclk: 0x" << std::hex << iter << std::dec << std::endl;
0258 }
0259 }
0260 }
0261
0262 void SingleInttEventInput::CleanupUsedPackets(const uint64_t bclk)
0263 {
0264 std::vector<uint64_t> toclearbclk;
0265 for (const auto &iter : m_InttRawHitMap)
0266 {
0267 if (iter.first <= bclk)
0268 {
0269 for (auto *pktiter : iter.second)
0270 {
0271 delete pktiter;
0272 }
0273 toclearbclk.push_back(iter.first);
0274 }
0275 else
0276 {
0277 break;
0278 }
0279 }
0280 for (auto iter : toclearbclk)
0281 {
0282 m_BclkStack.erase(iter);
0283 for (auto &[packetid, bclkstack] : m_BclkStackPacketMap)
0284 {
0285 bclkstack.erase(iter);
0286 }
0287 m_BeamClockFEE.erase(iter);
0288 m_InttRawHitMap.erase(iter);
0289 }
0290 }
0291
0292 bool SingleInttEventInput::CheckPoolDepth(const uint64_t bclk)
0293 {
0294 for (auto iter : m_FEEBclkMap)
0295 {
0296 if (Verbosity() > 2)
0297 {
0298 std::cout << "my bclk 0x" << std::hex << iter.second
0299 << " req: 0x" << bclk << std::dec << std::endl;
0300 }
0301 if (iter.second < bclk)
0302 {
0303 if (Verbosity() > 1)
0304 {
0305 std::cout << "FEE " << iter.first << " beamclock 0x" << std::hex << iter.second
0306 << " smaller than req bclk: 0x" << bclk << std::dec << std::endl;
0307 }
0308 return false;
0309 }
0310 }
0311 return true;
0312 }
0313
0314 void SingleInttEventInput::ClearCurrentEvent()
0315 {
0316
0317 uint64_t currentbclk = *(m_BclkStackPacketMap.begin()->second).begin();
0318
0319 CleanupUsedPackets(currentbclk);
0320
0321
0322 return;
0323 }
0324
0325 bool SingleInttEventInput::GetSomeMoreEvents(const uint64_t ibclk)
0326 {
0327 if (AllDone())
0328 {
0329 return false;
0330 }
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344 uint64_t localbclk = ibclk;
0345 if (ibclk == 0)
0346 {
0347 if (m_InttRawHitMap.empty())
0348 {
0349
0350 return true;
0351 }
0352 localbclk = m_InttRawHitMap.begin()->first;
0353 }
0354
0355 std::set<int> toerase;
0356 for (auto bcliter : m_FEEBclkMap)
0357 {
0358 if (bcliter.second <= localbclk)
0359 {
0360 uint64_t highest_bclk = m_InttRawHitMap.rbegin()->first;
0361 if ((highest_bclk - m_InttRawHitMap.begin()->first) < MaxBclkDiff())
0362 {
0363
0364
0365
0366 return true;
0367 }
0368
0369 std::cout << PHWHERE << Name() << ": erasing FEE " << bcliter.first
0370 << " with stuck bclk: " << std::hex << bcliter.second
0371 << " current bco range: 0x" << m_InttRawHitMap.begin()->first
0372 << ", to: 0x" << highest_bclk << ", delta: " << std::dec
0373 << (highest_bclk - m_InttRawHitMap.begin()->first)
0374 << std::dec << std::endl;
0375 toerase.insert(bcliter.first);
0376 }
0377 }
0378 for (auto iter : toerase)
0379 {
0380 m_FEEBclkMap.erase(iter);
0381 }
0382
0383 return false;
0384 }
0385
0386 void SingleInttEventInput::CreateDSTNode(PHCompositeNode *topNode)
0387 {
0388 PHNodeIterator iter(topNode);
0389 PHCompositeNode *dstNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "DST"));
0390 if (!dstNode)
0391 {
0392 dstNode = new PHCompositeNode("DST");
0393 topNode->addNode(dstNode);
0394 }
0395 PHNodeIterator iterDst(dstNode);
0396 PHCompositeNode *detNode = dynamic_cast<PHCompositeNode *>(iterDst.findFirst("PHCompositeNode", "INTT"));
0397 if (!detNode)
0398 {
0399 detNode = new PHCompositeNode("INTT");
0400 dstNode->addNode(detNode);
0401 }
0402 InttRawHitContainer *intthitcont = findNode::getClass<InttRawHitContainer>(detNode, m_rawHitContainerName);
0403 if (!intthitcont)
0404 {
0405 intthitcont = new InttRawHitContainerv2();
0406 PHIODataNode<PHObject> *newNode = new PHIODataNode<PHObject>(intthitcont, m_rawHitContainerName, "PHObject");
0407 detNode->addNode(newNode);
0408 }
0409 }
0410
0411
0412 void SingleInttEventInput::ConfigureStreamingInputManager()
0413 {
0414 if (StreamingInputManager())
0415 {
0416 StreamingInputManager()->SetInttBcoRange(m_BcoRange);
0417 StreamingInputManager()->SetInttNegativeBco(m_NegativeBco);
0418 }
0419 }