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