Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-06 08:17:20

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