Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-12-17 09:19:45

0001 #include "Fun4AllStreamingInputManager.h"
0002 
0003 #include "InputManagerType.h"
0004 #include "MvtxRawDefs.h"
0005 #include "SingleMicromegasPoolInput.h"
0006 #include "SingleMicromegasPoolInput_v2.h"
0007 #include "SingleMvtxPoolInput.h"
0008 #include "SingleStreamingInput.h"
0009 
0010 #include <ffarawobjects/Gl1Packet.h>
0011 #include <ffarawobjects/InttRawHit.h>
0012 #include <ffarawobjects/InttRawHitContainer.h>
0013 #include <ffarawobjects/MicromegasRawHit.h>
0014 #include <ffarawobjects/MicromegasRawHitContainer.h>
0015 #include <ffarawobjects/MvtxFeeIdInfov1.h>
0016 #include <ffarawobjects/MvtxRawEvtHeader.h>
0017 #include <ffarawobjects/MvtxRawHit.h>
0018 #include <ffarawobjects/MvtxRawHitContainer.h>
0019 #include <ffarawobjects/TpcRawHit.h>
0020 #include <ffarawobjects/TpcRawHitContainer.h>
0021 
0022 #include <fun4all/Fun4AllInputManager.h>  // for Fun4AllInputManager
0023 #include <fun4all/Fun4AllReturnCodes.h>
0024 #include <fun4all/Fun4AllServer.h>
0025 #include <fun4all/Fun4AllSyncManager.h>
0026 
0027 #include <ffaobjects/SyncObject.h>  // for SyncObject
0028 #include <ffaobjects/SyncObjectv1.h>
0029 
0030 #include <qautils/QAHistManagerDef.h>
0031 #include <qautils/QAUtil.h>
0032 
0033 #include <phool/PHObject.h>  // for PHObject
0034 #include <phool/getClass.h>
0035 #include <phool/phool.h>  // for PHWHERE
0036 #include <boost/format.hpp>
0037 
0038 #include <TH1.h>
0039 #include <TH2.h>
0040 #include <TSystem.h>
0041 
0042 #include <algorithm>  // for max
0043 #include <cassert>
0044 #include <cstdint>  // for uint64_t, uint16_t
0045 #include <cstdlib>
0046 #include <format>
0047 #include <iostream>  // for operator<<, basic_ostream, endl
0048 #include <utility>   // for pair
0049 
0050 Fun4AllStreamingInputManager::Fun4AllStreamingInputManager(const std::string &name, const std::string &dstnodename, const std::string &topnodename)
0051   : Fun4AllInputManager(name, dstnodename, topnodename)
0052   , m_SyncObject(new SyncObjectv1())
0053 {
0054   Fun4AllServer *se = Fun4AllServer::instance();
0055   m_topNode = se->topNode(TopNodeName());
0056 
0057   createQAHistos();
0058 
0059   return;
0060 }
0061 
0062 Fun4AllStreamingInputManager::~Fun4AllStreamingInputManager()
0063 {
0064   if (IsOpen())
0065   {
0066     fileclose();
0067   }
0068   delete m_SyncObject;
0069   // clear leftover raw event maps and vectors with poolreaders
0070   // GL1
0071   for (auto *iter : m_Gl1InputVector)
0072   {
0073     delete iter;
0074   }
0075 
0076   m_Gl1InputVector.clear();
0077 
0078   // MVTX
0079   for (auto const &mapiter : m_MvtxRawHitMap)
0080   {
0081     for (auto *mvtxhititer : mapiter.second.MvtxRawHitVector)
0082     {
0083       delete mvtxhititer;
0084     }
0085     for (auto *mvtxFeeIdInfo : mapiter.second.MvtxFeeIdInfoVector)
0086     {
0087       delete mvtxFeeIdInfo;
0088     }
0089   }
0090   m_MvtxRawHitMap.clear();
0091 
0092   for (auto *iter : m_MvtxInputVector)
0093   {
0094     delete iter;
0095   }
0096   m_MvtxInputVector.clear();
0097 
0098   // INTT
0099   for (auto const &mapiter : m_InttRawHitMap)
0100   {
0101     for (auto *intthititer : mapiter.second.InttRawHitVector)
0102     {
0103       delete intthititer;
0104     }
0105   }
0106   m_InttRawHitMap.clear();
0107 
0108   for (auto *iter : m_InttInputVector)
0109   {
0110     delete iter;
0111   }
0112   m_InttInputVector.clear();
0113 
0114   // TPC
0115   for (auto const &mapiter : m_TpcRawHitMap)
0116   {
0117     for (auto *tpchititer : mapiter.second.TpcRawHitVector)
0118     {
0119       delete tpchititer;
0120     }
0121   }
0122 
0123   m_TpcRawHitMap.clear();
0124   for (auto *iter : m_TpcInputVector)
0125   {
0126     delete iter;
0127   }
0128   m_TpcInputVector.clear();
0129 
0130   // Micromegas
0131 
0132   for (auto const &mapiter : m_MicromegasRawHitMap)
0133   {
0134     for (auto *micromegashititer : mapiter.second.MicromegasRawHitVector)
0135     {
0136       delete micromegashititer;
0137     }
0138   }
0139   for (auto *iter : m_MicromegasInputVector)
0140   {
0141     delete iter;
0142   }
0143 
0144   m_MicromegasInputVector.clear();
0145 }
0146 
0147 int Fun4AllStreamingInputManager::run(const int /*nevents*/)
0148 {
0149   int iret = 0;
0150   if (m_gl1_registered_flag)  // Gl1 first to get the reference
0151   {
0152     iret += FillGl1();
0153   }
0154   if (m_intt_registered_flag)
0155   {
0156     iret += FillIntt();
0157   }
0158   if (m_mvtx_registered_flag)
0159   {
0160     iret += FillMvtx();
0161   }
0162   if (m_tpc_registered_flag)
0163   {
0164     iret += FillTpc();
0165   }
0166 
0167   if (m_micromegas_registered_flag)
0168   {
0169     iret += FillMicromegas();
0170   }
0171 
0172   // std::cout << "size  m_InttRawHitMap: " <<  m_InttRawHitMap.size()
0173   //        << std::endl;
0174   return iret;
0175   // readagain:
0176   //   if (!IsOpen())
0177   //   {
0178   //     if (FileListEmpty())
0179   //     {
0180   //       if (Verbosity() > 0)
0181   //       {
0182   //         std::cout << Name() << ": No Input file open" << std::endl;
0183   //       }
0184   //       return -1;
0185   //     }
0186   //     else
0187   //     {
0188   //       if (OpenNextFile())
0189   //       {
0190   //         std::cout << Name() << ": No Input file from filelist opened" << std::endl;
0191   //         return -1;
0192   //       }
0193   //     }
0194   //   }
0195   //   if (Verbosity() > 3)
0196   //   {
0197   //     std::cout << "Getting Event from " << Name() << std::endl;
0198   //   }
0199   // // Fill Event combiner
0200   //   unsigned int watermark = m_EventCombiner.size();
0201   //   if (watermark < m_LowWaterMark)
0202   //   {
0203   //     for (unsigned int i = watermark; i < m_CombinerDepth; i++)
0204   //     {
0205   //       Event *evt = m_EventIterator->getNextEvent();
0206   //       std::cout << "Filling combiner with event " << evt->getEvtSequence() << std::endl;
0207   //       m_EventCombiner.insert(std::make_pair(evt->getEvtSequence(), evt));
0208   //     }
0209   //   }
0210   //   //  std::cout << "running event " << nevents << std::endl;
0211   //   PHNodeIterator iter(m_topNode);
0212   //   PHDataNode<Event> *EvtNode = dynamic_cast<PHDataNode<Event> *>(iter.findFirst("PHDataNode", m_EvtNodeName));
0213   //   if (m_SaveEvent)  // if an event was pushed back, copy saved pointer and reset m_SaveEvent pointer
0214   //   {
0215   //     m_Event = m_SaveEvent;
0216   //     m_SaveEvent = nullptr;
0217   //     m_EventsThisFile--;
0218   //     m_EventsTotal--;
0219   //   }
0220   //   else
0221   //   {
0222   //     m_Event = m_EventCombiner.begin()->second;
0223   //   }
0224   //   EvtNode->setData(m_Event);
0225   //   if (!m_Event)
0226   //   {
0227   //     fileclose();
0228   //     goto readagain;
0229   //   }
0230   //   if (Verbosity() > 1)
0231   //   {
0232   //     std::cout << Name() << " EVT run " << m_Event->getRunNumber() << ", evt no: " << m_Event->getEvtSequence() << std::endl;
0233   //   }
0234   //   m_EventsTotal++;
0235   //   m_EventsThisFile++;
0236   //   SetRunNumber(m_Event->getRunNumber());
0237   //   MySyncManager()->EvtEvents(m_EventsThisFile);
0238   //   MySyncManager()->SegmentNumber(m_Segment);
0239   //   MySyncManager()->CurrentEvent(m_Event->getEvtSequence());
0240   //   m_SyncObject->EventCounter(m_EventsThisFile);
0241   //   m_SyncObject->SegmentNumber(m_Segment);
0242   //   m_SyncObject->RunNumber(m_Event->getRunNumber());
0243   //   m_SyncObject->EventNumber(m_Event->getEvtSequence());
0244   //   // check if the local SubsysReco discards this event
0245   //   if (RejectEvent() != Fun4AllReturnCodes::EVENT_OK)
0246   //   {
0247   //     ResetEvent();
0248   //     goto readagain;
0249   //   }
0250   //  return 0;
0251 }
0252 
0253 int Fun4AllStreamingInputManager::fileclose()
0254 {
0255   return 0;
0256 }
0257 
0258 void Fun4AllStreamingInputManager::Print(const std::string &what) const
0259 {
0260   if (what == "TPC")
0261   {
0262     for (const auto &iter : m_TpcRawHitMap)
0263     {
0264       std::cout << "bco: " << std::hex << iter.first << std::dec << std::endl;
0265       for (const auto &itervec : iter.second.TpcRawHitVector)
0266       {
0267         std::cout << "hit: " << std::hex << itervec << std::dec << std::endl;
0268         itervec->identify();
0269       }
0270     }
0271   }
0272   if (what == "ALL" || what == "INPUTFILES")
0273   {
0274     std::cout << "-----------------------------" << std::endl;
0275     for (const auto &iter : m_Gl1InputVector)
0276     {
0277       std::cout << "Single Streaming Input Manager " << iter->Name() << " reads run "
0278                 << iter->RunNumber()
0279                 << " from file " << iter->FileName()
0280                 << std::endl;
0281     }
0282     for (const auto &iter : m_MvtxInputVector)
0283     {
0284       std::cout << "Single Streaming Input Manager " << iter->Name() << " reads run "
0285                 << iter->RunNumber()
0286                 << " from file " << iter->FileName()
0287                 << std::endl;
0288     }
0289     for (const auto &iter : m_InttInputVector)
0290     {
0291       std::cout << "Single Streaming Input Manager " << iter->Name() << " reads run "
0292                 << iter->RunNumber()
0293                 << " from file " << iter->FileName()
0294                 << std::endl;
0295     }
0296     for (const auto &iter : m_TpcInputVector)
0297     {
0298       std::cout << "Single Streaming Input Manager " << iter->Name() << " reads run "
0299                 << iter->RunNumber()
0300                 << " from file " << iter->FileName()
0301                 << std::endl;
0302     }
0303     for (const auto &iter : m_MicromegasInputVector)
0304     {
0305       std::cout << "Single Streaming Input Manager " << iter->Name() << " reads run "
0306                 << iter->RunNumber()
0307                 << " from file " << iter->FileName()
0308                 << std::endl;
0309     }
0310   }
0311   Fun4AllInputManager::Print(what);
0312   return;
0313 }
0314 
0315 int Fun4AllStreamingInputManager::ResetEvent()
0316 {
0317   // for (auto iter : m_EvtInputVector)
0318   // {
0319   //   iter->CleanupUsedPackets(m_CurrentBeamClock);
0320   // }
0321   //  m_SyncObject->Reset();
0322   m_RefBCO = 0;
0323   return 0;
0324 }
0325 
0326 int Fun4AllStreamingInputManager::PushBackEvents(const int /*i*/)
0327 {
0328   return 0;
0329   // PushBackEvents is supposedly pushing events back on the stack which works
0330   // easily with root trees (just grab a different entry) but hard in these HepMC ASCII files.
0331   // A special case is when the synchronization fails and we need to only push back a single
0332   // event. In this case we save the m_Event pointer as m_SaveEvent which is used in the run method
0333   // instead of getting the next event.
0334   // if (i > 0)
0335   // {
0336   //   if (i == 1 && m_Event)  // check on m_Event pointer makes sure it is not done from the cmd line
0337   //   {
0338   //     m_SaveEvent = m_Event;
0339   //     return 0;
0340   //   }
0341   //   std::cout << PHWHERE << Name()
0342   //        << " Fun4AllStreamingInputManager cannot push back " << i << " events into file"
0343   //        << std::endl;
0344   //   return -1;
0345   // }
0346   // if (!m_EventIterator)
0347   // {
0348   //   std::cout << PHWHERE << Name()
0349   //        << " no file open" << std::endl;
0350   //   return -1;
0351   // }
0352   // // Skipping events is implemented as
0353   // // pushing a negative number of events on the stack, so in order to implement
0354   // // the skipping of events we read -i events.
0355   // int nevents = -i;  // negative number of events to push back -> skip num events
0356   // int errorflag = 0;
0357   // while (nevents > 0 && !errorflag)
0358   // {
0359   //   m_Event = m_EventIterator->getNextEvent();
0360   //   if (!m_Event)
0361   //   {
0362   //     std::cout << "Error after skipping " << i - nevents
0363   //          << " file exhausted?" << std::endl;
0364   //     errorflag = -1;
0365   //     fileclose();
0366   //   }
0367   //   else
0368   //   {
0369   //     if (Verbosity() > 3)
0370   //     {
0371   //       std::cout << "Skipping evt no: " << m_Event->getEvtSequence() << std::endl;
0372   //     }
0373   //   }
0374   //   delete m_Event;
0375   //   m_Event = nullptr;
0376   //   nevents--;
0377   // }
0378   // return errorflag;
0379 }
0380 
0381 int Fun4AllStreamingInputManager::GetSyncObject(SyncObject **mastersync)
0382 {
0383   // here we copy the sync object from the current file to the
0384   // location pointed to by mastersync. If mastersync is a 0 pointer
0385   // the syncobject is cloned. If mastersync allready exists the content
0386   // of syncobject is copied
0387   if (!(*mastersync))
0388   {
0389     if (m_SyncObject)
0390     {
0391       *mastersync = dynamic_cast<SyncObject *>(m_SyncObject->CloneMe());
0392       assert(*mastersync);
0393     }
0394   }
0395   else
0396   {
0397     *(*mastersync) = *m_SyncObject;  // copy syncobject content
0398   }
0399   return Fun4AllReturnCodes::SYNC_OK;
0400 }
0401 
0402 int Fun4AllStreamingInputManager::SyncIt(const SyncObject *mastersync)
0403 {
0404   if (!mastersync)
0405   {
0406     std::cout << PHWHERE << Name() << " No MasterSync object, cannot perform synchronization" << std::endl;
0407     std::cout << "Most likely your first file does not contain a SyncObject and the file" << std::endl;
0408     std::cout << "opened by the Fun4AllDstInputManager with Name " << Name() << " has one" << std::endl;
0409     std::cout << "Change your macro and use the file opened by this input manager as first input" << std::endl;
0410     std::cout << "and you will be okay. Fun4All will not process the current configuration" << std::endl
0411               << std::endl;
0412     return Fun4AllReturnCodes::SYNC_FAIL;
0413   }
0414   int iret = m_SyncObject->Different(mastersync);
0415   if (iret)
0416   {
0417     std::cout << "big problem" << std::endl;
0418     exit(1);
0419   }
0420   return Fun4AllReturnCodes::SYNC_OK;
0421 }
0422 
0423 std::string Fun4AllStreamingInputManager::GetString(const std::string &what) const
0424 {
0425   std::cout << PHWHERE << " called with " << what << " , returning empty string" << std::endl;
0426   return "";
0427 }
0428 
0429 void Fun4AllStreamingInputManager::registerStreamingInput(SingleStreamingInput *evtin, InputManagerType::enu_subsystem system)
0430 {
0431   evtin->StreamingInputManager(this);
0432   // if the streaming flag is set, we only want the first event from the GL1 to
0433   // get the starting BCO of that run which enables us to dump all the junk which
0434   // is taken before the run starts in the streaming systems. But we don't want the
0435   // GL1 in the output, so we do not create its dst node if running in streaming
0436   if (system == InputManagerType::GL1)
0437   {
0438     if (!m_StreamingFlag)
0439     {
0440       evtin->CreateDSTNode(m_topNode);
0441     }
0442   }
0443   else
0444   {
0445     evtin->CreateDSTNode(m_topNode);
0446   }
0447   evtin->ConfigureStreamingInputManager();
0448   switch (system)
0449   {
0450   case InputManagerType::MVTX:
0451     m_mvtx_registered_flag = true;
0452     m_MvtxInputVector.push_back(evtin);
0453     break;
0454   case InputManagerType::INTT:
0455     m_intt_registered_flag = true;
0456     m_InttInputVector.push_back(evtin);
0457     break;
0458   case InputManagerType::TPC:
0459     m_tpc_registered_flag = true;
0460     m_TpcInputVector.push_back(evtin);
0461     break;
0462   case InputManagerType::MICROMEGAS:
0463     m_micromegas_registered_flag = true;
0464     evtin->createQAHistos();
0465     m_MicromegasInputVector.push_back(evtin);
0466     break;
0467   case InputManagerType::GL1:
0468     m_gl1_registered_flag = true;
0469     m_Gl1InputVector.push_back(evtin);
0470     break;
0471   default:
0472     std::cout << "invalid subsystem flag " << system << std::endl;
0473     gSystem->Exit(1);
0474     exit(1);
0475   }
0476   if (Verbosity() > 3)
0477   {
0478     std::cout << "registering " << evtin->Name()
0479               << " number of registered inputs: "
0480               << m_Gl1InputVector.size() + m_InttInputVector.size() + m_MicromegasInputVector.size() + m_MvtxInputVector.size() + m_TpcInputVector.size()
0481               << std::endl;
0482   }
0483 }
0484 
0485 void Fun4AllStreamingInputManager::AddGl1RawHit(uint64_t bclk, Gl1Packet *hit)
0486 {
0487   if (Verbosity() > 1)
0488   {
0489     std::cout << "Adding gl1 hit to bclk 0x"
0490               << std::hex << bclk << std::dec << std::endl;
0491   }
0492   m_Gl1RawHitMap[bclk].Gl1RawHitVector.push_back(hit);
0493 }
0494 
0495 void Fun4AllStreamingInputManager::AddMvtxRawHit(uint64_t bclk, MvtxRawHit *hit)
0496 {
0497   if (Verbosity() > 1)
0498   {
0499     std::cout << "Adding mvtx hit to bclk 0x"
0500               << std::hex << bclk << std::dec << std::endl;
0501   }
0502   m_MvtxRawHitMap[bclk].MvtxRawHitVector.push_back(hit);
0503 }
0504 
0505 void Fun4AllStreamingInputManager::AddMvtxFeeIdInfo(uint64_t bclk, uint16_t feeid, uint32_t detField)
0506 {
0507   if (Verbosity() > 1)
0508   {
0509     std::cout << "Adding mvtx feeid info to bclk 0x"
0510               << std::hex << bclk << std::dec << std::endl;
0511   }
0512   MvtxFeeIdInfo *feeidInfo = new MvtxFeeIdInfov1();
0513   feeidInfo->set_bco(bclk);
0514   feeidInfo->set_feeId(feeid);
0515   feeidInfo->set_detField(detField);
0516   m_MvtxRawHitMap[bclk].MvtxFeeIdInfoVector.push_back(feeidInfo);
0517 }
0518 
0519 void Fun4AllStreamingInputManager::AddMvtxL1TrgBco(uint64_t bclk, uint64_t lv1Bco)
0520 {
0521   if (Verbosity() > 1)
0522   {
0523     std::cout << "Adding mvtx L1Trg to bclk 0x"
0524               << std::hex << bclk << std::dec << std::endl;
0525   }
0526   m_MvtxRawHitMap[bclk].MvtxL1TrgBco.insert(lv1Bco);
0527 }
0528 
0529 void Fun4AllStreamingInputManager::AddInttRawHit(uint64_t bclk, InttRawHit *hit)
0530 {
0531   if (Verbosity() > 1)
0532   {
0533     std::cout << "Adding intt hit to bclk 0x"
0534               << std::hex << bclk << std::dec << std::endl;
0535   }
0536   m_InttRawHitMap[bclk].InttRawHitVector.push_back(hit);
0537   m_InttPacketFeeBcoMap[hit->get_packetid()][hit->get_fee()] = bclk;
0538 }
0539 
0540 void Fun4AllStreamingInputManager::AddMicromegasRawHit(uint64_t bclk, MicromegasRawHit *hit)
0541 {
0542   if (Verbosity() > 1)
0543   {
0544     std::cout << "Adding micromegas hit to bclk 0x"
0545               << std::hex << bclk << std::dec << std::endl;
0546   }
0547   m_MicromegasRawHitMap[bclk].MicromegasRawHitVector.push_back(hit);
0548 }
0549 
0550 void Fun4AllStreamingInputManager::AddTpcRawHit(uint64_t bclk, TpcRawHit *hit)
0551 {
0552   if (Verbosity() > 1)
0553   {
0554     std::cout << "Adding tpc hit to bclk 0x"
0555               << std::hex << bclk << std::dec << std::endl;
0556   }
0557   m_TpcRawHitMap[bclk].TpcRawHitVector.push_back(hit);
0558 }
0559 
0560 int Fun4AllStreamingInputManager::FillGl1()
0561 {
0562   // unsigned int alldone = 0;
0563   for (auto *iter : m_Gl1InputVector)
0564   {
0565     if (Verbosity() > 0)
0566     {
0567       std::cout << "Fun4AllStreamingInputManager::FillGl1 - fill pool for " << iter->Name() << std::endl;
0568     }
0569     iter->FillPool();
0570     if (m_RunNumber == 0)
0571     {
0572       m_RunNumber = iter->RunNumber();
0573       SetRunNumber(m_RunNumber);
0574     }
0575     else
0576     {
0577       if (m_RunNumber != iter->RunNumber())
0578       {
0579         std::cout << PHWHERE << " Run Number mismatch, run is "
0580                   << m_RunNumber << ", " << iter->Name() << " reads "
0581                   << iter->RunNumber() << std::endl;
0582         std::cout << "You are likely reading files from different runs, do not do that" << std::endl;
0583         Print("INPUTFILES");
0584         gSystem->Exit(1);
0585         exit(1);
0586       }
0587     }
0588   }
0589   if (m_Gl1RawHitMap.empty())
0590   {
0591     std::cout << "Gl1RawHitMap is empty - we are done" << std::endl;
0592     return -1;
0593   }
0594   //    std::cout << "stashed gl1 BCOs: " << m_Gl1RawHitMap.size() << std::endl;
0595   Gl1Packet *gl1packet = findNode::getClass<Gl1Packet>(m_topNode, "GL1RAWHIT");
0596   //  std::cout << "before filling m_Gl1RawHitMap size: " <<  m_Gl1RawHitMap.size() << std::endl;
0597   for (auto *gl1hititer : m_Gl1RawHitMap.begin()->second.Gl1RawHitVector)
0598   {
0599     if (Verbosity() > 1)
0600     {
0601       gl1hititer->identify();
0602     }
0603     if (!m_StreamingFlag)  // if streaming flag is set, the gl1packet is a nullptr
0604     {
0605       gl1packet->FillFrom(gl1hititer);
0606       MySyncManager()->CurrentEvent(gl1packet->getEvtSequence());
0607       m_SyncObject->RunNumber(m_RunNumber);
0608       m_SyncObject->EventNumber(gl1packet->getEvtSequence());
0609       m_SyncObject->SegmentNumber(0);
0610     }
0611     m_RefBCO = gl1hititer->getBCO();
0612     m_RefBCO = m_RefBCO & 0xFFFFFFFFFFU;  // 40 bits (need to handle rollovers)
0613                                           //    std::cout << "BCOis " << std::hex << m_RefBCO << std::dec << std::endl;
0614   }
0615   // if we run streaming, we only need the first gl1 bco to skip over all the junk
0616   // which is taken before the daq actually starts. But once we have the first event
0617   // and set the refBCO to the beginning of the run, we don't want the gl1 anymore
0618   // so we delete its input manager(s) and unregister it
0619   // deleting it also deletes all its allocated memory, so we don't have to worry
0620   // about clearing all gl1 related maps
0621   if (m_StreamingFlag)
0622   {
0623     for (auto *iter : m_Gl1InputVector)
0624     {
0625       delete iter;
0626     }
0627     m_gl1_registered_flag = false;
0628     m_Gl1InputVector.clear();
0629   }
0630   else
0631   {
0632     for (auto *iter : m_Gl1InputVector)
0633     {
0634       iter->CleanupUsedPackets(m_Gl1RawHitMap.begin()->first);
0635     }
0636     m_Gl1RawHitMap.begin()->second.Gl1RawHitVector.clear();
0637     m_Gl1RawHitMap.erase(m_Gl1RawHitMap.begin());
0638   }
0639   // std::cout << "size  m_Gl1RawHitMap: " <<  m_Gl1RawHitMap.size()
0640   //        << std::endl;
0641   return 0;
0642 }
0643 
0644 int Fun4AllStreamingInputManager::FillIntt()
0645 {
0646   int iret = FillInttPool();
0647   if (iret)
0648   {
0649     return iret;
0650   }
0651 
0652   // unsigned int alldone = 0;
0653   //     std::cout << "stashed intt BCOs: " << m_InttRawHitMap.size() << std::endl;
0654   InttRawHitContainer *inttcont = findNode::getClass<InttRawHitContainer>(m_topNode, "INTTRAWHIT");
0655   if (!inttcont)
0656   {
0657     inttcont = findNode::getClass<InttRawHitContainer>(m_topNode, (*(m_InttInputVector.begin()))->getHitContainerName());
0658     if (!inttcont)
0659     {
0660       std::cout << PHWHERE << "Could not find InttRawHitContainer node in topNode" << std::endl;
0661       gSystem->Exit(1);
0662       exit(1);
0663     }
0664   }
0665   //  std::cout << "before filling m_InttRawHitMap size: " <<  m_InttRawHitMap.size() << std::endl;
0666   // !m_InttRawHitMap.empty() is implicitely handled and the check is expensive
0667   // FillInttPool() contains this check already and will return non zero
0668   // so here m_InttRawHitMap will always contain entries
0669   uint64_t select_crossings = m_intt_bco_range;
0670   if (m_RefBCO == 0)
0671   {
0672     m_RefBCO = m_InttRawHitMap.begin()->first;
0673   }
0674   select_crossings += m_RefBCO;
0675   if (Verbosity() > 2)
0676   {
0677     std::cout << "select INTT crossings"
0678               << " from 0x" << std::hex << m_RefBCO - m_intt_negative_bco
0679               << " to 0x" << select_crossings - m_intt_negative_bco
0680               << " for ref BCO " << m_RefBCO
0681               << std::dec << std::endl;
0682   }
0683 
0684   while (m_InttRawHitMap.begin()->first < m_RefBCO - m_intt_negative_bco)
0685   {
0686     if (Verbosity() > 2)
0687     {
0688       std::cout << "Intt BCO: 0x" << std::hex << m_InttRawHitMap.begin()->first
0689                 << " corrected for negative offset: 0x" << m_InttRawHitMap.begin()->first + m_intt_negative_bco
0690                 << " smaller than GL1 BCO: 0x" << m_RefBCO
0691                 << " corrected for range: 0x" << select_crossings
0692                 << std::dec << " diff: " << (m_RefBCO - m_InttRawHitMap.begin()->first)
0693                 << ", ditching this bco" << std::dec << std::endl;
0694     }
0695     for (auto *iter : m_InttInputVector)
0696     {
0697       iter->CleanupUsedPackets(m_InttRawHitMap.begin()->first);
0698       iter->clearPacketBClkStackMap(m_InttRawHitMap.begin()->first);
0699       iter->clearFeeGTML1BCOMap(m_InttRawHitMap.begin()->first);
0700     }
0701 
0702     m_InttRawHitMap.begin()->second.InttRawHitVector.clear();
0703     m_InttRawHitMap.erase(m_InttRawHitMap.begin());
0704 
0705     iret = FillInttPool();
0706     if (iret)
0707     {
0708       return iret;
0709     }
0710   }
0711 
0712   unsigned int refbcobitshift = m_RefBCO & 0x3FU;
0713   bool allpackets = true;
0714   int allpacketsallfees = 0;
0715   for (auto &p : m_InttInputVector)
0716   {
0717     // this is on a per packet basis
0718     auto bcl_stack = p->BclkStackMap();
0719     auto feebclstack = p->getFeeGTML1BCOMap();
0720     int packet_id = bcl_stack.begin()->first;
0721     int histo_to_fill = (packet_id % 10) - 1;
0722 
0723     std::set<int> feeidset;
0724     int fee = 0;
0725     for (auto &[feeid, gtmbcoset] : feebclstack)
0726     {
0727       for (const auto &bcl : gtmbcoset)
0728       {
0729         auto diff = (m_RefBCO > bcl) ? m_RefBCO - bcl : bcl - m_RefBCO;
0730         h_bcodiff_intt[histo_to_fill]->Fill(feeid, diff);
0731         if (diff <= m_intt_bco_range)
0732         {  // diff is whatever the bco range is set as (2 for triggered, 120 for strobe)
0733           h_gl1taggedfee_intt[histo_to_fill][fee]->Fill(refbcobitshift);
0734           feeidset.insert(feeid);
0735           // this fee was tagged, go to the next one
0736           break;
0737         }
0738       }
0739       fee++;
0740     }
0741 
0742     if (feeidset.size() == 14)
0743     {
0744       allpacketsallfees++;
0745       h_taggedAllFees_intt[histo_to_fill]->Fill(refbcobitshift);
0746     }
0747     feeidset.clear();
0748     bool thispacket = false;
0749     h_refbco_intt[histo_to_fill]->Fill(refbcobitshift);
0750 
0751     for (auto &[packetid, gtmbcoset] : bcl_stack)
0752     {
0753       for (const auto &gtmbco : gtmbcoset)
0754       {
0755         auto diff = (m_RefBCO > gtmbco) ? m_RefBCO - gtmbco : gtmbco - m_RefBCO;
0756         if (diff < m_intt_bco_range)
0757         {
0758           thispacket = true;
0759           h_gl1tagged_intt[histo_to_fill]->Fill(refbcobitshift);
0760           break;
0761         }
0762       }
0763     }
0764 
0765     if (thispacket == false)
0766     {
0767       allpackets = false;
0768     }
0769   }
0770   if (allpackets)
0771   {
0772     h_taggedAll_intt->Fill(refbcobitshift);
0773   }
0774   if (allpacketsallfees == (int) m_InttInputVector.size())
0775   {
0776     h_taggedAllFee_intt->Fill(refbcobitshift);
0777   }
0778   while (m_InttRawHitMap.begin()->first <= select_crossings - m_intt_negative_bco)
0779   {
0780     for (auto *intthititer : m_InttRawHitMap.begin()->second.InttRawHitVector)
0781     {
0782       if (Verbosity() > 1)
0783       {
0784         std::cout << "Adding intt hit with bco 0x" << std::hex
0785                   << intthititer->get_bco() << std::dec << std::endl;
0786         //        intthititer->identify();
0787       }
0788       inttcont->AddHit(intthititer);
0789     }
0790     for (auto *iter : m_InttInputVector)
0791     {
0792       iter->CleanupUsedPackets(m_InttRawHitMap.begin()->first);
0793       if (m_intt_negative_bco < 2)  // triggered mode
0794       {
0795         iter->clearPacketBClkStackMap(m_InttRawHitMap.begin()->first);
0796         iter->clearFeeGTML1BCOMap(m_InttRawHitMap.begin()->first);
0797       }
0798     }
0799     m_InttRawHitMap.begin()->second.InttRawHitVector.clear();
0800     m_InttRawHitMap.erase(m_InttRawHitMap.begin());
0801     if (m_InttRawHitMap.empty())
0802     {
0803       break;
0804     }
0805   }
0806   return 0;
0807 }
0808 
0809 int Fun4AllStreamingInputManager::FillMvtx()
0810 {
0811   int iret = FillMvtxPool();
0812   if (iret)
0813   {
0814     return iret;
0815   }
0816 
0817   MvtxRawEvtHeader *mvtxEvtHeader = findNode::getClass<MvtxRawEvtHeader>(m_topNode, "MVTXRAWEVTHEADER");
0818   if (!mvtxEvtHeader)
0819   {
0820     mvtxEvtHeader = findNode::getClass<MvtxRawEvtHeader>(m_topNode, (static_cast<SingleMvtxPoolInput *>(*(m_MvtxInputVector.begin())))->getRawEventHeaderName());
0821     if (!mvtxEvtHeader)
0822     {
0823       std::cout << PHWHERE << "ERROR: MVTXRAWEVTHEADER node not found, exit. " << std::endl;
0824       gSystem->Exit(1);
0825       exit(1);
0826     }
0827   }
0828 
0829   MvtxRawHitContainer *mvtxcont = findNode::getClass<MvtxRawHitContainer>(m_topNode, "MVTXRAWHIT");
0830   if (!mvtxcont)
0831   {
0832     mvtxcont = findNode::getClass<MvtxRawHitContainer>(m_topNode, (*(m_MvtxInputVector.begin()))->getHitContainerName());
0833     if (!mvtxcont)
0834     {
0835       std::cout << PHWHERE << "ERROR: MVTXRAWHIT node not found, exit. " << std::endl;
0836       gSystem->Exit(1);
0837       exit(1);
0838     }
0839   }
0840   // std::cout << "before filling m_MvtxRawHitMap size: " <<  m_MvtxRawHitMap.size() << std::endl;
0841   uint64_t select_crossings = m_mvtx_is_triggered ? 0 : m_mvtx_bco_range;
0842   if (m_RefBCO == 0)
0843   {
0844     m_RefBCO = m_MvtxRawHitMap.begin()->first;
0845   }
0846   select_crossings += m_RefBCO;
0847 
0848   uint64_t ref_bco_minus_range = m_RefBCO < m_mvtx_bco_range ? 0 : m_RefBCO - m_mvtx_bco_range;
0849   if (Verbosity() > 2)
0850   {
0851     std::cout << "select MVTX crossings"
0852               << " from 0x" << std::hex << ref_bco_minus_range
0853               << " to 0x" << select_crossings - m_mvtx_bco_range
0854               << std::dec << std::endl;
0855   }
0856   // m_MvtxRawHitMap.empty() does not need to be checked here, FillMvtxPool returns non zero
0857   // if this map is empty which is handled above
0858   // All three values used in the while loop evaluation are unsigned ints. If m_RefBCO is < m_mvtx_bco_range then we will overflow and delete all hits
0859   while (m_MvtxRawHitMap.begin()->first < ref_bco_minus_range)
0860   {
0861     if (Verbosity() > 2)
0862     {
0863       std::cout << "ditching mvtx bco 0x" << std::hex << m_MvtxRawHitMap.begin()->first << ", ref: 0x" << m_RefBCO << std::dec << std::endl;
0864     }
0865     for (auto *iter : m_MvtxInputVector)
0866     {
0867       iter->CleanupUsedPackets(m_MvtxRawHitMap.begin()->first);
0868       iter->clearFeeGTML1BCOMap(m_MvtxRawHitMap.begin()->first);
0869     }
0870     for (auto *mvtxFeeIdInfo : m_MvtxRawHitMap.begin()->second.MvtxFeeIdInfoVector)
0871     {
0872       if (Verbosity() > 1)
0873       {
0874         mvtxFeeIdInfo->identify();
0875       }
0876       delete mvtxFeeIdInfo;
0877     }
0878 
0879     m_MvtxRawHitMap.begin()->second.MvtxFeeIdInfoVector.clear();
0880     m_MvtxRawHitMap.begin()->second.MvtxL1TrgBco.clear();
0881     m_MvtxRawHitMap.begin()->second.MvtxRawHitVector.clear();
0882     m_MvtxRawHitMap.erase(m_MvtxRawHitMap.begin());
0883 
0884     iret = FillMvtxPool();
0885     if (iret)
0886     {
0887       return iret;
0888     }
0889   }
0890   // again m_MvtxRawHitMap.empty() is handled by return of FillMvtxPool()
0891   if (Verbosity() > 2)
0892   {
0893     std::cout << "after ditching, mvtx bco: 0x" << std::hex << m_MvtxRawHitMap.begin()->first << ", ref: 0x" << m_RefBCO
0894               << std::dec << std::endl;
0895   }
0896 
0897   unsigned int refbcobitshift = m_RefBCO & 0x3FU;
0898   h_refbco_mvtx->Fill(refbcobitshift);
0899   for (auto &[strbbco, mvtxrawhitinfo] : m_MvtxRawHitMap)
0900   {
0901     auto diff = (m_RefBCO > strbbco) ? m_RefBCO - strbbco : strbbco - m_RefBCO;
0902     bool match = false;
0903     for (auto *feeidinfo : mvtxrawhitinfo.MvtxFeeIdInfoVector)
0904     {
0905       auto feeId = feeidinfo->get_feeId();
0906 
0907       auto link = MvtxRawDefs::decode_feeid(feeId);
0908       auto [felix, endpoint] = MvtxRawDefs::get_flx_endpoint(link.layer, link.stave);
0909       int packetid = felix * 2 + endpoint;
0910       h_bcoLL1Strobediff[packetid]->Fill(diff);
0911       if (diff <= m_mvtx_bco_range)
0912       {
0913         h_tagStBcoFelix_mvtx[packetid]->Fill(refbcobitshift);
0914         h_tagStBcoFEE_mvtx[packetid]->Fill(feeId);
0915         match = true;
0916       }
0917     }
0918 
0919     if (match)
0920     {
0921       // break because we found a match for this GL1, so we are done
0922       break;
0923     }
0924   }
0925 
0926   std::map<int, std::set<int>> taggedPacketsFEEs;
0927   for (auto &p : m_MvtxInputVector)
0928   {
0929     auto gtml1bcoset_perfee = p->getFeeGTML1BCOMap();
0930     //    int feecounter = 0;
0931     for (auto &[feeid, gtmbcoset] : gtml1bcoset_perfee)
0932     {
0933       auto link = MvtxRawDefs::decode_feeid(feeid);
0934       auto [felix, endpoint] = MvtxRawDefs::get_flx_endpoint(link.layer, link.stave);
0935       int packetid = felix * 2 + endpoint;
0936       for (const auto &gtmbco : gtmbcoset)
0937       {
0938         auto diff = (m_RefBCO > gtmbco) ? m_RefBCO - gtmbco : gtmbco - m_RefBCO;
0939 
0940         h_bcoGL1LL1diff[packetid]->Fill(diff);
0941         if (diff <= 3)
0942         {
0943           taggedPacketsFEEs[packetid].insert(feeid);
0944           h_tagL1BcoFEE_mvtx[packetid]->Fill(feeid);
0945           break;
0946         }
0947       }
0948       //      feecounter++;
0949     }
0950   }
0951   int allfeestagged = 0;
0952   for (auto &[pid, feeset] : taggedPacketsFEEs)
0953   {
0954     h_tagBcoFelix_mvtx[pid]->Fill(refbcobitshift);
0955     if (feeset.size() == 12)
0956     {
0957       allfeestagged++;
0958       h_tagBcoFelixAllFees_mvtx[pid]->Fill(refbcobitshift);
0959     }
0960     feeset.clear();
0961   }
0962   if (allfeestagged == 12)
0963   {
0964     h_taggedAllFelixesAllFees_mvtx->Fill(refbcobitshift);
0965   }
0966   if (taggedPacketsFEEs.size() == 12)
0967   {
0968     h_taggedAllFelixes_mvtx->Fill(refbcobitshift);
0969   }
0970   taggedPacketsFEEs.clear();
0971 
0972   if (m_mvtx_is_triggered)
0973   {
0974     while (select_crossings <= m_MvtxRawHitMap.begin()->first && m_MvtxRawHitMap.begin()->first <= select_crossings + m_mvtx_bco_range)  // triggered
0975     {
0976       if (Verbosity() > 2)
0977       {
0978         std::cout << "Adding 0x" << std::hex << m_MvtxRawHitMap.begin()->first
0979                   << " ref: 0x" << select_crossings << std::dec << std::endl;
0980       }
0981       for (auto *mvtxFeeIdInfo : m_MvtxRawHitMap.begin()->second.MvtxFeeIdInfoVector)
0982       {
0983         if (Verbosity() > 1)
0984         {
0985           mvtxFeeIdInfo->identify();
0986         }
0987         mvtxEvtHeader->AddFeeIdInfo(mvtxFeeIdInfo);
0988         delete mvtxFeeIdInfo;
0989       }
0990       m_MvtxRawHitMap.begin()->second.MvtxFeeIdInfoVector.clear();
0991       mvtxEvtHeader->AddL1Trg(m_MvtxRawHitMap.begin()->second.MvtxL1TrgBco);
0992 
0993       for (auto *mvtxhititer : m_MvtxRawHitMap.begin()->second.MvtxRawHitVector)
0994       {
0995         if (Verbosity() > 1)
0996         {
0997           mvtxhititer->identify();
0998         }
0999         mvtxcont->AddHit(mvtxhititer);
1000       }
1001       for (auto *iter : m_MvtxInputVector)
1002       {
1003         iter->CleanupUsedPackets(m_MvtxRawHitMap.begin()->first);
1004       }
1005       m_MvtxRawHitMap.begin()->second.MvtxRawHitVector.clear();
1006       m_MvtxRawHitMap.begin()->second.MvtxL1TrgBco.clear();
1007       m_MvtxRawHitMap.erase(m_MvtxRawHitMap.begin());
1008       // m_MvtxRawHitMap.empty() need to be checked here since we do not call FillPoolMvtx()
1009       if (m_MvtxRawHitMap.empty())
1010       {
1011         break;
1012       }
1013     }
1014   }
1015   else
1016   {
1017     while (select_crossings - m_mvtx_bco_range - m_mvtx_negative_bco <= m_MvtxRawHitMap.begin()->first && m_MvtxRawHitMap.begin()->first <= select_crossings)  // streamed
1018     {
1019       if (Verbosity() > 2)
1020       {
1021         std::cout << "Adding 0x" << std::hex << m_MvtxRawHitMap.begin()->first
1022                   << " ref: 0x" << select_crossings << std::dec << std::endl;
1023       }
1024       for (auto *mvtxFeeIdInfo : m_MvtxRawHitMap.begin()->second.MvtxFeeIdInfoVector)
1025       {
1026         if (Verbosity() > 1)
1027         {
1028           mvtxFeeIdInfo->identify();
1029         }
1030         mvtxEvtHeader->AddFeeIdInfo(mvtxFeeIdInfo);
1031         delete mvtxFeeIdInfo;
1032       }
1033       m_MvtxRawHitMap.begin()->second.MvtxFeeIdInfoVector.clear();
1034       mvtxEvtHeader->AddL1Trg(m_MvtxRawHitMap.begin()->second.MvtxL1TrgBco);
1035 
1036       for (auto *mvtxhititer : m_MvtxRawHitMap.begin()->second.MvtxRawHitVector)
1037       {
1038         if (Verbosity() > 1)
1039         {
1040           mvtxhititer->identify();
1041         }
1042         mvtxcont->AddHit(mvtxhititer);
1043       }
1044       for (auto *iter : m_MvtxInputVector)
1045       {
1046         iter->CleanupUsedPackets(m_MvtxRawHitMap.begin()->first);
1047       }
1048       m_MvtxRawHitMap.begin()->second.MvtxRawHitVector.clear();
1049       m_MvtxRawHitMap.begin()->second.MvtxL1TrgBco.clear();
1050       m_MvtxRawHitMap.erase(m_MvtxRawHitMap.begin());
1051       // m_MvtxRawHitMap.empty() need to be checked here since we do not call FillPoolMvtx()
1052       if (m_MvtxRawHitMap.empty())
1053       {
1054         break;
1055       }
1056     }
1057   }
1058 
1059   return 0;
1060 }
1061 
1062 //_______________________________________________________
1063 int Fun4AllStreamingInputManager::FillMicromegas()
1064 {
1065   int iret = FillMicromegasPool();
1066   if (iret)
1067   {
1068     return iret;
1069   }
1070 
1071   auto *container = findNode::getClass<MicromegasRawHitContainer>(m_topNode, "MICROMEGASRAWHIT");
1072   if (!container)
1073   {
1074     container = findNode::getClass<MicromegasRawHitContainer>(m_topNode, (*(m_MicromegasInputVector.begin()))->getHitContainerName());
1075     if (!container)
1076     {
1077       std::cout << PHWHERE << "No micromegas raw hit container found, exiting." << std::endl;
1078       gSystem->Exit(1);
1079       exit(1);
1080     }
1081   }
1082 
1083   // get reference BCO from Micromegas data stream if not set already
1084   if (m_RefBCO == 0)
1085   {
1086     m_RefBCO = m_MicromegasRawHitMap.begin()->first;
1087   }
1088 
1089   // define bco range
1090   const uint64_t first_bco = m_RefBCO - m_micromegas_negative_bco;
1091   const uint64_t last_bco = m_RefBCO + m_micromegas_bco_range - m_micromegas_negative_bco;
1092   if (Verbosity() > 2)
1093   {
1094     std::cout
1095         << "Fun4AllStreamingInputManager::FillMicromegas - select Micromegas crossings"
1096         << " from 0x" << std::hex << first_bco
1097         << " to 0x" << last_bco
1098         << " for ref BCO " << m_RefBCO
1099         << std::dec << std::endl;
1100   }
1101 
1102   // cleanup all data that correspond to too early BCO. Said data is effectively dropped
1103   while (m_MicromegasRawHitMap.begin()->first < first_bco)
1104   {
1105     if (Verbosity() > 2)
1106     {
1107       std::cout
1108           << "Micromegas BCO: 0x" << std::hex << m_MicromegasRawHitMap.begin()->first
1109           << " smaller than GL1 BCO: 0x" << first_bco
1110           << ", ditching this bco" << std::dec << std::endl;
1111     }
1112 
1113     for (const auto &poolinput : m_MicromegasInputVector)
1114     {
1115       poolinput->CleanupUsedPackets(m_MicromegasRawHitMap.begin()->first, true);
1116     }
1117 
1118     // remove
1119     m_MicromegasRawHitMap.erase(m_MicromegasRawHitMap.begin());
1120 
1121     // fill pools again
1122     iret = FillMicromegasPool();
1123     if (iret)
1124     {
1125       return iret;
1126     }
1127   }
1128 
1129   // fill all BCO statistics
1130   for (const auto &iter : m_MicromegasInputVector)
1131   {
1132     iter->FillBcoQA(m_RefBCO);
1133   }
1134 
1135   // store hits relevant for this trigger and cleanup
1136   for (auto iter = m_MicromegasRawHitMap.begin(); iter != m_MicromegasRawHitMap.end() && iter->first <= last_bco; iter = m_MicromegasRawHitMap.erase(iter))
1137   {
1138     for (const auto &hititer : iter->second.MicromegasRawHitVector)
1139     {
1140       container->AddHit(hititer);
1141     }
1142 
1143     for (const auto &poolinput : m_MicromegasInputVector)
1144     {
1145       poolinput->CleanupUsedPackets(iter->first);
1146     }
1147   }
1148 
1149   return 0;
1150 }
1151 
1152 int Fun4AllStreamingInputManager::FillTpc()
1153 {
1154   int iret = FillTpcPool();
1155   if (iret)
1156   {
1157     return iret;
1158   }
1159   TpcRawHitContainer *tpccont = findNode::getClass<TpcRawHitContainer>(m_topNode, "TPCRAWHIT");
1160   if (!tpccont)
1161   {
1162     /// if we set the node name and are running over single prdfs, thre is only one prdf in the vector
1163     tpccont = findNode::getClass<TpcRawHitContainer>(m_topNode, (*(m_TpcInputVector.begin()))->getHitContainerName());
1164     if (!tpccont)
1165     {
1166       std::cout << PHWHERE << "No tpc raw hit container found, exiting." << std::endl;
1167       gSystem->Exit(1);
1168       exit(1);
1169     }
1170   }
1171   //  std::cout << "before filling m_TpcRawHitMap size: " <<  m_TpcRawHitMap.size() << std::endl;
1172   uint64_t select_crossings = m_tpc_bco_range;
1173   if (m_RefBCO == 0)
1174   {
1175     m_RefBCO = m_TpcRawHitMap.begin()->first;
1176   }
1177   select_crossings += m_RefBCO;
1178   if (Verbosity() > 2)
1179   {
1180     std::cout << "select TPC crossings"
1181               << " from 0x" << std::hex << m_RefBCO - m_tpc_negative_bco
1182               << " to 0x" << select_crossings - m_tpc_negative_bco
1183               << std::dec << std::endl;
1184   }
1185   // m_TpcRawHitMap.empty() does not need to be checked here, FillTpcPool returns non zero
1186   // if this map is empty which is handled above
1187 
1188   if (!m_TpcRawHitMap.empty())
1189   {
1190     while (m_TpcRawHitMap.begin()->first < m_RefBCO - m_tpc_negative_bco)
1191     {
1192       for (auto *iter : m_TpcInputVector)
1193       {
1194         iter->CleanupUsedPackets(m_TpcRawHitMap.begin()->first);
1195         iter->clearPacketBClkStackMap(m_TpcRawHitMap.begin()->first);
1196       }
1197       m_TpcRawHitMap.begin()->second.TpcRawHitVector.clear();
1198       m_TpcRawHitMap.erase(m_TpcRawHitMap.begin());
1199       iret = FillTpcPool();
1200       if (iret)
1201       {
1202         return iret;
1203       }
1204     }
1205   }
1206 
1207   // again m_TpcRawHitMap.empty() is handled by return of FillTpcPool()
1208   if (!m_TpcRawHitMap.empty())
1209   {
1210     while (m_TpcRawHitMap.begin()->first <= select_crossings - m_tpc_negative_bco)
1211     {
1212       for (auto *tpchititer : m_TpcRawHitMap.begin()->second.TpcRawHitVector)
1213       {
1214         if (Verbosity() > 1)
1215         {
1216           tpchititer->identify();
1217         }
1218         tpccont->AddHit(tpchititer);
1219       }
1220       for (auto *iter : m_TpcInputVector)
1221       {
1222         iter->CleanupUsedPackets(m_TpcRawHitMap.begin()->first);
1223         // we just want to erase anything that is well away from the current GL1
1224       }
1225       m_TpcRawHitMap.begin()->second.TpcRawHitVector.clear();
1226       m_TpcRawHitMap.erase(m_TpcRawHitMap.begin());
1227       if (m_TpcRawHitMap.empty())
1228       {
1229         break;
1230       }
1231     }
1232   }
1233   if (Verbosity() > 0)
1234   {
1235     std::cout << "tpc container size: " << tpccont->get_nhits();
1236     std::cout << ", size  m_TpcRawHitMap: " << m_TpcRawHitMap.size()
1237               << std::endl;
1238   }
1239   if (tpccont->get_nhits() > 500000)
1240   {
1241     std::cout << "Resetting TPC Container with number of entries " << tpccont->get_nhits() << std::endl;
1242     tpccont->Reset();
1243   }
1244   return 0;
1245 }
1246 
1247 void Fun4AllStreamingInputManager::SetInttBcoRange(const unsigned int i)
1248 {
1249   m_intt_bco_range = std::max(i, m_intt_bco_range);
1250 }
1251 
1252 void Fun4AllStreamingInputManager::SetInttNegativeBco(const unsigned int i)
1253 {
1254   m_intt_negative_bco = std::max(i, m_intt_negative_bco);
1255 }
1256 
1257 void Fun4AllStreamingInputManager::SetMicromegasBcoRange(const unsigned int i)
1258 {
1259   m_micromegas_bco_range = std::max(i, m_micromegas_bco_range);
1260 }
1261 
1262 void Fun4AllStreamingInputManager::SetMicromegasNegativeBco(const unsigned int i)
1263 {
1264   m_micromegas_negative_bco = std::max(i, m_micromegas_negative_bco);
1265 }
1266 
1267 void Fun4AllStreamingInputManager::SetMvtxNegativeBco(const unsigned int i)
1268 {
1269   m_mvtx_negative_bco = std::max(i, m_mvtx_negative_bco);
1270 }
1271 
1272 void Fun4AllStreamingInputManager::SetTpcBcoRange(const unsigned int i)
1273 {
1274   m_tpc_bco_range = std::max(i, m_tpc_bco_range);
1275 }
1276 
1277 void Fun4AllStreamingInputManager::SetTpcNegativeBco(const unsigned int i)
1278 {
1279   m_tpc_negative_bco = std::max(i, m_tpc_negative_bco);
1280 }
1281 
1282 void Fun4AllStreamingInputManager::SetMvtxBcoRange(const unsigned int i)
1283 {
1284   m_mvtx_bco_range = std::max(i, m_mvtx_bco_range);
1285 }
1286 
1287 int Fun4AllStreamingInputManager::FillInttPool()
1288 {
1289   uint64_t ref_bco_minus_range = 0;
1290   if (m_RefBCO > m_intt_negative_bco)
1291   {
1292     ref_bco_minus_range = m_RefBCO - m_intt_negative_bco;
1293   }
1294   for (auto *iter : m_InttInputVector)
1295   {
1296     if (!m_gl1_registered_flag)
1297     {
1298       iter->SetStandaloneMode(true);
1299     }
1300     if (Verbosity() > 0)
1301     {
1302       std::cout << "Fun4AllStreamingInputManager::FillInttPool - fill pool for " << iter->Name() << std::endl;
1303     }
1304     iter->FillPool(ref_bco_minus_range);
1305     // iter->FillPool();
1306     if (m_RunNumber == 0)
1307     {
1308       m_RunNumber = iter->RunNumber();
1309       SetRunNumber(m_RunNumber);
1310     }
1311     else
1312     {
1313       if (m_RunNumber != iter->RunNumber())
1314       {
1315         std::cout << PHWHERE << " Run Number mismatch, run is "
1316                   << m_RunNumber << ", " << iter->Name() << " reads "
1317                   << iter->RunNumber() << std::endl;
1318         std::cout << "You are likely reading files from different runs, do not do that" << std::endl;
1319         Print("INPUTFILES");
1320         gSystem->Exit(1);
1321         exit(1);
1322       }
1323     }
1324   }
1325   if (m_InttRawHitMap.empty())
1326   {
1327     std::cout << "InttRawHitMap is empty - we are done" << std::endl;
1328     return -1;
1329   }
1330   return 0;
1331 }
1332 
1333 int Fun4AllStreamingInputManager::FillTpcPool()
1334 {
1335   uint64_t ref_bco_minus_range = 0;
1336   if (m_RefBCO > m_tpc_negative_bco)
1337   {
1338     ref_bco_minus_range = m_RefBCO - m_tpc_negative_bco;
1339   }
1340 
1341   for (auto *iter : m_TpcInputVector)
1342   {
1343     if (Verbosity() > 0)
1344     {
1345       std::cout << "Fun4AllStreamingInputManager::FillTpcPool - fill pool for " << iter->Name() << std::endl;
1346     }
1347     iter->FillPool(ref_bco_minus_range);
1348     if (m_RunNumber == 0)
1349     {
1350       m_RunNumber = iter->RunNumber();
1351       SetRunNumber(m_RunNumber);
1352     }
1353     else
1354     {
1355       if (m_RunNumber != iter->RunNumber())
1356       {
1357         std::cout << PHWHERE << " Run Number mismatch, run is "
1358                   << m_RunNumber << ", " << iter->Name() << " reads "
1359                   << iter->RunNumber() << std::endl;
1360         std::cout << "You are likely reading files from different runs, do not do that" << std::endl;
1361         Print("INPUTFILES");
1362         gSystem->Exit(1);
1363         exit(1);
1364       }
1365     }
1366   }
1367   // if (m_TpcRawHitMap.empty())
1368   // {
1369   //   std::cout << "TpcRawHitMap is empty - we are done" << std::endl;
1370   // return -1;
1371   // }
1372   return 0;
1373 }
1374 
1375 int Fun4AllStreamingInputManager::FillMicromegasPool()
1376 {
1377   for (auto *iter : m_MicromegasInputVector)
1378   {
1379     if (Verbosity() > 0)
1380     {
1381       std::cout << "Fun4AllStreamingInputManager::FillMicromegasPool - fill pool for " << iter->Name() << std::endl;
1382     }
1383     iter->FillPool();
1384     if (m_RunNumber == 0)
1385     {
1386       m_RunNumber = iter->RunNumber();
1387       SetRunNumber(m_RunNumber);
1388     }
1389     else
1390     {
1391       if (m_RunNumber != iter->RunNumber())
1392       {
1393         std::cout << PHWHERE << " Run Number mismatch, run is "
1394                   << m_RunNumber << ", " << iter->Name() << " reads "
1395                   << iter->RunNumber() << std::endl;
1396         std::cout << "You are likely reading files from different runs, do not do that" << std::endl;
1397         Print("INPUTFILES");
1398         gSystem->Exit(1);
1399         exit(1);
1400       }
1401     }
1402   }
1403   if (m_MicromegasRawHitMap.empty())
1404   {
1405     std::cout << "MicromegasRawHitMap is empty - we are done" << std::endl;
1406     return -1;
1407   }
1408   return 0;
1409 }
1410 
1411 int Fun4AllStreamingInputManager::FillMvtxPool()
1412 {
1413   uint64_t ref_bco_minus_range = m_RefBCO < m_mvtx_bco_range ? m_mvtx_bco_range : m_RefBCO - m_mvtx_bco_range;
1414   for (auto *iter : m_MvtxInputVector)
1415   {
1416     if (Verbosity() > 3)
1417     {
1418       std::cout << "Fun4AllStreamingInputManager::FillMvtxPool - fill pool for " << iter->Name() << std::endl;
1419     }
1420     iter->FillPool(ref_bco_minus_range);
1421     if (m_RunNumber == 0)
1422     {
1423       m_RunNumber = iter->RunNumber();
1424       SetRunNumber(m_RunNumber);
1425     }
1426     else
1427     {
1428       if (m_RunNumber != iter->RunNumber())
1429       {
1430         std::cout << PHWHERE << " Run Number mismatch, run is "
1431                   << m_RunNumber << ", " << iter->Name() << " reads "
1432                   << iter->RunNumber() << std::endl;
1433         std::cout << "You are likely reading files from different runs, do not do that" << std::endl;
1434         Print("INPUTFILES");
1435         gSystem->Exit(1);
1436         exit(1);
1437       }
1438     }
1439   }
1440   if (m_MvtxRawHitMap.empty())
1441   {
1442     std::cout << "MvtxRawHitMap is empty - we are done" << std::endl;
1443     return -1;
1444   }
1445   return 0;
1446 }
1447 void Fun4AllStreamingInputManager::createQAHistos()
1448 {
1449   auto *hm = QAHistManagerDef::getHistoManager();
1450   assert(hm);
1451 
1452   {
1453     auto *h = new TH1I("h_MvtxPoolQA_RefGL1BCO", "MVTX ref BCO", 1000, 0, 1000);
1454     h->GetXaxis()->SetTitle("GL1 BCO");
1455     h->SetTitle("GL1 Reference BCO");
1456     hm->registerHisto(h);
1457   }
1458 
1459   {
1460     auto *h = new TH1I("h_InttPoolQA_TagBCOAllServers", "INTT trigger tagged BCO all servers", 1000, 0, 1000);
1461     h->GetXaxis()->SetTitle("GL1 BCO");
1462     h->SetTitle("GL1 Reference BCO");
1463     hm->registerHisto(h);
1464   }
1465   {
1466     auto *h = new TH1I("h_MvtxPoolQA_TagBCOAllFelixs", "MVTX trigger tagged BCO all felixs", 1000, 0, 1000);
1467     h->GetXaxis()->SetTitle("GL1 BCO");
1468     h->SetTitle("GL1 Reference BCO");
1469     hm->registerHisto(h);
1470   }
1471   {
1472     auto *h = new TH1I("h_MvtxPoolQA_TagBCOAllFelixsAllFees", "MVTX trigger tagged BCO all felixes and fees", 1000, 0, 1000);
1473     h->GetXaxis()->SetTitle("GL1 BCO");
1474     hm->registerHisto(h);
1475     h_taggedAllFelixesAllFees_mvtx = h;
1476   }
1477 
1478   for (int i = 0; i < 12; i++)
1479   {
1480     h_tagStBcoFEE_mvtx[i] = new TH1I((boost::format("h_MvtxPoolQA_TagStBcoFEEsPacket%i") % i).str().c_str(), "", 10000, 0, 10000);
1481     hm->registerHisto(h_tagStBcoFEE_mvtx[i]);
1482     h_tagL1BcoFEE_mvtx[i] = new TH1I((boost::format("h_MvtxPoolQA_TagL1BcoFEEsPacket%i") % i).str().c_str(), "", 10000, 0, 10000);
1483     hm->registerHisto(h_tagL1BcoFEE_mvtx[i]);
1484   }
1485   // intt has 8 prdfs, one per felix
1486   for (int i = 0; i < 8; i++)
1487   {
1488     auto *hgl1 = new TH1I(std::format("h_InttPoolQA_RefGL1BCO_server{}", i).c_str(), std::format("INTT ref BCO server{}", i).c_str(), 1000, 0, 1000);
1489     hgl1->GetXaxis()->SetTitle("GL1 BCO");
1490     hgl1->SetTitle(std::format("GL1 Reference BCO for server{}", i).c_str());
1491     hm->registerHisto(hgl1);
1492 
1493     auto *h = new TH1I((boost::format("h_InttPoolQA_TagBCO_server%i") % i).str().c_str(), "INTT trigger tagged BCO", 1000, 0, 1000);
1494     h->GetXaxis()->SetTitle("GL1 BCO");
1495     h->SetTitle((boost::format("EBDC %i") % i).str().c_str());
1496     hm->registerHisto(h);
1497 
1498     auto *h_all = new TH1I((boost::format("h_InttPoolQA_TagBCOAllFees_Server%i") % i).str().c_str(), "INTT trigger tagged BCO all servers", 1000, 0, 1000);
1499     h_all->GetXaxis()->SetTitle("GL1 BCO");
1500     h_all->SetTitle("GL1 Reference BCO");
1501     hm->registerHisto(h_all);
1502     for (int j = 0; j < 14; j++)
1503     {
1504       auto *h2 = new TH1I((boost::format("h_InttPoolQA_TagBCO_server%i_fee%i") % i % j).str().c_str(), "INTT trigger tagged BCO per FEE", 1000, 0, 1000);
1505       h2->GetXaxis()->SetTitle("GL1 BCO");
1506       h2->SetTitle((boost::format("EBDC %i FEE %i") % i % j).str().c_str());
1507       hm->registerHisto(h2);
1508     }
1509   }
1510   for (int i = 0; i < 12; i++)
1511   {
1512     {
1513       auto *h = new TH1I((boost::format("h_MvtxPoolQA_TagBCO_felix%i") % i).str().c_str(), "MVTX trigger tagged BCO", 1000, 0, 1000);
1514       h->GetXaxis()->SetTitle("GL1 BCO");
1515       h->SetTitle((boost::format("Felix %i") % i).str().c_str());
1516       hm->registerHisto(h);
1517     }
1518     {
1519       auto *h = new TH1I((boost::format("h_MvtxPoolQA_TagStBco_felix%i") % i).str().c_str(), "", 1000, 0, 1000);
1520       hm->registerHisto(h);
1521       h_tagStBcoFelix_mvtx[i] = h;
1522     }
1523     auto *h_all = new TH1I((boost::format("h_MvtxPoolQA_TagBCOAllFees_Felix%i") % i).str().c_str(), "MVTX trigger tagged BCO all Fees", 1000, 0, 1000);
1524     h_all->GetXaxis()->SetTitle("GL1 BCO");
1525     h_all->SetTitle("GL1 Reference BCO");
1526     hm->registerHisto(h_all);
1527   }
1528 
1529   for (int i = 0; i < 12; i++)
1530   {
1531     h_bcoGL1LL1diff[i] = new TH1I((boost::format("h_MvtxPoolQA_GL1LL1BCODiff_packet%i") % i).str().c_str(), "MVTX BCO diff;|GL1 BCO - LL1 BCO|", 5000, 0, 5000);
1532     hm->registerHisto(h_bcoGL1LL1diff[i]);
1533     h_bcoLL1Strobediff[i] = new TH1I((boost::format("h_MvtxPoolQA_LL1StrobeBCODiff_packet%i") % i).str().c_str(), "MVTX BCO diff; |LL1 BCO - Strobe BCO|", 100000, 0, 100000);
1534     hm->registerHisto(h_bcoLL1Strobediff[i]);
1535   }
1536   // Get the global pointers
1537   h_taggedAll_intt = dynamic_cast<TH1 *>(hm->getHisto("h_InttPoolQA_TagBCOAllServers"));
1538   h_taggedAllFee_intt = new TH1I("h_InttPoolQA_TagBCOAllServersAllFees", "INTT trigger tagged BCO all servers and fees", 1000, 0, 1000);
1539   hm->registerHisto(h_taggedAllFee_intt);
1540   for (int i = 0; i < 8; i++)
1541   {
1542     h_refbco_intt[i] = dynamic_cast<TH1 *>(hm->getHisto(std::format("h_InttPoolQA_RefGL1BCO_server{}", i)));
1543 
1544     h_gl1tagged_intt[i] = dynamic_cast<TH1 *>(hm->getHisto((boost::format("h_InttPoolQA_TagBCO_server%i") % i).str()));
1545     h_bcodiff_intt[i] = new TH2I((boost::format("h_InttPoolQA_BCODiff_server%i") % i).str().c_str(), ";FEE ID;|GL1 BCO - GTM BCO|", 14, 0, 14, 10000, 0, 10000);
1546     hm->registerHisto(h_bcodiff_intt[i]);
1547     for (int j = 0; j < 14; j++)
1548     {
1549       h_gl1taggedfee_intt[i][j] = dynamic_cast<TH1 *>(hm->getHisto((boost::format("h_InttPoolQA_TagBCO_server%i_fee%i") % i % j).str()));
1550     }
1551     h_taggedAllFees_intt[i] = dynamic_cast<TH1 *>(hm->getHisto((boost::format("h_InttPoolQA_TagBCOAllFees_Server%i") % i).str()));
1552   }
1553 
1554   h_refbco_mvtx = dynamic_cast<TH1 *>(hm->getHisto("h_MvtxPoolQA_RefGL1BCO"));
1555   h_taggedAllFelixes_mvtx = dynamic_cast<TH1 *>(hm->getHisto("h_MvtxPoolQA_TagBCOAllFelixs"));
1556   for (int i = 0; i < 12; i++)
1557   {
1558     h_tagBcoFelix_mvtx[i] = dynamic_cast<TH1 *>(hm->getHisto((boost::format("h_MvtxPoolQA_TagBCO_felix%i") % i).str()));
1559     h_tagBcoFelixAllFees_mvtx[i] = dynamic_cast<TH1 *>(hm->getHisto((boost::format("h_MvtxPoolQA_TagBCOAllFees_Felix%i") % i).str()));
1560   }
1561 }