Back to home page

sPhenix code displayed by LXR

 
 

    


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)  // old combined packet containers
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)  // old combined packet containers
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   //  PHNodeIterator
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       //      std::cout << "ClockDiffCheck: " << "could not find " << iter << " node" << std::endl;
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     // only calculate clk diff and correct clock for rollover if previous clk is set (default is max uint64)
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     // at least one packet (6024) has a stuck bit in the fem event nr, check fem clock counter in this case
0445     // if they are identical FEM is good (not checked if the FEM clock is stuck though)
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  // event nr and fem clock differ
0462     {
0463       // now lets find which one is the outlier
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 }