File indexing completed on 2025-08-05 08:16:15
0001 #include "SingleCemcTriggerInput.h"
0002
0003 #include "Fun4AllPrdfInputTriggerManager.h"
0004 #include "InputManagerType.h"
0005
0006 #include <ffarawobjects/CaloPacketContainerv1.h>
0007 #include <ffarawobjects/CaloPacketv1.h>
0008
0009 #include <phool/PHCompositeNode.h>
0010 #include <phool/PHIODataNode.h> // for PHIODataNode
0011 #include <phool/PHNode.h> // for PHNode
0012 #include <phool/PHNodeIterator.h> // for PHNodeIterator
0013 #include <phool/PHObject.h> // for PHObject
0014 #include <phool/getClass.h>
0015 #include <phool/phool.h>
0016
0017 #include <Event/Event.h>
0018 #include <Event/EventTypes.h>
0019 #include <Event/Eventiterator.h>
0020 #include <Event/packet.h> // for Packet
0021
0022 #include <TSystem.h>
0023
0024 #include <algorithm>
0025 #include <cstdint> // for uint64_t
0026 #include <iostream> // for operator<<, basic_ostream<...
0027 #include <iterator> // for reverse_iterator
0028 #include <limits> // for numeric_limits
0029 #include <memory>
0030 #include <set>
0031 #include <utility> // for pair
0032
0033 SingleCemcTriggerInput::SingleCemcTriggerInput(const std::string &name)
0034 : SingleTriggerInput(name)
0035 {
0036 SubsystemEnum(InputManagerType::CEMC);
0037 LocalPoolDepth(3);
0038 }
0039
0040 SingleCemcTriggerInput::~SingleCemcTriggerInput()
0041 {
0042 CleanupUsedLocalPackets(std::numeric_limits<int>::max());
0043 CleanupUsedPackets(std::numeric_limits<int>::max());
0044
0045
0046 while (m_EventStack.begin() != m_EventStack.end())
0047 {
0048 m_EventStack.erase(m_EventStack.begin());
0049 }
0050 }
0051
0052 void SingleCemcTriggerInput::FillPool(const unsigned int keep)
0053 {
0054 if (AllDone())
0055 {
0056 return;
0057 }
0058 while (GetEventiterator() == nullptr)
0059 {
0060 if (!OpenNextFile())
0061 {
0062 AllDone(1);
0063 return;
0064 }
0065 }
0066 while (GetSomeMoreEvents(keep))
0067 {
0068 std::unique_ptr<Event> evt(GetEventiterator()->getNextEvent());
0069 while (!evt)
0070 {
0071 fileclose();
0072 if (!OpenNextFile())
0073 {
0074 AllDone(1);
0075 return;
0076 }
0077 evt.reset(GetEventiterator()->getNextEvent());
0078 }
0079 if (Verbosity() > 21)
0080 {
0081 std::cout << PHWHERE << "Fetching next Event" << evt->getEvtSequence() << std::endl;
0082 }
0083 RunNumber(evt->getRunNumber());
0084 if (Verbosity() > 21)
0085 {
0086 evt->identify();
0087 }
0088 if (evt->getEvtType() != DATAEVENT)
0089 {
0090 m_NumSpecialEvents++;
0091 continue;
0092 }
0093 int EventSequence = evt->getEvtSequence();
0094 if (EventSequence < SkipToEvent())
0095 {
0096 continue;
0097 }
0098 std::vector<Packet *> pktvec = evt->getPacketVector();
0099 for (auto packet : pktvec)
0100 {
0101 int packet_id = packet->getIdentifier();
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113 int CorrectedEventSequence = EventSequence + EventNumberOffset(packet_id);
0114 if (Verbosity() > 2)
0115 {
0116 packet->identify();
0117 }
0118
0119
0120 CaloPacket *newhit = new CaloPacketv1();
0121 int nr_modules = packet->iValue(0, "NRMODULES");
0122 int nr_channels = packet->iValue(0, "CHANNELS");
0123 int nr_samples = packet->iValue(0, "SAMPLES");
0124 if (nr_modules > newhit->getMaxNumModules())
0125 {
0126 std::cout << PHWHERE << " too many modules " << nr_modules << ", max is "
0127 << newhit->getMaxNumModules() << ", need to adjust arrays" << std::endl;
0128 gSystem->Exit(1);
0129 }
0130 if (nr_channels > newhit->getMaxNumChannels())
0131 {
0132 std::cout << PHWHERE << " too many channels " << nr_channels << ", max is "
0133 << newhit->getMaxNumChannels() << ", need to adjust arrays" << std::endl;
0134 gSystem->Exit(1);
0135 }
0136 if (nr_samples > newhit->getMaxNumSamples())
0137 {
0138 std::cout << PHWHERE << " too many samples " << nr_samples << ", max is "
0139 << newhit->getMaxNumSamples() << ", need to adjust arrays" << std::endl;
0140 gSystem->Exit(1);
0141 }
0142
0143 uint64_t gtm_bco = packet->lValue(0, "CLOCK");
0144 newhit->setNrModules(nr_modules);
0145 newhit->setNrSamples(nr_samples);
0146 newhit->setNrChannels(nr_channels);
0147 newhit->setBCO(gtm_bco);
0148 newhit->setPacketEvtSequence(packet->iValue(0, "EVTNR"));
0149 newhit->setIdentifier(packet_id);
0150 newhit->setHitFormat(packet->getHitFormat());
0151 newhit->setEvtSequence(CorrectedEventSequence);
0152 newhit->setEvenChecksum(packet->iValue(0, "EVENCHECKSUM"));
0153 newhit->setCalcEvenChecksum(packet->iValue(0, "CALCEVENCHECKSUM"));
0154 newhit->setOddChecksum(packet->iValue(0, "ODDCHECKSUM"));
0155 newhit->setCalcOddChecksum(packet->iValue(0, "CALCODDCHECKSUM"));
0156 newhit->setModuleAddress(packet->iValue(0, "MODULEADDRESS"));
0157 newhit->setDetId(packet->iValue(0, "DETID"));
0158
0159 std::map<int, unsigned int> femevtmap;
0160 std::map<int, unsigned int> femclkmap;
0161 unsigned int femevt = std::numeric_limits<unsigned int>::max();
0162 unsigned int femclk = std::numeric_limits<unsigned int>::max();
0163 for (int ifem = 0; ifem < nr_modules; ifem++)
0164 {
0165 femevt = packet->iValue(ifem, "FEMEVTNR");
0166 femclk = packet->iValue(ifem, "FEMCLOCK");
0167 femclkmap[femclk]++;
0168 femevtmap[femevt]++;
0169 newhit->setFemSlot(ifem, packet->iValue(ifem, "FEMSLOT"));
0170 newhit->setChecksumLsb(ifem, packet->iValue(ifem, "CHECKSUMLSB"));
0171 newhit->setChecksumMsb(ifem, packet->iValue(ifem, "CHECKSUMMSB"));
0172 newhit->setCalcChecksumLsb(ifem, packet->iValue(ifem, "CALCCHECKSUMLSB"));
0173 newhit->setCalcChecksumMsb(ifem, packet->iValue(ifem, "CALCCHECKSUMMSB"));
0174 }
0175
0176 if (femclkmap.size() > 1)
0177 {
0178 if (femclkmap.size() >= 3)
0179 {
0180 femclk = std::numeric_limits<int>::max();
0181 }
0182 else
0183 {
0184 unsigned int imax = 0;
0185 for (auto &iter : femclkmap)
0186 {
0187 if (imax < iter.second)
0188 {
0189 imax = iter.second;
0190 femclk = iter.first;
0191 }
0192 }
0193 }
0194 }
0195 for (int ifem = 0; ifem < nr_modules; ifem++)
0196 {
0197 newhit->setFemClock(ifem, femclk);
0198 }
0199
0200
0201 if (femevtmap.size() > 1)
0202 {
0203 if (femevtmap.size() >= 3)
0204 {
0205 femevt = std::numeric_limits<int>::max();
0206 }
0207 else
0208 {
0209 unsigned int imax = 0;
0210 for (auto &iter : femevtmap)
0211 {
0212 if (imax < iter.second)
0213 {
0214 imax = iter.second;
0215 femevt = iter.first;
0216 }
0217 }
0218 }
0219 }
0220 for (int ifem = 0; ifem < nr_modules; ifem++)
0221 {
0222 newhit->setFemEvtSequence(ifem, femevt);
0223 }
0224
0225 for (int ipmt = 0; ipmt < nr_channels; ipmt++)
0226 {
0227
0228
0229 bool isSuppressed = packet->iValue(ipmt, "SUPPRESSED");
0230 newhit->setSuppressed(ipmt, isSuppressed);
0231 if (isSuppressed)
0232 {
0233 newhit->setPre(ipmt, packet->iValue(ipmt, "PRE"));
0234 newhit->setPost(ipmt, packet->iValue(ipmt, "POST"));
0235 }
0236 else
0237 {
0238 for (int isamp = 0; isamp < nr_samples; isamp++)
0239 {
0240 newhit->setSample(ipmt, isamp, packet->iValue(isamp, ipmt));
0241 }
0242 }
0243 }
0244 if (Verbosity() > 2)
0245 {
0246 std::cout << PHWHERE << "corrected evtno: " << CorrectedEventSequence
0247 << ", original evtno: " << EventSequence
0248 << ", bco: 0x" << std::hex << gtm_bco << std::dec
0249 << std::endl;
0250 }
0251
0252 m_LocalPacketMap[CorrectedEventSequence].push_back(newhit);
0253 m_EventStack.insert(CorrectedEventSequence);
0254 if (ddump_enabled())
0255 {
0256 ddumppacket(packet);
0257 }
0258 delete packet;
0259 }
0260 if (m_LocalPacketMap.size() >= LocalPoolDepth())
0261 {
0262 CheckFEMEventNumber();
0263 }
0264 while (m_LocalPacketMap.size() > LocalPoolDepth())
0265 {
0266 std::set<int> events;
0267 auto nh = m_LocalPacketMap.begin()->second;
0268
0269 events.insert(m_LocalPacketMap.begin()->first);
0270 m_PacketMap[m_LocalPacketMap.begin()->first] = std::move(nh);
0271 m_LocalPacketMap.erase(m_LocalPacketMap.begin());
0272
0273 if (FEMClockProblemFlag())
0274 {
0275 std::vector<OfflinePacket *> badpackets;
0276 uint64_t refbco = std::numeric_limits<uint64_t>::max();
0277 uint64_t fallbackrefbco = std::numeric_limits<uint64_t>::max();
0278 for (const auto &iter : m_PacketMap)
0279 {
0280 if (events.find(iter.first) == events.end())
0281 {
0282
0283 continue;
0284 }
0285 for (auto pktiter : iter.second)
0286 {
0287 if (pktiter->getIdentifier() == ClockReferencePacket())
0288 {
0289 refbco = pktiter->getBCO();
0290 }
0291 else if (m_BadBCOPacketSet.find(pktiter->getIdentifier()) == m_BadBCOPacketSet.end())
0292 {
0293 fallbackrefbco = pktiter->getBCO();
0294 }
0295 else
0296 {
0297
0298 badpackets.push_back(pktiter);
0299 }
0300 }
0301 if (refbco == std::numeric_limits<uint64_t>::max())
0302 {
0303 static int count = 0;
0304 if (count < 1000)
0305 {
0306 std::cout << PHWHERE << ": crap that didn't work, could not locate reference packet" << std::endl;
0307 count++;
0308 }
0309 refbco = fallbackrefbco;
0310 }
0311 for (auto pktiter : badpackets)
0312 {
0313 if (Verbosity() > 2)
0314 {
0315 std::cout << "event " << iter.first << " Setting packet " << pktiter->getIdentifier() << " to bco " << std::hex
0316 << refbco << std::dec << std::endl;
0317 }
0318 pktiter->setBCO(refbco);
0319 }
0320 }
0321 }
0322 }
0323
0324 if (TriggerInputManager())
0325 {
0326 for (const auto &evtiter : m_PacketMap)
0327 {
0328 for (auto pktiter : evtiter.second)
0329 {
0330 CaloPacket *calpacket = dynamic_cast<CaloPacket *>(pktiter);
0331 if (calpacket)
0332 {
0333
0334 TriggerInputManager()->AddCemcPacket(evtiter.first, calpacket);
0335 }
0336 else
0337 {
0338 static int count = 0;
0339 if (count < 1000)
0340 {
0341 std::cout << PHWHERE << " dynamic cast from offline to calo packet failed??? here is its identify():" << std::endl;
0342 count++;
0343 }
0344 pktiter->identify();
0345 }
0346 }
0347 }
0348 }
0349 }
0350 }
0351
0352 void SingleCemcTriggerInput::Print(const std::string &what) const
0353 {
0354 if (what == "ALL" || what == "STORAGE")
0355 {
0356 for (const auto &bcliter : m_PacketMap)
0357 {
0358 std::cout << PHWHERE << "Event: " << bcliter.first << std::endl;
0359 }
0360 }
0361 if (what == "ALL" || what == "STACK")
0362 {
0363 for (auto iter : m_EventStack)
0364 {
0365 std::cout << PHWHERE << "stacked event: " << iter << std::endl;
0366 }
0367 }
0368 if (what == "LOCALMAP")
0369 {
0370 for (auto &iter : m_LocalPacketMap)
0371 {
0372 std::cout << "LocalMap Event " << iter.first << std::endl;
0373 for (auto pktiter : iter.second)
0374 {
0375 std::cout << "Packet " << pktiter->getIdentifier()
0376 << ", BCO: " << std::hex << pktiter->getBCO() << std::dec
0377 << ", FEM: " << std::hex << pktiter->iValue(0, "FEMCLOCK") << std::dec << std::endl;
0378 }
0379 }
0380 }
0381 if (what == "PACKETMAP")
0382 {
0383 for (auto &iter : m_PacketMap)
0384 {
0385 std::cout << "PacketMap Event " << iter.first << std::endl;
0386 for (auto pktiter : iter.second)
0387 {
0388 std::cout << "Packet " << pktiter->getIdentifier()
0389 << ", BCO: " << std::hex << pktiter->getBCO() << std::dec
0390 << ", FEM: " << std::hex << pktiter->iValue(0, "FEMCLOCK") << std::dec << std::endl;
0391 }
0392 }
0393 }
0394 }
0395
0396 void SingleCemcTriggerInput::CleanupUsedLocalPackets(const int eventno)
0397 {
0398 std::vector<int> toclearevents;
0399 for (const auto &iter : m_LocalPacketMap)
0400 {
0401 if (iter.first <= eventno)
0402 {
0403 for (auto pktiter : iter.second)
0404 {
0405 delete pktiter;
0406 }
0407 toclearevents.push_back(iter.first);
0408 }
0409 else
0410 {
0411 break;
0412 }
0413 }
0414 for (auto iter : toclearevents)
0415 {
0416
0417 m_EventStack.erase(iter);
0418 m_LocalPacketMap.erase(iter);
0419 }
0420 }
0421
0422 void SingleCemcTriggerInput::CleanupUsedPackets(const int eventno)
0423 {
0424 std::vector<int> toclearevents;
0425 for (const auto &iter : m_PacketMap)
0426 {
0427 if (iter.first <= eventno)
0428 {
0429 for (auto pktiter : iter.second)
0430 {
0431 delete pktiter;
0432 }
0433 toclearevents.push_back(iter.first);
0434 }
0435 else
0436 {
0437 break;
0438 }
0439 }
0440
0441 for (auto iter : toclearevents)
0442 {
0443
0444 m_EventStack.erase(iter);
0445 m_PacketMap.erase(iter);
0446 }
0447 }
0448
0449 void SingleCemcTriggerInput::ClearCurrentEvent()
0450 {
0451
0452 int currentevent = *m_EventStack.begin();
0453
0454 CleanupUsedPackets(currentevent);
0455 return;
0456 }
0457
0458 void SingleCemcTriggerInput::CreateDSTNode(PHCompositeNode *topNode)
0459 {
0460 PHNodeIterator iter(topNode);
0461 PHCompositeNode *dstNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "DST"));
0462 if (!dstNode)
0463 {
0464 dstNode = new PHCompositeNode("DST");
0465 topNode->addNode(dstNode);
0466 }
0467 PHNodeIterator iterDst(dstNode);
0468 PHCompositeNode *detNode = dynamic_cast<PHCompositeNode *>(iterDst.findFirst("PHCompositeNode", "CEMC"));
0469 if (!detNode)
0470 {
0471 detNode = new PHCompositeNode("CEMC");
0472 dstNode->addNode(detNode);
0473 }
0474 CaloPacketContainer *cemcpacketcont = findNode::getClass<CaloPacketContainer>(detNode, "CEMCPackets");
0475 if (!cemcpacketcont)
0476 {
0477 cemcpacketcont = new CaloPacketContainerv1();
0478 PHIODataNode<PHObject> *newNode = new PHIODataNode<PHObject>(cemcpacketcont, "CEMCPackets", "PHObject");
0479 detNode->addNode(newNode);
0480 }
0481 }
0482
0483 void SingleCemcTriggerInput::CheckFEMClock()
0484 {
0485
0486 auto first_event = m_LocalPacketMap.begin();
0487
0488 std::map<uint64_t, std::set<int>> pktbcomap;
0489 uint64_t ref_femclk = std::numeric_limits<uint64_t>::max();
0490 std::map<uint64_t, unsigned int> bcocount;
0491 for (auto pktiter : first_event->second)
0492 {
0493
0494 std::set<uint64_t> femclockset;
0495 for (int i = 0; i < pktiter->iValue(0, "NRMODULES"); i++)
0496 {
0497 uint64_t femclk = pktiter->iValue(i, "FEMCLOCK");
0498 bcocount[femclk]++;
0499 if (Verbosity() > 21)
0500 {
0501 std::cout << "packet id: " << pktiter->getIdentifier() << " packet clock: 0x" << std::hex << pktiter->iValue(0, "CLOCK")
0502 << " FEMClock: 0x" << femclk << std::dec << std::endl;
0503 }
0504 femclockset.insert(femclk);
0505 if (ref_femclk == std::numeric_limits<uint64_t>::max())
0506 {
0507 ref_femclk = femclk;
0508 }
0509 else
0510 {
0511 if (ref_femclk != femclk)
0512 {
0513 if (Verbosity() > 1)
0514 {
0515 std::cout << "Event " << first_event->first << " FEM Clock mismatch for packet " << pktiter->getIdentifier() << std::endl;
0516 std::cout << "ref fem clk: 0x" << std::hex << ref_femclk << ", femclk: 0x"
0517 << femclk << std::dec << std::endl;
0518 }
0519 }
0520 }
0521 if (femclockset.size() > 1)
0522 {
0523 static int count = 0;
0524 if (count < 1000)
0525 {
0526 std::cout << PHWHERE << " FEM Clocks differ for packet " << pktiter->getIdentifier()
0527 << ", found " << femclockset.size() << " different ones" << std::endl;
0528 for (auto &iter : femclockset)
0529 {
0530 std::cout << "0x" << std::hex << iter << std::dec << std::endl;
0531 }
0532 count++;
0533 }
0534 }
0535 }
0536 pktbcomap[*femclockset.begin()].insert(pktiter->getIdentifier());
0537 }
0538
0539 if (bcocount.size() < 2)
0540 {
0541
0542 return;
0543 }
0544 static int count = 0;
0545 if (count < 1000)
0546 {
0547 std::cout << PHWHERE << " FEM clocks are off, found " << bcocount.size() << " different ones, here we go ..." << std::endl;
0548 count++;
0549 }
0550
0551 SetFEMClockProblemFlag();
0552
0553 if (Verbosity() > 1)
0554 {
0555 std::cout << "LocalPacketMap size: " << m_LocalPacketMap.size()
0556 << ", pool depth: " << LocalPoolDepth() << std::endl;
0557 }
0558 if (m_LocalPacketMap.size() < LocalPoolDepth())
0559 {
0560
0561
0562 return;
0563 }
0564
0565 uint64_t goodfembco = std::numeric_limits<uint64_t>::max();
0566 unsigned int maxnumpackets = 0;
0567 for (auto bcoiter : bcocount)
0568 {
0569 if (bcoiter.second > maxnumpackets)
0570 {
0571 maxnumpackets = bcoiter.second;
0572 goodfembco = bcoiter.first;
0573 }
0574
0575 }
0576 int refpacketid = *pktbcomap.find(goodfembco)->second.begin();
0577 if (Verbosity() > 1)
0578 {
0579 std::cout << "Use packet " << refpacketid << " for reference bco 0x"
0580 << std::hex << goodfembco << std::dec << std::endl;
0581 }
0582 SetClockReferencePacket(refpacketid);
0583 pktbcomap.erase(goodfembco);
0584 for (const auto &badpktmapiter : pktbcomap)
0585 {
0586 for (auto badpktiter : badpktmapiter.second)
0587 {
0588
0589 if (TriggerInputManager())
0590 {
0591 TriggerInputManager()->AddFEMProblemPacket(badpktiter);
0592 }
0593 m_BadBCOPacketSet.insert(badpktiter);
0594 }
0595 }
0596 std::vector<uint64_t> HayStack;
0597 std::map<int, std::vector<uint64_t>> NeedleMap;
0598 m_EventRefBCO.clear();
0599 for (auto &iter : m_LocalPacketMap)
0600 {
0601
0602 for (auto pktiter : iter.second)
0603 {
0604 if (pktiter->getIdentifier() == refpacketid)
0605 {
0606
0607 uint64_t femclk = pktiter->iValue(0, "FEMCLOCK");
0608 HayStack.push_back(femclk);
0609 m_EventRefBCO[iter.first] = pktiter->getBCO();
0610 }
0611 else if (m_BadBCOPacketSet.find(pktiter->getIdentifier()) != m_BadBCOPacketSet.end())
0612 {
0613 uint64_t femclk = pktiter->iValue(0, "FEMCLOCK");
0614 NeedleMap[pktiter->getIdentifier()].push_back(femclk);
0615 }
0616 }
0617 }
0618 if (Verbosity() > 1)
0619 {
0620 for (auto bco : HayStack)
0621 {
0622 std::cout << "Haystack : 0x" << std::hex << bco << std::dec << std::endl;
0623 }
0624 }
0625 for (const auto &needleiter : NeedleMap)
0626 {
0627 std::vector needle = needleiter.second;
0628 needle.pop_back();
0629 if (Verbosity() > 1)
0630 {
0631 std::cout << "Packet " << needleiter.first << std::endl;
0632 for (auto bco : needle)
0633 {
0634 std::cout << "Needle: 0x" << std::hex << bco << std::dec << std::endl;
0635 }
0636 }
0637 auto it = std::search(HayStack.begin(), HayStack.end(), needle.begin(), needle.end());
0638 if (it != HayStack.end())
0639 {
0640 int position = std::distance(HayStack.begin(), it);
0641
0642 AdjustEventNumberOffset(needleiter.first, position);
0643 ShiftEvents(needleiter.first, position);
0644 }
0645 }
0646 return;
0647 }
0648
0649 int SingleCemcTriggerInput::ShiftEvents(int pktid, int offset)
0650 {
0651 std::vector<int> eventnumbers;
0652 for (auto pktmapiter = m_LocalPacketMap.rbegin(); pktmapiter != m_LocalPacketMap.rend(); ++pktmapiter)
0653 {
0654 eventnumbers.push_back(pktmapiter->first);
0655 }
0656 for (auto evtnumiter : eventnumbers)
0657 {
0658 auto &pktmapiter = m_LocalPacketMap[evtnumiter];
0659
0660 int newevent = evtnumiter + offset;
0661 for (unsigned int i = 0; i < pktmapiter.size(); ++i)
0662 {
0663 auto packet = pktmapiter[i];
0664 if (packet->getIdentifier() == pktid)
0665 {
0666 if (Verbosity() > 1)
0667 {
0668 std::cout << "moving packet " << packet->getIdentifier() << " from position " << i
0669 << " from event " << evtnumiter << " to event " << newevent << std::endl;
0670 }
0671 auto bcotmpiter = m_EventRefBCO.find(newevent);
0672 if (bcotmpiter != m_EventRefBCO.end())
0673 {
0674 packet->setBCO(bcotmpiter->second);
0675 }
0676 else
0677 {
0678 packet->setBCO(std::numeric_limits<uint64_t>::max());
0679 }
0680
0681 m_LocalPacketMap[newevent].push_back(packet);
0682 pktmapiter.erase(pktmapiter.begin() + i);
0683 break;
0684 }
0685 }
0686 if (Verbosity() > 1)
0687 {
0688 for (auto iter : m_LocalPacketMap[evtnumiter])
0689 {
0690 std::cout << "local packetmap after erase: " << iter->getIdentifier() << std::endl;
0691 }
0692 }
0693 }
0694
0695 return 0;
0696 }
0697
0698 void SingleCemcTriggerInput::CheckFEMEventNumber()
0699 {
0700
0701 auto first_event = m_LocalPacketMap.begin();
0702
0703 std::map<int, std::set<int>> pktevtnummap;
0704 int ref_femevtnum = std::numeric_limits<int>::max();
0705 std::map<int, unsigned int> evtnumcount;
0706 for (auto pktiter : first_event->second)
0707 {
0708
0709 std::set<int> femevtnumset;
0710 for (int i = 0; i < pktiter->iValue(0, "NRMODULES"); i++)
0711 {
0712 int femevtnum = pktiter->iValue(i, "FEMEVTNR");
0713 evtnumcount[femevtnum]++;
0714 if (Verbosity() > 21)
0715 {
0716 std::cout << "packet id: " << pktiter->getIdentifier() << " packet clock: 0x" << std::hex << pktiter->iValue(0, "CLOCK")
0717 << " FEM EvtNo: " << std::dec << femevtnum << std::endl;
0718 }
0719 femevtnumset.insert(femevtnum);
0720 if (ref_femevtnum == std::numeric_limits<int>::max())
0721 {
0722 ref_femevtnum = femevtnum;
0723 }
0724 else
0725 {
0726 if (ref_femevtnum != femevtnum)
0727 {
0728 if (Verbosity() > 1)
0729 {
0730 std::cout << "Event " << first_event->first << " FEM Evt Num mismatch for packet " << pktiter->getIdentifier() << std::endl;
0731 std::cout << "ref fem evt: " << ref_femevtnum << ", femevtnum: "
0732 << femevtnum << std::endl;
0733 }
0734 }
0735 }
0736 if (femevtnumset.size() > 1)
0737 {
0738 static int count = 0;
0739 if (count < 1000)
0740 {
0741 std::cout << PHWHERE << " FEM Evt Nums differ for packet " << pktiter->getIdentifier()
0742 << ", found " << femevtnumset.size() << " different ones" << std::endl;
0743 for (auto &iter : femevtnumset)
0744 {
0745 std::cout << iter << std::endl;
0746 }
0747 count++;
0748 }
0749 }
0750 }
0751 pktevtnummap[*femevtnumset.begin()].insert(pktiter->getIdentifier());
0752 }
0753
0754 if (evtnumcount.size() < 2)
0755 {
0756
0757 return;
0758 }
0759 static int count = 0;
0760 if (count < 1000)
0761 {
0762 std::cout << PHWHERE << " FEM clocks are off, found " << evtnumcount.size() << " different ones, here we go ..." << std::endl;
0763 count++;
0764 }
0765
0766 SetFEMClockProblemFlag();
0767
0768 if (Verbosity() > 1)
0769 {
0770 std::cout << "LocalPacketMap size: " << m_LocalPacketMap.size()
0771 << ", pool depth: " << LocalPoolDepth() << std::endl;
0772 }
0773 if (m_LocalPacketMap.size() < LocalPoolDepth())
0774 {
0775
0776
0777 return;
0778 }
0779
0780 int goodfemevtnum = std::numeric_limits<int>::max();
0781 unsigned int maxnumpackets = 0;
0782 for (auto bcoiter : evtnumcount)
0783 {
0784 if (bcoiter.second > maxnumpackets)
0785 {
0786 maxnumpackets = bcoiter.second;
0787 goodfemevtnum = bcoiter.first;
0788 }
0789
0790 }
0791 int refpacketid = *pktevtnummap.find(goodfemevtnum)->second.begin();
0792 if (Verbosity() > 1)
0793 {
0794 std::cout << "Use packet " << refpacketid << " for reference bco 0x"
0795 << std::hex << goodfemevtnum << std::dec << std::endl;
0796 }
0797 SetClockReferencePacket(refpacketid);
0798 pktevtnummap.erase(goodfemevtnum);
0799 for (const auto &badpktmapiter : pktevtnummap)
0800 {
0801 for (auto badpktiter : badpktmapiter.second)
0802 {
0803
0804 if (TriggerInputManager())
0805 {
0806 TriggerInputManager()->AddFEMProblemPacket(badpktiter);
0807 }
0808 m_BadBCOPacketSet.insert(badpktiter);
0809 }
0810 }
0811 std::vector<int> HayStack;
0812 std::map<int, std::vector<int>> NeedleMap;
0813 m_EventRefBCO.clear();
0814 for (auto &iter : m_LocalPacketMap)
0815 {
0816
0817 for (auto pktiter : iter.second)
0818 {
0819 if (pktiter->getIdentifier() == refpacketid)
0820 {
0821
0822 int femevtnum = pktiter->iValue(0, "FEMEVTNR");
0823 HayStack.push_back(femevtnum);
0824 m_EventRefBCO[iter.first] = pktiter->getBCO();
0825 }
0826 else if (m_BadBCOPacketSet.find(pktiter->getIdentifier()) != m_BadBCOPacketSet.end())
0827 {
0828 int femevtnum = pktiter->iValue(0, "FEMEVTNR");
0829 NeedleMap[pktiter->getIdentifier()].push_back(femevtnum);
0830 }
0831 }
0832 }
0833 if (Verbosity() > 1)
0834 {
0835 for (auto evtno : HayStack)
0836 {
0837 std::cout << "Haystack : " << evtno << std::endl;
0838 }
0839 }
0840 for (const auto &needleiter : NeedleMap)
0841 {
0842 std::vector needle = needleiter.second;
0843 needle.pop_back();
0844 if (Verbosity() > 1)
0845 {
0846 std::cout << "Packet " << needleiter.first << std::endl;
0847 for (auto evtno : needle)
0848 {
0849 std::cout << "Needle: " << evtno << std::endl;
0850 }
0851 }
0852 auto it = std::search(HayStack.begin(), HayStack.end(), needle.begin(), needle.end());
0853 if (it != HayStack.end())
0854 {
0855 int position = std::distance(HayStack.begin(), it);
0856
0857 AdjustEventNumberOffset(needleiter.first, position);
0858 ShiftEvents(needleiter.first, position);
0859 }
0860 }
0861 return;
0862 }