File indexing completed on 2025-08-06 08:17:12
0001 #include "ClockDiffCheck.h"
0002
0003 #include <fun4all/Fun4AllInputManager.h>
0004 #include <fun4all/Fun4AllReturnCodes.h>
0005 #include <fun4all/SubsysReco.h> // for SubsysReco
0006
0007 #include <ffarawobjects/CaloPacket.h>
0008 #include <ffarawobjects/CaloPacketContainer.h>
0009
0010 #include <phool/PHCompositeNode.h>
0011 #include <phool/PHDataNode.h>
0012 #include <phool/PHNode.h> // for PHNode
0013 #include <phool/PHNodeIterator.h> // for PHNodeIterator
0014 #include <phool/PHPointerListIterator.h>
0015 #include <phool/getClass.h>
0016
0017 #include <TH1.h>
0018 #include <TSystem.h>
0019
0020 #include <bitset>
0021 #include <iostream> // for operator<<, endl, basic_ost...
0022 #include <utility> // for pair
0023 #include <vector> // for vector
0024
0025
0026 ClockDiffCheck::ClockDiffCheck(const std::string &name)
0027 : SubsysReco(name)
0028 {
0029 }
0030
0031 ClockDiffCheck::~ClockDiffCheck()
0032 {
0033 for (auto &[packetid, tup] : m_PacketStuffMap)
0034 {
0035 delete std::get<3>(tup);
0036 std::get<3>(tup) = nullptr;
0037 }
0038 }
0039
0040
0041 int ClockDiffCheck::InitRun(PHCompositeNode *topNode)
0042 {
0043 PHNodeIterator iter(topNode);
0044 PHCompositeNode *dstNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "DST"));
0045 if (!dstNode)
0046 {
0047 std::cout << "ClockDiffCheck: " << "Could not find DST Node" << std::endl;
0048 gSystem->Exit(1);
0049 exit(1);
0050 }
0051 PHNodeIterator iterDst(dstNode);
0052 PHCompositeNode *pktNode = dynamic_cast<PHCompositeNode *>(iterDst.findFirst("PHCompositeNode", "Packets"));
0053 PHCompositeNode *pktKeepNode = dynamic_cast<PHCompositeNode *>(iterDst.findFirst("PHCompositeNode", "PacketsKeep"));
0054 if (pktNode)
0055 {
0056 PHNodeIterator iterPkt(pktNode);
0057 PHPointerListIterator<PHNode> nodeIter(iterPkt.ls());
0058 PHNode *thisNode;
0059 while ((thisNode = nodeIter()))
0060 {
0061 m_PacketNodeNames.push_back(thisNode->getName());
0062 }
0063 }
0064 if (pktKeepNode)
0065 {
0066 PHNodeIterator iterPkt(pktKeepNode);
0067 PHPointerListIterator<PHNode> nodeIter(iterPkt.ls());
0068 PHNode *thisNode;
0069 while ((thisNode = nodeIter()))
0070 {
0071 m_PacketNodeNames.push_back(thisNode->getName());
0072 }
0073 }
0074 return Fun4AllReturnCodes::EVENT_OK;
0075 }
0076
0077
0078 int ClockDiffCheck::process_event(PHCompositeNode *topNode)
0079 {
0080 count++;
0081
0082 PHNodeIterator topnodeiter(topNode);
0083 for (auto &iter : m_PacketStuffMap)
0084 {
0085 std::get<0>(iter.second) = std::get<1>(iter.second);
0086 std::get<4>(iter.second) = false;
0087 }
0088 OfflinePacket *pkt = findNode::getClass<OfflinePacket>(topNode, 14001);
0089 if (pkt)
0090 {
0091 FillPacketDiff(pkt);
0092 }
0093 pkt = findNode::getClass<OfflinePacket>(topNode, "GL1Packet");
0094 if (pkt)
0095 {
0096 FillPacketDiff(pkt);
0097 }
0098
0099 std::vector<std::string> nodenames{"CEMCPackets", "HCALPackets", "MBDPackets", "SEPDPackets", "ZDCPackets"};
0100 for (const auto &iter : nodenames)
0101 {
0102 CaloPacketContainer *cemccont = findNode::getClass<CaloPacketContainer>(topNode, iter);
0103 if (!cemccont)
0104 {
0105
0106 }
0107 else
0108 {
0109 FillCaloClockDiff(cemccont);
0110 }
0111 }
0112
0113 for (const auto &iter : m_PacketNodeNames)
0114 {
0115 if (iter == "14001") continue;
0116 CaloPacket *calopacket = findNode::getClass<CaloPacket>(topNode, iter);
0117 if (!calopacket)
0118 {
0119 std::cout << "ClockDiffCheck: " << "could not find " << iter << " node" << std::endl;
0120 }
0121 else
0122 {
0123 if (calopacket->getStatus() != OfflinePacket::PACKET_OK)
0124 {
0125 static int npacketprnt = 0;
0126 if ( npacketprnt < 100)
0127 {
0128 std::cout << "packet " << calopacket->getIdentifier() << " status marked as " << calopacket->getStatus() << ". Skipping diff check " << count << std::endl;
0129 npacketprnt++;
0130 }
0131 std::get<1>(m_PacketStuffMap[calopacket->getIdentifier()]) = std::numeric_limits<uint64_t>::max();
0132 continue;
0133 }
0134 FillCaloClockDiffSngl(calopacket);
0135 }
0136 }
0137
0138 std::vector<unsigned int> badPackets;
0139 uint64_t refdiff = std::numeric_limits<uint64_t>::max();
0140 auto itergl1 = m_PacketStuffMap.find(14001);
0141 if (itergl1 != m_PacketStuffMap.end())
0142 {
0143 refdiff = std::get<2>(itergl1->second);
0144 }
0145 for (auto &iter : m_PacketStuffMap)
0146 {
0147 if (!std::get<4>(iter.second))
0148 {
0149 std::get<0>(iter.second) = std::numeric_limits<uint64_t>::max();
0150 }
0151 else
0152 {
0153 if (Verbosity() > 2)
0154 {
0155 std::cout << "ClockDiffCheck: " << "looking at " << iter.first
0156 << ", prev bco: " << std::hex << std::get<0>(iter.second)
0157 << ", curr bco: " << std::get<1>(iter.second)
0158 << ", clkdiff: " << std::get<2>(iter.second) << std::dec
0159 << ", valid: " << std::get<4>(iter.second) << std::endl;
0160 }
0161 if (refdiff == std::numeric_limits<uint64_t>::max())
0162 {
0163 refdiff = std::get<2>(iter.second);
0164 }
0165 else
0166 {
0167 if ((refdiff & 0xFFFFFFFFU) != (std::get<2>(iter.second) & 0xFFFFFFFFU))
0168 {
0169 badPackets.push_back(iter.first);
0170 static int nprint = 0;
0171 if (nprint < 1000 || Verbosity() > 1)
0172 {
0173 std::bitset<32> x(refdiff);
0174 std::bitset<32> y0(std::get<0>(iter.second));
0175 std::bitset<32> y1(std::get<1>(iter.second));
0176 std::bitset<32> y2(std::get<2>(iter.second));
0177 std::cout << "ClockDiffCheck: " << "packet " << iter.first << " had different clock diff: 0x" << std::hex
0178 << std::get<1>(iter.second) << ", ref diff: 0x" << refdiff << std::dec << std::endl;
0179
0180 std::cout << "reff: " << x << std::endl;
0181 std::cout << "this: " << y2 << std::endl;
0182
0183 std::cout << "prev: " << y0 << std::endl;
0184 std::cout << "curr: " << y1 << std::endl;
0185 nprint++;
0186 }
0187 }
0188 }
0189 }
0190 }
0191
0192 for (const auto &nodeiter : nodenames)
0193 {
0194 CaloPacketContainer *container = findNode::getClass<CaloPacketContainer>(topNode, nodeiter);
0195 if (!container)
0196 {
0197 continue;
0198 }
0199 if (delBadPkts)
0200 {
0201 for (unsigned int i = 0; i < container->get_npackets(); i++)
0202 {
0203 unsigned int packetID = container->getPacket(i)->getIdentifier();
0204 for (unsigned int badPacket : badPackets)
0205 {
0206 if (badPacket == packetID)
0207 {
0208 if (Verbosity() > 1)
0209 {
0210 std::cout << "ClockDiffCheck: " << "Dropping packet " << container->getPacket(i)->getIdentifier() << " for XMIT clock mismatch" << std::endl;
0211 }
0212 container->deletePacket(container->getPacket(i));
0213 break;
0214 }
0215 }
0216 }
0217 }
0218
0219 std::vector<std::vector<int>> EvtCounts;
0220 std::vector<int> NrAndCount(2);
0221 NrAndCount[1] = 1;
0222 int counter = 0;
0223 int bestEvt = -1;
0224 int bestEvtCnt = 0;
0225 unsigned int npacket = container->get_npackets();
0226 for (unsigned int i = 0; i < npacket; i++)
0227 {
0228 CaloPacket *packet = container->getPacket(i);
0229 if (packet)
0230 {
0231 int nrModules = packet->iValue(0, "NRMODULES");
0232 for (int j = 0; j < nrModules; j++)
0233 {
0234 int k;
0235 for (k = 0; k < counter; k++)
0236 {
0237 if (EvtCounts[k][0] == packet->iValue(j, "FEMEVTNR"))
0238 {
0239 EvtCounts[k][1]++;
0240 break;
0241 }
0242 }
0243 if (k >= counter)
0244 {
0245 NrAndCount[0] = packet->iValue(j, "FEMEVTNR");
0246 EvtCounts.push_back(NrAndCount);
0247 counter++;
0248 }
0249 }
0250 }
0251 }
0252 if (counter > 1)
0253 {
0254 for (int i = 0; i < counter; i++)
0255 {
0256 if (bestEvtCnt < EvtCounts[i][1])
0257 {
0258 bestEvtCnt = EvtCounts[i][1];
0259 bestEvt = EvtCounts[i][0];
0260 }
0261 }
0262 for (unsigned int i = 0; i < npacket; ++i)
0263 {
0264 CaloPacket *packet = container->getPacket(i);
0265 if (packet)
0266 {
0267 for (int j = 0; j < packet->iValue(0, "NRMODULES"); j++)
0268 {
0269 if (packet->iValue(j, "FEMEVTNR") != bestEvt && bestEvt != -1)
0270 {
0271 static int icnt = 0;
0272 if (icnt < 1000)
0273 {
0274 std::cout << "ClockDiffCheck: " << "found different FEM clock for packet " << packet->getIdentifier() << std::endl;
0275 icnt++;
0276 }
0277 if (delBadPkts)
0278 {
0279 if (Verbosity() > 1)
0280 {
0281 std::cout << "ClockDiffCheck: " << "deleting packet " << packet->getIdentifier()
0282 << " with fem clock mismatch" << std::endl;
0283 }
0284 container->deletePacket(packet);
0285 }
0286 break;
0287 }
0288 }
0289 }
0290 }
0291 }
0292 }
0293 for (const auto &iter : m_PacketNodeNames)
0294 {
0295 CaloPacket *calopacket = findNode::getClass<CaloPacket>(topNode, iter);
0296 if (!calopacket)
0297 {
0298 continue;
0299 }
0300 if (delBadPkts)
0301 {
0302 unsigned int packetID = calopacket->getIdentifier();
0303 for (unsigned int badPacket : badPackets)
0304 {
0305 if (badPacket == packetID)
0306 {
0307 static int icnt = 0;
0308 if (icnt < 1000)
0309 {
0310 std::cout << "ClockDiffCheck: " << "Dropping packet " << calopacket->getIdentifier() << " for XMIT clock mismatch" << std::endl;
0311 icnt++;
0312 }
0313 calopacket->Reset();
0314 break;
0315 }
0316 }
0317 }
0318 bool FemClockOk = CheckFemEventNr(calopacket);
0319 if (!FemClockOk)
0320 {
0321 static int icnt = 0;
0322 if (icnt < 100)
0323 {
0324 std::cout << "FemClockOk failed. Resetting packet " << calopacket->getIdentifier()
0325 << " with fem event and clock mismatch" << std::endl;
0326 icnt++;
0327 }
0328 calopacket->Reset();
0329 }
0330 }
0331
0332 return Fun4AllReturnCodes::EVENT_OK;
0333 }
0334
0335 void ClockDiffCheck::FillCaloClockDiff(CaloPacketContainer *pktcont)
0336 {
0337 for (unsigned int i = 0; i < pktcont->get_npackets(); i++)
0338 {
0339 FillCaloClockDiffSngl(pktcont->getPacket(i));
0340 }
0341 return;
0342 }
0343
0344 void ClockDiffCheck::FillCaloClockDiffSngl(CaloPacket *calopkt)
0345 {
0346 unsigned int packetid = calopkt->getIdentifier();
0347 if (m_PacketStuffMap.find(packetid) == m_PacketStuffMap.end())
0348 {
0349 std::string hname = "clkdiff" + std::to_string(packetid);
0350 TH1 *h1 = new TH1F(hname.c_str(), hname.c_str(), 100, 0, 99);
0351 m_PacketStuffMap[packetid] = std::make_tuple(std::numeric_limits<uint64_t>::max(), std::numeric_limits<uint64_t>::max(), std::numeric_limits<uint64_t>::max(), h1, false);
0352 if (Verbosity() > 3)
0353 {
0354 std::cout << "ClockDiffCheck: " << "Add tuple for " << packetid << std::endl;
0355 auto &pktiter = m_PacketStuffMap[packetid];
0356 std::cout << PHWHERE << "packet init " << packetid << std::hex
0357 << ", clk: " << std::get<1>(pktiter)
0358 << ", clkdiff: " << std::get<2>(pktiter) << std::dec << ", valid: " << std::get<4>(pktiter)
0359 << std::endl;
0360 }
0361 }
0362 else
0363 {
0364 auto &pktiter = m_PacketStuffMap[packetid];
0365 uint64_t clk = calopkt->getBCO();
0366 uint64_t clkdiff = std::numeric_limits<uint64_t>::max();
0367 std::get<1>(pktiter) = clk;
0368
0369 if (std::get<0>(pktiter) < std::numeric_limits<uint64_t>::max())
0370 {
0371 if (clk < std::get<0>(pktiter))
0372 {
0373 clk |= 0x100000000U;
0374 }
0375 clkdiff = clk - std::get<0>(pktiter);
0376 clk &= 0xFFFFFFFF;
0377 std::get<2>(pktiter) = clkdiff;
0378 std::get<4>(pktiter) = true;
0379 }
0380
0381 if (Verbosity() > 2)
0382 {
0383 std::cout << "ClockDiffCheck: " << "packet " << packetid << ", clk: " << std::hex << clk
0384 << ", clk(tup): " << std::get<1>(pktiter) << ", diff: " << clkdiff
0385 << ", diff(tup): " << std::get<2>(pktiter) << std::dec << ", valid: " << std::get<4>(pktiter)
0386 << std::endl;
0387 }
0388 }
0389 }
0390
0391 void ClockDiffCheck::FillPacketDiff(OfflinePacket *pkt)
0392 {
0393 unsigned int packetid = pkt->getIdentifier();
0394 uint64_t clk = (pkt->getBCO() & 0xFFFFFFFF);
0395 if (m_PacketStuffMap.find(packetid) == m_PacketStuffMap.end())
0396 {
0397 std::string hname = "clkdiff" + std::to_string(packetid);
0398 TH1 *h1 = new TH1F(hname.c_str(), hname.c_str(), 100, 0, 99);
0399 m_PacketStuffMap[packetid] = std::make_tuple(std::numeric_limits<uint64_t>::max(), std::numeric_limits<uint64_t>::max(), std::numeric_limits<uint64_t>::max(), h1, false);
0400 if (Verbosity() > 3)
0401 {
0402 std::cout << "ClockDiffCheck: " << "Add tuple for " << packetid << std::endl;
0403 }
0404 }
0405 else
0406 {
0407 auto &pktiter = m_PacketStuffMap[packetid];
0408 uint64_t clkdiff = std::numeric_limits<uint64_t>::max();
0409 if (std::get<0>(pktiter) < std::numeric_limits<uint64_t>::max())
0410 {
0411 if (clk < std::get<0>(pktiter))
0412 {
0413 clk |= 0x100000000U;
0414 }
0415 clkdiff = clk - std::get<0>(pktiter);
0416 clk &= 0xFFFFFFFF;
0417 }
0418 std::get<1>(pktiter) = clk;
0419 std::get<2>(pktiter) = clkdiff;
0420 std::get<4>(pktiter) = true;
0421 if (Verbosity() > 2)
0422 {
0423 std::cout << "ClockDiffCheck: " << "packet " << packetid << ", clk: " << std::hex << clk
0424 << ", clk(tup): " << std::get<1>(pktiter) << ", diff: " << clkdiff
0425 << ", diff(tup): " << std::get<2>(pktiter) << std::dec << ", valid: " << std::get<4>(pktiter)
0426 << std::endl;
0427 }
0428 }
0429 }
0430
0431 bool ClockDiffCheck::CheckFemEventNr(CaloPacket *calopkt)
0432 {
0433 int nrModules = calopkt->iValue(0, "NRMODULES");
0434 std::set<int> EventNoSet;
0435 for (int j = 0; j < nrModules; j++)
0436 {
0437 if (calopkt->getFemStatus(j) == CaloPacket::FEM_OK)
0438 {
0439 EventNoSet.insert(calopkt->iValue(j, "FEMEVTNR"));
0440 }
0441 }
0442 if (EventNoSet.size() > 1)
0443 {
0444
0445
0446 std::set<int> FemClockSet;
0447 for (int j = 0; j < nrModules; j++)
0448 {
0449 FemClockSet.insert(calopkt->iValue(j, "FEMCLOCK"));
0450 }
0451 if (FemClockSet.size() == 1)
0452 {
0453 static int icnt = 0;
0454 if (icnt < 100)
0455 {
0456 icnt++;
0457 std::cout << "ClockDiffCheck: " << "clk check Packet " << calopkt->getIdentifier() << " has not unique event numbers"
0458 << " but FEM Clock counters are identical" << std::endl;
0459 }
0460 }
0461 else
0462 {
0463
0464 static int icnt = 0;
0465 if (icnt < 1000)
0466 {
0467 icnt++;
0468 std::cout << "ClockDiffCheck: " << "resetting packet " << calopkt->getIdentifier()
0469 << " with fem event and clock mismatch" << std::endl;
0470 std::map<int, int> EventMap;
0471 std::map<int, int> ClockMap;
0472 for (int j = 0; j < nrModules; j++)
0473 {
0474 EventMap[calopkt->iValue(j, "FEMEVTNR")]++;
0475 ClockMap[calopkt->iValue(j, "FEMCLOCK")]++;
0476 }
0477 for (const auto iterA : EventMap)
0478 {
0479 std::cout << "ClockDiffCheck: " << "Event Nr : " << iterA.first << " shows up " << iterA.second << " times"
0480 << std::hex << ", Event Nr 0x" << iterA.first << std::dec << std::endl;
0481 }
0482 for (const auto iterA : ClockMap)
0483 {
0484 std::cout << "ClockDiffCheck: " << "Clock : 0x" << std::hex << iterA.first << std::dec
0485 << " shows up " << iterA.second << " times" << std::endl;
0486 }
0487 }
0488 return false;
0489 }
0490 }
0491 return true;
0492 }