File indexing completed on 2025-08-06 08:17:19
0001 #include "Fun4AllPrdfInputPoolManager.h"
0002
0003 #include "SinglePrdfInput.h"
0004
0005 #include <fun4all/Fun4AllInputManager.h> // for Fun4AllInputManager
0006 #include <fun4all/Fun4AllReturnCodes.h>
0007 #include <fun4all/Fun4AllServer.h>
0008
0009 #include <ffaobjects/SyncObject.h> // for SyncObject
0010 #include <ffaobjects/SyncObjectv1.h>
0011
0012 #include <phool/PHCompositeNode.h>
0013 #include <phool/PHDataNode.h>
0014 #include <phool/PHNode.h> // for PHNode
0015 #include <phool/PHNodeIterator.h> // for PHNodeIterator
0016 #include <phool/PHObject.h> // for PHObject
0017 #include <phool/phool.h> // for PHWHERE
0018
0019 #include <Event/A_Event.h>
0020 #include <Event/Event.h>
0021 #include <Event/oEvent.h>
0022 #include <Event/packet.h>
0023
0024 #include <cassert>
0025 #include <climits>
0026 #include <cstdlib>
0027 #include <iostream> // for operator<<, basic_ostream, endl
0028 #include <utility> // for pair
0029
0030 Fun4AllPrdfInputPoolManager::Fun4AllPrdfInputPoolManager(const std::string &name, const std::string &prdfnodename, const std::string &topnodename)
0031 : Fun4AllInputManager(name, prdfnodename, topnodename)
0032 , m_SyncObject(new SyncObjectv1())
0033 , m_PrdfNodeName(prdfnodename)
0034 {
0035 Fun4AllServer *se = Fun4AllServer::instance();
0036 m_topNode = se->topNode(TopNodeName());
0037 PHNodeIterator iter(m_topNode);
0038 PHDataNode<Event> *PrdfNode = dynamic_cast<PHDataNode<Event> *>(iter.findFirst("PHDataNode", m_PrdfNodeName));
0039 if (!PrdfNode)
0040 {
0041 PHDataNode<Event> *newNode = new PHDataNode<Event>(m_Event, m_PrdfNodeName, "Event");
0042 m_topNode->addNode(newNode);
0043 }
0044 oph = new oEvent(workmem, 4 * 1024 * 1024, 1, 1, 1);
0045 return;
0046 }
0047
0048 Fun4AllPrdfInputPoolManager::~Fun4AllPrdfInputPoolManager()
0049 {
0050 if (IsOpen())
0051 {
0052 fileclose();
0053 }
0054 delete m_SyncObject;
0055 for (auto iter : m_PrdfInputVector)
0056 {
0057 delete iter;
0058 }
0059 for (const auto &pktinfoiter : m_PacketMap)
0060 {
0061 for (auto const &pktiter : pktinfoiter.second.PacketVector)
0062 {
0063 delete pktiter;
0064 }
0065 }
0066 delete oph;
0067 }
0068
0069 int Fun4AllPrdfInputPoolManager::run(const int )
0070 {
0071 if (m_StartUpFlag)
0072 {
0073 for (auto iter : m_PrdfInputVector)
0074 {
0075 iter->FillPool(m_InitialPoolDepth);
0076 m_RunNumber = iter->RunNumber();
0077 }
0078 CreateBclkOffsets();
0079 m_StartUpFlag = false;
0080 }
0081 bool event_ok = false;
0082 while (!event_ok)
0083 {
0084 event_ok = true;
0085 if (m_PacketMap.size() < m_PoolDepth)
0086 {
0087 for (auto iter : m_PrdfInputVector)
0088 {
0089 iter->FillPool(m_PoolDepth);
0090 m_RunNumber = iter->RunNumber();
0091 }
0092 SetRunNumber(m_RunNumber);
0093 }
0094
0095 if (m_PacketMap.empty())
0096 {
0097 std::cout << "we are done" << std::endl;
0098 return -1;
0099 }
0100
0101 auto pktinfoiter = m_PacketMap.begin();
0102 int eventnumber = pktinfoiter->first;
0103
0104
0105 if (m_RefClockCounters.find(eventnumber) == m_RefClockCounters.end())
0106 {
0107 event_ok = false;
0108 DitchEvent(eventnumber);
0109 }
0110 else
0111 {
0112 int refclock = m_RefClockCounters[eventnumber];
0113 for (auto veciter : m_ClockCounters[eventnumber])
0114 {
0115 int diffclock = CalcDiffBclk(veciter.first, refclock);
0116 if (diffclock != m_SinglePrdfInputInfo[veciter.second].bclkoffset)
0117 {
0118 std::cout << "Houston we have a problem with event " << eventnumber << std::endl;
0119 std::cout << "name " << veciter.second->Name() << ", diffclk: 0x" << std::hex
0120 << diffclock << ", my bclk: 0x" << veciter.first
0121 << ", ref clk: 0x" << refclock << std::dec << std::endl;
0122 Resynchronize();
0123 event_ok = false;
0124 break;
0125 }
0126 }
0127 }
0128 }
0129 auto pktinfoiter = m_PacketMap.begin();
0130 oph->prepare_next(pktinfoiter->first, m_RunNumber);
0131
0132 for (auto &pktiter : pktinfoiter->second.PacketVector)
0133 {
0134 oph->addPacket(pktiter);
0135 }
0136 m_Event = new A_Event(workmem);
0137 if (Verbosity() > 1)
0138 {
0139 m_Event->identify();
0140 }
0141 PHNodeIterator iter(m_topNode);
0142 PHDataNode<Event> *PrdfNode = dynamic_cast<PHDataNode<Event> *>(iter.findFirst("PHDataNode", m_PrdfNodeName));
0143 PrdfNode->setData(m_Event);
0144 for (auto &pktiter : pktinfoiter->second.PacketVector)
0145 {
0146 delete pktiter;
0147 }
0148 m_ClockCounters.erase(pktinfoiter->first);
0149 m_RefClockCounters.erase(pktinfoiter->first);
0150 m_PacketMap.erase(pktinfoiter);
0151 return 0;
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228 }
0229
0230 int Fun4AllPrdfInputPoolManager::fileclose()
0231 {
0232 for (auto iter : m_PrdfInputVector)
0233 {
0234 delete iter;
0235 }
0236 m_PrdfInputVector.clear();
0237 return 0;
0238 }
0239
0240 void Fun4AllPrdfInputPoolManager::Print(const std::string &what) const
0241 {
0242
0243 if (what == "ALL" || what == "DROPPED")
0244 {
0245 std::cout << "-----------------------------" << std::endl;
0246 std::cout << "dropped packets:" << std::endl;
0247 for (auto iter : m_DroppedPacketMap)
0248 {
0249 std::cout << "Packet " << iter.first << " was dropped " << iter.second << " times" << std::endl;
0250 }
0251 }
0252 return;
0253 }
0254
0255 int Fun4AllPrdfInputPoolManager::ResetEvent()
0256 {
0257 PHNodeIterator iter(m_topNode);
0258 PHDataNode<Event> *PrdfNode = dynamic_cast<PHDataNode<Event> *>(iter.findFirst("PHDataNode", m_PrdfNodeName));
0259 PrdfNode->setData(nullptr);
0260 delete m_Event;
0261 m_Event = nullptr;
0262
0263 return 0;
0264 }
0265
0266 int Fun4AllPrdfInputPoolManager::PushBackEvents(const int )
0267 {
0268 return 0;
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319 }
0320
0321 int Fun4AllPrdfInputPoolManager::GetSyncObject(SyncObject **mastersync)
0322 {
0323
0324
0325
0326
0327 if (!(*mastersync))
0328 {
0329 if (m_SyncObject)
0330 {
0331 *mastersync = dynamic_cast<SyncObject *>(m_SyncObject->CloneMe());
0332 assert(*mastersync);
0333 }
0334 }
0335 else
0336 {
0337 *(*mastersync) = *m_SyncObject;
0338 }
0339 return Fun4AllReturnCodes::SYNC_OK;
0340 }
0341
0342 int Fun4AllPrdfInputPoolManager::SyncIt(const SyncObject *mastersync)
0343 {
0344 if (!mastersync)
0345 {
0346 std::cout << PHWHERE << Name() << " No MasterSync object, cannot perform synchronization" << std::endl;
0347 std::cout << "Most likely your first file does not contain a SyncObject and the file" << std::endl;
0348 std::cout << "opened by the Fun4AllDstInputManager with Name " << Name() << " has one" << std::endl;
0349 std::cout << "Change your macro and use the file opened by this input manager as first input" << std::endl;
0350 std::cout << "and you will be okay. Fun4All will not process the current configuration" << std::endl
0351 << std::endl;
0352 return Fun4AllReturnCodes::SYNC_FAIL;
0353 }
0354 int iret = m_SyncObject->Different(mastersync);
0355 if (iret)
0356 {
0357 std::cout << "big problem" << std::endl;
0358 exit(1);
0359 }
0360 return Fun4AllReturnCodes::SYNC_OK;
0361 }
0362
0363 std::string Fun4AllPrdfInputPoolManager::GetString(const std::string &what) const
0364 {
0365 if (what == "PRDFNODENAME")
0366 {
0367 return m_PrdfNodeName;
0368 }
0369 return "";
0370 }
0371
0372 SinglePrdfInput *Fun4AllPrdfInputPoolManager::AddPrdfInputFile(const std::string &filenam)
0373 {
0374 SinglePrdfInput *prdfin = new SinglePrdfInput("PRDFIN_" + std::to_string(m_PrdfInputVector.size()), this);
0375 prdfin->AddFile(filenam);
0376 m_PrdfInputVector.push_back(prdfin);
0377 return m_PrdfInputVector.back();
0378 }
0379
0380 SinglePrdfInput *Fun4AllPrdfInputPoolManager::AddPrdfInputList(const std::string &filenam)
0381 {
0382 SinglePrdfInput *prdfin = new SinglePrdfInput("PRDFIN_" + std::to_string(m_PrdfInputVector.size()), this);
0383 prdfin->AddListFile(filenam);
0384 m_PrdfInputVector.push_back(prdfin);
0385 return m_PrdfInputVector.back();
0386 }
0387
0388 SinglePrdfInput *Fun4AllPrdfInputPoolManager::registerPrdfInput(SinglePrdfInput *prdfin)
0389 {
0390 m_PrdfInputVector.push_back(prdfin);
0391 return m_PrdfInputVector.back();
0392 }
0393
0394 void Fun4AllPrdfInputPoolManager::AddPacket(const int evtno, Packet *p)
0395 {
0396 if (Verbosity() > 1)
0397 {
0398 std::cout << "Adding packet " << p->getIdentifier() << " to event no " << evtno << std::endl;
0399 }
0400 m_PacketMap[evtno].PacketVector.push_back(p);
0401 }
0402
0403 void Fun4AllPrdfInputPoolManager::AddBeamClock(const int evtno, const int bclk, SinglePrdfInput *prdfin)
0404 {
0405 if (Verbosity() > 1)
0406 {
0407 std::cout << "Adding event " << evtno << ", clock 0x" << std::hex << bclk << std::dec
0408 << " snglinput: " << prdfin->Name() << std::endl;
0409 }
0410 m_ClockCounters[evtno].push_back(std::make_pair(bclk, prdfin));
0411 }
0412
0413 void Fun4AllPrdfInputPoolManager::UpdateEventFoundCounter(const int evtno)
0414 {
0415 m_PacketMap[evtno].EventFoundCounter++;
0416 }
0417
0418 void Fun4AllPrdfInputPoolManager::UpdateDroppedPacket(const int packetid)
0419 {
0420 m_DroppedPacketMap[packetid]++;
0421 }
0422
0423 void Fun4AllPrdfInputPoolManager::SetReferenceClock(const int evtno, const int bclk)
0424 {
0425 m_RefClockCounters[evtno] = bclk;
0426 }
0427
0428 void Fun4AllPrdfInputPoolManager::CreateBclkOffsets()
0429 {
0430 if (!m_RefPrdfInput)
0431 {
0432 std::cout << PHWHERE << " No reference input manager given" << std::endl;
0433 exit(1);
0434 }
0435 std::map<SinglePrdfInput *, std::map<int, int>> clockcounters;
0436 for (const auto &iter : m_ClockCounters)
0437 {
0438 int refclock = m_RefClockCounters[iter.first];
0439 for (auto veciter : iter.second)
0440 {
0441 int diffclk = CalcDiffBclk(veciter.first, refclock);
0442 if (Verbosity() > 1)
0443 {
0444 std::cout << "diffclk for " << veciter.second->Name() << ": " << std::hex
0445 << diffclk << ", clk: 0x" << veciter.first
0446 << ", refclk: 0x" << refclock << std::dec << std::endl;
0447 }
0448 auto clkiter = clockcounters.find(veciter.second);
0449 if (clkiter == clockcounters.end())
0450 {
0451 std::map<int, int> mymap;
0452 clkiter = clockcounters.insert(std::make_pair(veciter.second, mymap)).first;
0453 }
0454 clkiter->second[diffclk]++;
0455 }
0456 }
0457
0458 for (const auto &iter : clockcounters)
0459 {
0460 int imax = -1;
0461 int diffmax = INT_MAX;
0462 for (auto initer : iter.second)
0463 {
0464 if (Verbosity() > 0)
0465 {
0466 std::cout << iter.first->Name() << " initer.second " << initer.second << std::hex
0467 << " initer.first: " << initer.first << std::dec << std::endl;
0468 }
0469 if (initer.second > imax)
0470 {
0471 diffmax = initer.first;
0472 imax = initer.second;
0473 }
0474 m_SinglePrdfInputInfo[iter.first].bclkoffset = diffmax;
0475 }
0476 }
0477 for (auto iter : m_SinglePrdfInputInfo)
0478 {
0479 if (Verbosity() > 0)
0480 {
0481 std::cout << "prdf mgr " << iter.first->Name() << " clkdiff: 0x" << std::hex
0482 << iter.second.bclkoffset << std::dec << std::endl;
0483 }
0484 }
0485 }
0486
0487 int Fun4AllPrdfInputPoolManager::CalcDiffBclk(const int bclk1, const int bclk2)
0488 {
0489 int diffclk = (bclk1 - bclk2) & 0xFFFF;
0490 return diffclk;
0491 }
0492
0493 void Fun4AllPrdfInputPoolManager::DitchEvent(const int eventno)
0494 {
0495 if (Verbosity() > 1)
0496 {
0497 std::cout << "Killing event " << eventno << std::endl;
0498 }
0499 m_ClockCounters.erase(eventno);
0500 m_RefClockCounters.erase(eventno);
0501 auto pktinfoiter = m_PacketMap.find(eventno);
0502 if (pktinfoiter == m_PacketMap.end())
0503 {
0504 return;
0505 }
0506 for (auto const &pktiter : pktinfoiter->second.PacketVector)
0507 {
0508 delete pktiter;
0509 }
0510 m_PacketMap.erase(pktinfoiter);
0511 return;
0512 }
0513
0514 void Fun4AllPrdfInputPoolManager::Resynchronize()
0515 {
0516
0517 struct LocalInfo
0518 {
0519 int clockcounter;
0520 int eventdiff;
0521 };
0522 for (auto iter : m_PrdfInputVector)
0523 {
0524 iter->FillPool(10);
0525
0526 m_RunNumber = iter->RunNumber();
0527 }
0528 std::map<SinglePrdfInput *, LocalInfo> matchevent;
0529 std::vector<int> ditchevents;
0530 for (auto iter : m_RefClockCounters)
0531 {
0532 if (Verbosity() > 1)
0533 {
0534 std::cout << "looking for matching event " << iter.first
0535 << std::hex << " with clk 0x" << iter.second << std::dec << std::endl;
0536 }
0537 for (const auto &clockiter : m_ClockCounters)
0538 {
0539 if (Verbosity() > 1)
0540 {
0541 std::cout << "testing for matching with event " << clockiter.first << std::endl;
0542 }
0543 for (auto eventiter : clockiter.second)
0544 {
0545 int diffclock = CalcDiffBclk(eventiter.first, iter.second);
0546 if (Verbosity() > 1)
0547 {
0548 std::cout << "Event " << iter.first << " match with event " << clockiter.first
0549 << " clock 0x" << std::hex << eventiter.first << ", ref clock 0x" << iter.second
0550 << " diff 0x" << diffclock << std::dec
0551 << " for " << eventiter.second->Name() << std::endl;
0552 }
0553 if (diffclock == m_SinglePrdfInputInfo[eventiter.second].bclkoffset)
0554 {
0555 if (Verbosity() > 1)
0556 {
0557 std::cout << "looking good for " << eventiter.second->Name() << std::endl;
0558 }
0559 matchevent[eventiter.second].clockcounter = clockiter.first;
0560 matchevent[eventiter.second].eventdiff = clockiter.first - iter.first;
0561 }
0562 else
0563 {
0564 if (Verbosity() > 1)
0565 {
0566 std::cout << "not so great for " << eventiter.second->Name() << std::endl;
0567 }
0568 }
0569 }
0570 if (matchevent.size() == m_SinglePrdfInputInfo.size())
0571 {
0572 if (Verbosity() > 1)
0573 {
0574 std::cout << "found all matches" << std::endl;
0575 }
0576 break;
0577 }
0578 }
0579 if (matchevent.size() == m_SinglePrdfInputInfo.size())
0580 {
0581 if (Verbosity() > 1)
0582 {
0583 std::cout << "found all matches" << std::endl;
0584 }
0585 break;
0586 }
0587 ditchevents.push_back(iter.first);
0588 }
0589 for (auto ievent : ditchevents)
0590 {
0591 DitchEvent(ievent);
0592 }
0593 int minoffset = INT_MAX;
0594 for (auto matches : matchevent)
0595 {
0596 if (Verbosity() > 1)
0597 {
0598 std::cout << matches.first->Name() << " update event offset with: " << matches.second.eventdiff
0599 << ", current offset : " << matches.first->EventNumberOffset()
0600 << " would go to " << matches.first->EventNumberOffset() - matches.second.eventdiff << std::endl;
0601 }
0602 if (minoffset > matches.first->EventNumberOffset() - matches.second.eventdiff)
0603 {
0604 minoffset = matches.first->EventNumberOffset() - matches.second.eventdiff;
0605 }
0606 }
0607
0608 int addoffset = 0;
0609 if (minoffset < 0)
0610 {
0611 if (Verbosity() > 1)
0612 {
0613 std::cout << "minoffset < 0: " << minoffset << " this will be interesting" << std::endl;
0614 }
0615 addoffset = -minoffset;
0616 }
0617 for (auto matches : matchevent)
0618 {
0619 matches.first->EventNumberOffset(matches.first->EventNumberOffset() - matches.second.eventdiff + addoffset);
0620 if (Verbosity() > 1)
0621 {
0622 std::cout << matches.first->Name() << " update event offset to: " << matches.first->EventNumberOffset()
0623 << std::endl;
0624 }
0625 }
0626 ClearAllEvents();
0627 return;
0628 }
0629
0630 void Fun4AllPrdfInputPoolManager::ClearAllEvents()
0631 {
0632 for (const auto &pktinfoiter : m_PacketMap)
0633 {
0634 for (auto const &pktiter : pktinfoiter.second.PacketVector)
0635 {
0636 delete pktiter;
0637 }
0638 }
0639 m_ClockCounters.clear();
0640 m_RefClockCounters.clear();
0641 m_PacketMap.clear();
0642 }