File indexing completed on 2025-08-05 08:16:17
0001 #include "SingleTpcTimeFrameInput.h"
0002 #include "TpcTimeFrameBuilder.h"
0003
0004 #include "Fun4AllStreamingInputManager.h"
0005 #include "InputManagerType.h"
0006
0007 #include <ffarawobjects/TpcRawHitContainerv3.h>
0008 #include <ffarawobjects/TpcRawHitv3.h>
0009
0010 #include <frog/FROG.h>
0011 #include <phool/PHTimer.h> // for PHTimer
0012
0013 #include <fun4all/Fun4AllHistoManager.h>
0014 #include <fun4all/Fun4AllReturnCodes.h>
0015 #include <qautils/QAHistManagerDef.h>
0016
0017 #include <TAxis.h>
0018 #include <TH1.h>
0019 #include <TH2.h>
0020
0021 #include <phool/PHCompositeNode.h>
0022 #include <phool/PHNodeIterator.h> // for PHNodeIterator
0023 #include <phool/getClass.h>
0024 #include <phool/phool.h>
0025
0026 #include <Event/Event.h>
0027 #include <Event/EventTypes.h>
0028 #include <Event/Eventiterator.h>
0029 #include <Event/fileEventiterator.h>
0030
0031 #include <memory>
0032 #include <set>
0033
0034 SingleTpcTimeFrameInput::SingleTpcTimeFrameInput(const std::string &name)
0035 : SingleStreamingInput(name)
0036 {
0037 SubsystemEnum(InputManagerType::TPC);
0038 m_rawHitContainerName = "TPCRAWHIT";
0039 plist = new Packet *[NTPCPACKETS];
0040
0041
0042
0043 m_FillPoolTimer = new PHTimer("SingleTpcTimeFrameInput_" + name + "_FillPool");
0044 m_getNextEventTimer = new PHTimer("SingleTpcTimeFrameInput_" + name + "_getNextEvent");
0045 m_ProcessPacketTimer = new PHTimer("SingleTpcTimeFrameInput_" + name + "_ProcessPacket");
0046 m_getTimeFrameTimer = new PHTimer("SingleTpcTimeFrameInput_" + name + "_getTimeFrame");
0047
0048 Fun4AllHistoManager *hm = QAHistManagerDef::getHistoManager();
0049 assert(hm);
0050
0051 m_hNorm = new TH1D(TString("SingleTpcTimeFrameInput_" + name) + "_Normalization",
0052 TString("SingleTpcTimeFrameInput_" + name) + " Normalization;Items;Count",
0053 20, .5, 20.5);
0054 int i = 1;
0055 m_hNorm->GetXaxis()->SetBinLabel(i++, "FillPoolCount");
0056 m_hNorm->GetXaxis()->SetBinLabel(i++, "FillPoolTime[ms]");
0057 m_hNorm->GetXaxis()->SetBinLabel(i++, "getNextEventCount");
0058 m_hNorm->GetXaxis()->SetBinLabel(i++, "getNextEventTime[ms]");
0059 m_hNorm->GetXaxis()->SetBinLabel(i++, "ProcessPacketCount");
0060 m_hNorm->GetXaxis()->SetBinLabel(i++, "ProcessPacketTime[ms]");
0061 m_hNorm->GetXaxis()->SetBinLabel(i++, "getTimeFrameCount");
0062 m_hNorm->GetXaxis()->SetBinLabel(i++, "getTimeFrameTime[ms]");
0063 assert(i <= 20);
0064 m_hNorm->GetXaxis()->LabelsOption("v");
0065 hm->registerHisto(m_hNorm);
0066 }
0067
0068 SingleTpcTimeFrameInput::~SingleTpcTimeFrameInput()
0069 {
0070 delete[] plist;
0071 delete m_FillPoolTimer;
0072 delete m_getNextEventTimer;
0073 delete m_ProcessPacketTimer;
0074 delete m_getTimeFrameTimer;
0075 for (auto iter : m_TpcTimeFrameBuilderMap)
0076 {
0077 delete iter.second;
0078 }
0079 }
0080
0081 SingleTpcTimeFrameInput::TimeTracker::TimeTracker(PHTimer *timer, const std::string &name, TH1 *hout)
0082 : m_timer(timer)
0083 , m_name(name.c_str())
0084 , m_hNorm(hout)
0085 {
0086 assert(m_timer);
0087 assert(m_hNorm);
0088
0089 m_hNorm->Fill(m_name + "Count", 1);
0090
0091 m_timer->restart();
0092 }
0093
0094 void SingleTpcTimeFrameInput::TimeTracker::stop()
0095 {
0096 assert(m_timer);
0097 assert(m_hNorm);
0098
0099 m_timer->stop();
0100 m_hNorm->Fill(m_name + "Time[ms]", m_timer->elapsed());
0101
0102 stopped = true;
0103 }
0104
0105 SingleTpcTimeFrameInput::TimeTracker::~TimeTracker()
0106 {
0107 if (!stopped)
0108 {
0109 stop();
0110 }
0111 }
0112
0113 void SingleTpcTimeFrameInput::FillPool(const uint64_t targetBCO)
0114 {
0115 {
0116 static bool first = true;
0117 if (first)
0118 {
0119 first = false;
0120
0121 if (m_SelectedPacketIDs.size())
0122 {
0123 std::cout << "SingleTpcTimeFrameInput::" << Name() << " : note, only processing packets with ID: ";
0124 for (const auto &id : m_SelectedPacketIDs)
0125 {
0126 std::cout << id << " ";
0127 }
0128 std::cout << std::endl;
0129 }
0130 }
0131 }
0132
0133 TimeTracker fillPoolTimer(m_FillPoolTimer, "FillPool", m_hNorm);
0134
0135 if ((Verbosity() >= 1 and targetBCO % 941 == 10) or Verbosity() >= 2)
0136 {
0137 std::cout << "SingleTpcTimeFrameInput::FillPool: " << Name()
0138 << " Entry with targetBCO = 0x" << std::hex << targetBCO
0139 << "(" << std::dec << targetBCO << ")" << std::endl;
0140
0141 m_FillPoolTimer->print_stat();
0142 m_getNextEventTimer->print_stat();
0143 m_ProcessPacketTimer->print_stat();
0144 m_getTimeFrameTimer->print_stat();
0145 }
0146
0147 if (AllDone())
0148 {
0149 if (Verbosity() > 1)
0150 {
0151 std::cout << "SingleTpcTimeFrameInput::FillPool: " << Name()
0152 << " AllDone for targetBCO " << targetBCO << std::endl;
0153 }
0154
0155 return;
0156 }
0157 while (GetEventiterator() == nullptr)
0158 {
0159 if (Verbosity() > 1)
0160 {
0161 std::cout << "SingleTpcTimeFrameInput::FillPool: " << Name()
0162 << " GetEventiterator == null for targetBCO " << targetBCO << std::endl;
0163 }
0164
0165 if (!OpenNextFile())
0166 {
0167 if (Verbosity() > 1)
0168 {
0169 std::cout << "SingleTpcTimeFrameInput::FillPool: " << Name()
0170 << " OpenNextFile() quit for targetBCO " << targetBCO << std::endl;
0171 }
0172 AllDone(1);
0173 return;
0174 }
0175 }
0176
0177 while (true)
0178 {
0179 if (m_TpcTimeFrameBuilderMap.empty())
0180 {
0181 if (Verbosity() > 1)
0182 {
0183 std::cout << "SingleTpcTimeFrameInput::FillPool: " << Name()
0184 << " m_TpcTimeFrameBuilderMap empty for targetBCO 0x"
0185 << std::hex << targetBCO << std::dec << ". Start processing next event... " << std::endl;
0186 }
0187 }
0188 else
0189 {
0190 bool require_more_data = false;
0191 for (auto &map_builder : m_TpcTimeFrameBuilderMap)
0192 {
0193 require_more_data |= map_builder.second->isMoreDataRequired(targetBCO);
0194 }
0195 if (not require_more_data)
0196 {
0197 if (Verbosity() > 1)
0198 {
0199 std::cout << "SingleTpcTimeFrameInput::FillPool: " << Name()
0200 << " satisified require_more_data for targetBCO 0x"
0201 << std::hex << targetBCO << std::dec << std::endl;
0202 }
0203
0204 break;
0205 }
0206 }
0207 if (Verbosity() > 1)
0208 {
0209 std::cout << "SingleTpcTimeFrameInput::FillPool: " << Name()
0210 << " require_more_data for targetBCO 0x"
0211 << std::hex << targetBCO << std::dec << std::endl;
0212 }
0213
0214 TimeTracker getNextEventTimer(m_getNextEventTimer, "getNextEvent", m_hNorm);
0215 std::unique_ptr<Event> evt(GetEventiterator()->getNextEvent());
0216 while (!evt)
0217 {
0218 fileclose();
0219 if (!OpenNextFile())
0220 {
0221 AllDone(1);
0222 return;
0223 }
0224 evt.reset(GetEventiterator()->getNextEvent());
0225 RunNumber(0);
0226 }
0227
0228 if (RunNumber() == 0)
0229 {
0230 RunNumber(evt->getRunNumber());
0231
0232 if (Verbosity() >= 1)
0233 {
0234 std::cout << __PRETTY_FUNCTION__ << ": Fetching new file "<<FileName()
0235 <<" for run "<<evt->getRunNumber()<<" with next Event # " << evt->getEvtSequence() << std::endl;
0236 }
0237 }
0238
0239 if (Verbosity() > 2)
0240 {
0241 std::cout << "Fetching next Event" << evt->getEvtSequence() << std::endl;
0242 }
0243 if (GetVerbosity() > 1)
0244 {
0245 evt->identify();
0246 }
0247 if (evt->getEvtType() != DATAEVENT)
0248 {
0249 m_NumSpecialEvents++;
0250 continue;
0251 }
0252
0253 int npackets = evt->getPacketList(plist, NTPCPACKETS);
0254
0255 if (npackets >= NTPCPACKETS)
0256 {
0257 std::cout << PHWHERE << " Packets array size " << NTPCPACKETS
0258 << " too small for " << Name()
0259 << ", increase NTPCPACKETS and rebuild" << std::endl;
0260 exit(1);
0261 }
0262 getNextEventTimer.stop();
0263
0264 TimeTracker ProcessPacketTimer(m_ProcessPacketTimer, "ProcessPacket", m_hNorm);
0265 for (int i = 0; i < npackets; i++)
0266 {
0267
0268 auto &packet = plist[i];
0269 assert(packet);
0270
0271
0272 const auto packet_id = packet->getIdentifier();
0273
0274 if (m_SelectedPacketIDs.size() > 0 and m_SelectedPacketIDs.find(packet_id) == m_SelectedPacketIDs.end())
0275 {
0276 if (Verbosity() > 1)
0277 {
0278 std::cout << __PRETTY_FUNCTION__ << ": Skipping packet id: " << packet_id << std::endl;
0279 }
0280
0281 delete packet;
0282 packet = nullptr;
0283 continue;
0284 }
0285
0286 if (m_TpcTimeFrameBuilderMap.find(packet_id) == m_TpcTimeFrameBuilderMap.end())
0287 {
0288 if (Verbosity() >= 1)
0289 {
0290 std::cout << __PRETTY_FUNCTION__ << ": Creating TpcTimeFrameBuilder for packet id: " << packet_id << std::endl;
0291 }
0292
0293 m_TpcTimeFrameBuilderMap[packet_id] = new TpcTimeFrameBuilder(packet_id);
0294 m_TpcTimeFrameBuilderMap[packet_id]->setVerbosity(Verbosity());
0295 if (m_digitalCurrentDebugTTreeName.size())
0296 {
0297 m_TpcTimeFrameBuilderMap[packet_id]->SaveDigitalCurrentDebugTTree(m_digitalCurrentDebugTTreeName);
0298 }
0299 }
0300
0301 if (Verbosity() > 1)
0302 {
0303 packet->identify();
0304 }
0305
0306 assert(m_TpcTimeFrameBuilderMap[packet_id]);
0307 m_TpcTimeFrameBuilderMap[packet_id]->ProcessPacket(packet);
0308
0309
0310 delete packet;
0311 packet = nullptr;
0312 }
0313 ProcessPacketTimer.stop();
0314
0315 }
0316
0317
0318 for (auto &map_builder : m_TpcTimeFrameBuilderMap)
0319 {
0320 assert(not map_builder.second->isMoreDataRequired(targetBCO));
0321 auto &timeframe = map_builder.second->getTimeFrame(targetBCO);
0322
0323 for (auto newhit : timeframe)
0324 {
0325 StreamingInputManager()->AddTpcRawHit(targetBCO, newhit);
0326 }
0327 }
0328
0329 TimeTracker getTimeFrameTimer(m_getTimeFrameTimer, "getTimeFrame", m_hNorm);
0330 }
0331
0332 void SingleTpcTimeFrameInput::Print(const std::string & ) const
0333 {
0334 }
0335
0336 void SingleTpcTimeFrameInput::CleanupUsedPackets(const uint64_t bclk)
0337 {
0338 if (Verbosity() > 2)
0339 {
0340 std::cout << "cleaning up bcos < 0x" << std::hex
0341 << bclk << std::dec << std::endl;
0342 }
0343
0344 for (auto &iter : m_TpcTimeFrameBuilderMap)
0345 {
0346 iter.second->CleanupUsedPackets(bclk);
0347 }
0348 }
0349
0350 void SingleTpcTimeFrameInput::ClearCurrentEvent()
0351 {
0352 std::cout << "SingleTpcTimeFrameInput::ClearCurrentEvent() - deprecated " << std::endl;
0353 exit(1);
0354
0355
0356
0357
0358
0359
0360
0361 return;
0362 }
0363
0364 void SingleTpcTimeFrameInput::CreateDSTNode(PHCompositeNode *topNode)
0365 {
0366 PHNodeIterator iter(topNode);
0367 PHCompositeNode *dstNode = dynamic_cast<PHCompositeNode *>(iter.findFirst("PHCompositeNode", "DST"));
0368 if (!dstNode)
0369 {
0370 dstNode = new PHCompositeNode("DST");
0371 topNode->addNode(dstNode);
0372 }
0373 PHNodeIterator iterDst(dstNode);
0374 PHCompositeNode *detNode = dynamic_cast<PHCompositeNode *>(iterDst.findFirst("PHCompositeNode", "TPC"));
0375 if (!detNode)
0376 {
0377 detNode = new PHCompositeNode("TPC");
0378 dstNode->addNode(detNode);
0379 }
0380 TpcRawHitContainer *tpchitcont = findNode::getClass<TpcRawHitContainer>(detNode, m_rawHitContainerName);
0381 if (!tpchitcont)
0382 {
0383 tpchitcont = new TpcRawHitContainerv3();
0384 PHIODataNode<PHObject> *newNode = new PHIODataNode<PHObject>(tpchitcont, m_rawHitContainerName, "PHObject");
0385 detNode->addNode(newNode);
0386 }
0387 }
0388
0389 void SingleTpcTimeFrameInput::ConfigureStreamingInputManager()
0390 {
0391 if (StreamingInputManager())
0392 {
0393 StreamingInputManager()->SetTpcBcoRange(m_BcoRange);
0394 StreamingInputManager()->SetTpcNegativeBco(m_NegativeBco);
0395 }
0396 return;
0397 }