Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-05 08:16:15

0001 #include "SingleInttPoolInput.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 #include <phool/recoConsts.h>
0015 
0016 #include <Event/Event.h>
0017 #include <Event/EventTypes.h>
0018 #include <Event/Eventiterator.h>
0019 
0020 #include <algorithm>  // for max
0021 #include <cstdint>    // for uint64_t
0022 #include <cstdlib>    // for exit
0023 #include <iostream>   // for operator<<, basic_o...
0024 #include <set>
0025 #include <memory>
0026 #include <utility>  // for pair
0027 
0028 SingleInttPoolInput::SingleInttPoolInput(const std::string &name)
0029   : SingleStreamingInput(name)
0030 {
0031   SubsystemEnum(InputManagerType::INTT);
0032   plist = new Packet *[1];
0033   m_rawHitContainerName = "INTTRAWHIT";
0034 }
0035 
0036 SingleInttPoolInput::~SingleInttPoolInput()
0037 {
0038   delete[] plist;
0039   for (auto iter : poolmap)
0040   {
0041     if (Verbosity() > 2)
0042     {
0043       std::cout << "deleting intt pool for id  " << (iter.second)->getIdentifier() << std::endl;
0044     }
0045     delete (iter.second);
0046   }
0047 }
0048 
0049 void SingleInttPoolInput::FillPool(const uint64_t minBCO)
0050 {
0051   if (AllDone())  // no more files and all events read
0052   {
0053     return;
0054   }
0055   while (GetEventiterator() == nullptr)  // at startup this is a null pointer
0056   {
0057     if (!OpenNextFile())
0058     {
0059       AllDone(1);
0060       return;
0061     }
0062   }
0063 
0064   //  std::set<uint64_t> saved_beamclocks;
0065   while (GetSomeMoreEvents(0))
0066   {
0067     Event *evt = GetEventiterator()->getNextEvent();
0068     while (!evt)
0069     {
0070       fileclose();
0071       if (!OpenNextFile())
0072       {
0073         AllDone(1);
0074         return;
0075       }
0076       evt = GetEventiterator()->getNextEvent();
0077     }
0078     if (Verbosity() > 2)
0079     {
0080       std::cout << "Fetching next Event" << evt->getEvtSequence() << std::endl;
0081     }
0082     RunNumber(evt->getRunNumber());
0083     if (GetVerbosity() > 1)
0084     {
0085       evt->identify();
0086     }
0087     // not interested in special events, really
0088     if (evt->getEvtType() != DATAEVENT)
0089     {
0090       m_NumSpecialEvents++;
0091       if (evt->getEvtType() == ENDRUNEVENT)
0092       {
0093         std::cout << "End run flag for INTT found, remaining INTT data is corrupted" << std::endl;
0094         delete evt;
0095         AllDone(1);
0096         return;
0097       }
0098       delete evt;
0099       continue;
0100     }
0101 
0102     int EventSequence = evt->getEvtSequence();
0103     int npackets = evt->getPacketList(plist, 1);
0104 
0105     if (npackets > 1)
0106     {
0107       exit(1);
0108     }
0109     if (m_SkipEarlyEvents)
0110     {
0111       for (int i = 0; i < npackets; i++)
0112       {
0113         int numBCOs = plist[i]->iValue(0, "NR_BCOS");
0114         for (int j = 0; j < numBCOs; j++)
0115         {
0116           uint64_t bco = plist[i]->lValue(j, "BCOLIST");
0117           if (bco < minBCO)
0118           {
0119             continue;
0120           }
0121           m_SkipEarlyEvents = false;
0122         }
0123       }
0124     }
0125     if (m_SkipEarlyEvents)
0126     {
0127       for (int i = 0; i < npackets; i++)
0128       {
0129         delete plist[i];
0130       }
0131       delete evt;
0132       continue;
0133     }
0134     for (int i = 0; i < npackets; i++)
0135     {
0136       if (Verbosity() > 2)
0137       {
0138         plist[i]->identify();
0139       }
0140 
0141       if (poolmap.find(plist[i]->getIdentifier()) == poolmap.end())  // we haven't seen this one yet
0142       {
0143         if (Verbosity() > 1)
0144         {
0145           std::cout << "starting new intt pool for packet " << plist[i]->getIdentifier() << std::endl;
0146         }
0147         poolmap[plist[i]->getIdentifier()] = new intt_pool(1000, 100);
0148         poolmap[plist[i]->getIdentifier()]->Verbosity(Verbosity());
0149         poolmap[plist[i]->getIdentifier()]->Name(std::to_string(plist[i]->getIdentifier()));
0150       }
0151       poolmap[plist[i]->getIdentifier()]->addPacket(plist[i]);
0152 
0153       delete plist[i];
0154     }
0155 
0156     delete evt;
0157 
0158     for (auto iter : poolmap)
0159     {
0160       intt_pool *pool = iter.second;  // less typing
0161       auto packet_id = pool->getIdentifier();
0162       if (pool->depth_ok())
0163       {
0164         int num_hits = pool->iValue(0, "NR_HITS");
0165         if (Verbosity() > 1)
0166         {
0167           std::cout << "Number of Hits: " << num_hits << " for packet "
0168             << pool->getIdentifier() << std::endl;
0169         }
0170         if (Verbosity() > 2)
0171         {
0172           if(IsStandaloneMode())
0173           {
0174 
0175             std::cout<<"INTT Pool in Standalone mode "<<std::endl;
0176           }
0177           else
0178             std::cout<<"INTT Pool with GL1 BCO "<<std::endl;
0179         }
0180         int numBCOs = pool->iValue(0, "NR_BCOS");
0181         uint64_t largest_bco = 0;
0182         bool skipthis{true};
0183 
0184         for (int j = 0; j < numBCOs; j++)
0185         {
0186           uint64_t bco = pool->lValue(j, "BCOLIST");
0187           if (largest_bco < bco)
0188           {
0189             largest_bco = bco;
0190           }
0191           if (bco < minBCO)
0192           {
0193             continue;
0194           }
0195           if(!IsStandaloneMode() && bco > minBCO * 2)
0196           {
0197             continue;
0198           }
0199           skipthis = false;
0200           m_BclkStack.insert(bco);
0201           m_BclkStackPacketMap[packet_id].insert(bco);
0202         }
0203 
0204         int nFEEs = pool->iValue(0, "UNIQUE_FEES");
0205         for (int j = 0; j < nFEEs; j++)
0206         {
0207           int fee = pool->iValue(j, "FEE_ID");
0208           int nbcos = pool->iValue(fee, "FEE_BCOS");
0209           for (int k = 0; k < nbcos; k++)
0210           {
0211             uint64_t bco = pool->lValue(fee, k, "BCOVAL");
0212             if(bco < minBCO)
0213             {
0214               continue;
0215             }
0216             if(!IsStandaloneMode() && bco > minBCO * 2)
0217             {
0218               continue;
0219             }
0220             m_FeeGTML1BCOMap[fee].insert(bco);
0221           }
0222         }
0223         if (skipthis)
0224         {
0225           if (Verbosity() > 1)
0226           {
0227             std::cout << "largest bco: 0x" << std::hex << largest_bco << ", minbco 0x" << minBCO
0228                       << std::dec << ", evtno: " << EventSequence << std::endl;
0229           }
0230         }
0231         else
0232         {
0233           for (int j = 0; j < num_hits; j++)
0234           {
0235             uint64_t gtm_bco = pool->lValue(j, "BCO");
0236             if (gtm_bco < minBCO)
0237             {
0238               // std::cout << "dropping hit with bco 0x" << std::hex
0239               //          << gtm_bco << ", min bco: 0x" << minBCO
0240               //          << std::endl;
0241               continue;
0242             }
0243             if(!IsStandaloneMode() && gtm_bco > minBCO * 2)
0244             {
0245               continue;
0246             }
0247             auto newhit = std::make_unique<InttRawHitv2>();
0248             int FEE = pool->iValue(j, "FEE");
0249             newhit->set_packetid(pool->getIdentifier());
0250             newhit->set_fee(FEE);
0251             newhit->set_bco(gtm_bco);
0252             newhit->set_adc(pool->iValue(j, "ADC"));
0253             newhit->set_amplitude(pool->iValue(j, "AMPLITUDE"));
0254             newhit->set_chip_id(pool->iValue(j, "CHIP_ID"));
0255             newhit->set_channel_id(pool->iValue(j, "CHANNEL_ID"));
0256             newhit->set_word(pool->iValue(j, "DATAWORD"));
0257             newhit->set_FPHX_BCO(pool->iValue(j, "FPHX_BCO"));
0258             newhit->set_full_FPHX(pool->iValue(j, "FULL_FPHX"));
0259             newhit->set_full_ROC(pool->iValue(j, "FULL_ROC"));
0260             newhit->set_event_counter(pool->iValue(j, "EVENT_COUNTER"));
0261             gtm_bco += m_Rollover[FEE];
0262 
0263             if (gtm_bco < m_PreviousClock[FEE])
0264             {
0265               m_Rollover[FEE] += 0x10000000000;
0266               gtm_bco += 0x10000000000;  // rollover makes sure our bclks are ascending even if we roll over the 40 bit counter
0267             }
0268             m_PreviousClock[FEE] = gtm_bco;
0269             m_BeamClockFEE[gtm_bco].insert(FEE);
0270             m_FEEBclkMap[FEE] = gtm_bco;
0271             if (Verbosity() > 2)
0272             {
0273               std::cout << "evtno: " << EventSequence
0274                 << ", hits: " << j
0275                 << ", nr_hits: " << num_hits
0276                 << ", FEE: " << FEE
0277                 << ", bco: 0x" << std::hex << gtm_bco << std::dec
0278                 << ", min bco: 0x" << std::hex << minBCO << std::dec
0279                 << ", channel: " << newhit->get_channel_id()
0280                 << ", evt_counter: " << newhit->get_event_counter() << std::endl;
0281             }
0282             if (StreamingInputManager())
0283             {
0284               StreamingInputManager()->AddInttRawHit(gtm_bco, newhit.get());
0285             }
0286             m_InttRawHitMap[gtm_bco].push_back(newhit.release());
0287           }
0288         }
0289         //      Print("FEEBCLK");
0290       }
0291       pool->next();
0292     }
0293   }
0294 }
0295 
0296 void SingleInttPoolInput::Print(const std::string &what) const
0297 {
0298   if (what == "ALL" || what == "FEE")
0299   {
0300     for (const auto &bcliter : m_BeamClockFEE)
0301     {
0302       std::cout << "Beam clock 0x" << std::hex << bcliter.first << std::dec << std::endl;
0303       for (auto feeiter : bcliter.second)
0304       {
0305         std::cout << "FEM: " << feeiter << std::endl;
0306       }
0307     }
0308   }
0309   if (what == "ALL" || what == "FEEBCLK")
0310   {
0311     std::cout << "Printing last beamclock for every FEE" << std::endl;
0312     for (auto bcliter : m_FEEBclkMap)
0313     {
0314       std::cout << "FEE" << bcliter.first << " bclk: 0x"
0315                 << std::hex << bcliter.second << std::dec << std::endl;
0316     }
0317   }
0318   if (what == "ALL" || what == "STORAGE")
0319   {
0320     for (const auto &bcliter : m_InttRawHitMap)
0321     {
0322       std::cout << "Beam clock 0x" << std::hex << bcliter.first << std::dec << std::endl;
0323       for (auto feeiter : bcliter.second)
0324       {
0325         std::cout << "fee: " << feeiter->get_fee()
0326                   << " at " << std::hex << feeiter << std::dec << std::endl;
0327       }
0328     }
0329   }
0330   if (what == "ALL" || what == "STACK")
0331   {
0332     for (auto &[packetid, bclkstack] : m_BclkStackPacketMap)
0333     {
0334       for (auto &bclk : bclkstack)
0335       {
0336         std::cout << "stacked bclk: 0x" << std::hex << bclk << std::dec << std::endl;
0337       }
0338     }
0339     for (auto iter : m_BclkStack)
0340     {
0341       std::cout << "stacked bclk: 0x" << std::hex << iter << std::dec << std::endl;
0342     }
0343   }
0344 }
0345 
0346 void SingleInttPoolInput::CleanupUsedPackets(const uint64_t bclk)
0347 {
0348   m_BclkStack.erase(m_BclkStack.begin(), m_BclkStack.upper_bound(bclk));
0349   m_BeamClockFEE.erase(m_BeamClockFEE.begin(), m_BeamClockFEE.upper_bound(bclk));
0350   for(auto it = m_InttRawHitMap.begin(); it != m_InttRawHitMap.end() && (it->first <= bclk); it = m_InttRawHitMap.erase(it))
0351   {
0352     for( const auto& rawhit : it->second)
0353     {
0354       delete rawhit;
0355     }
0356   }
0357   m_InttRawHitMap.erase(m_InttRawHitMap.begin(), m_InttRawHitMap.upper_bound(bclk));
0358 }
0359 
0360 bool SingleInttPoolInput::CheckPoolDepth(const uint64_t bclk)
0361 {
0362   for (auto iter : m_FEEBclkMap)
0363   {
0364     if (Verbosity() > 2)
0365     {
0366       std::cout << "my bclk 0x" << std::hex << iter.second
0367                 << " req: 0x" << bclk << std::dec << std::endl;
0368     }
0369     if (iter.second < bclk)
0370     {
0371       if (Verbosity() > 1)
0372       {
0373         std::cout << "FEE " << iter.first << " beamclock 0x" << std::hex << iter.second
0374                   << " smaller than req bclk: 0x" << bclk << std::dec << std::endl;
0375       }
0376       return false;
0377     }
0378   }
0379   return true;
0380 }
0381 
0382 void SingleInttPoolInput::ClearCurrentEvent()
0383 {
0384   // called interactively, to get rid of the current event
0385   uint64_t currentbclk = *(m_BclkStackPacketMap.begin()->second).begin();
0386   //  std::cout << "clearing bclk 0x" << std::hex << currentbclk << std::dec << std::endl;
0387   CleanupUsedPackets(currentbclk);
0388   // m_BclkStack.erase(currentbclk);
0389   // m_BeamClockFEE.erase(currentbclk);
0390   return;
0391 }
0392 
0393 bool SingleInttPoolInput::GetSomeMoreEvents(const uint64_t ibclk)
0394 {
0395   if (AllDone())
0396   {
0397     return false;
0398   }
0399   if (poolmap.empty())
0400   {
0401     //      std::cout << "GetSomeMoreEvents poolmap empty, ret true" << std::endl;
0402     return true;
0403   }
0404   // for (auto iter : poolmap)
0405   // {
0406   //   if (!iter.second->depth_ok())
0407   //   {
0408   //   std::cout << "GetSomeMoreEvents depth not ok, ret true" << std::endl;
0409   //    return true;
0410   //   }
0411   // }
0412   uint64_t localbclk = ibclk;
0413   if (ibclk == 0)
0414   {
0415     if (m_InttRawHitMap.empty())
0416     {
0417       //      std::cout << "GetSomeMoreEvents hitmap empty, ret true" << std::endl;
0418       return true;
0419     }
0420     localbclk = m_InttRawHitMap.begin()->first;
0421   }
0422 
0423   std::set<int> toerase;
0424   for (auto bcliter : m_FEEBclkMap)
0425   {
0426     if (bcliter.second <= localbclk)
0427     {
0428       uint64_t highest_bclk = m_InttRawHitMap.rbegin()->first;
0429       if ((highest_bclk - m_InttRawHitMap.begin()->first) < MaxBclkDiff())
0430       {
0431         // std::cout << "FEE " << bcliter.first << " bclk: "
0432         //      << std::hex << bcliter.second << ", req: " << localbclk
0433         //      << std::dec << std::endl;
0434         return true;
0435       }
0436       else
0437       {
0438         std::cout << PHWHERE << Name() << ": erasing FEE " << bcliter.first
0439                   << " with stuck bclk: 0x" << std::hex << bcliter.second
0440                   << " current bco range: 0x" << m_InttRawHitMap.begin()->first
0441                   << ", to: 0x" << highest_bclk << ", delta: " << std::dec
0442                   << (highest_bclk - m_InttRawHitMap.begin()->first)
0443                   << std::dec << std::endl;
0444         toerase.insert(bcliter.first);
0445       }
0446     }
0447   }
0448   for (auto iter : toerase)
0449   {
0450     m_FEEBclkMap.erase(iter);
0451   }
0452   //  std::cout << "GetSomeMoreEvents ret false" << std::endl;
0453   return false;
0454 }
0455 
0456 void SingleInttPoolInput::CreateDSTNode(PHCompositeNode *topNode)
0457 {
0458   PHNodeIterator iter(topNode);
0459   PHCompositeNode *dstNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "DST"));
0460   if (!dstNode)
0461   {
0462     dstNode = new PHCompositeNode("DST");
0463     topNode->addNode(dstNode);
0464   }
0465   PHNodeIterator iterDst(dstNode);
0466   PHCompositeNode *detNode = dynamic_cast<PHCompositeNode *>(iterDst.findFirst("PHCompositeNode", "INTT"));
0467   if (!detNode)
0468   {
0469     detNode = new PHCompositeNode("INTT");
0470     dstNode->addNode(detNode);
0471   }
0472   InttRawHitContainer *intthitcont = findNode::getClass<InttRawHitContainer>(detNode, m_rawHitContainerName);
0473   if (!intthitcont)
0474   {
0475     intthitcont = new InttRawHitContainerv2();
0476     PHIODataNode<PHObject> *newNode = new PHIODataNode<PHObject>(intthitcont, m_rawHitContainerName, "PHObject");
0477     detNode->addNode(newNode);
0478   }
0479 }
0480 //_______________________________________________________
0481 
0482 void SingleInttPoolInput::ConfigureStreamingInputManager()
0483 {
0484   if (StreamingInputManager())
0485   {
0486     auto rc = recoConsts::instance();
0487     // if it is triggered after the gtm firmware change
0488     if(rc->get_IntFlag("RUNNUMBER") > 58677 && m_BcoRange < 5)
0489     {
0490       SetBcoRange(3);
0491       std::cout << "INTT changed to triggered event combining with range [-"
0492                 << m_NegativeBco << "," << m_BcoRange << "]" << std::endl;
0493     }
0494 
0495     StreamingInputManager()->SetInttBcoRange(m_BcoRange);
0496     StreamingInputManager()->SetInttNegativeBco(m_NegativeBco);
0497   }
0498 }