1 #include "art/Framework/Core/FileBlock.h"
2 #include "art/Framework/Core/InputSourceMacros.h"
3 #include "art/Framework/Core/ProductRegistryHelper.h"
4 #include "art/Framework/IO/Sources/Source.h"
5 #include "art/Framework/IO/Sources/SourceHelper.h"
6 #include "art/Framework/IO/Sources/SourceTraits.h"
7 #include "art/Framework/Services/Registry/ServiceHandle.h"
9 #include "art/Persistency/Provenance/BranchIDListHelper.h"
10 #include "art/Persistency/Provenance/BranchIDListRegistry.h"
11 #include "art/Persistency/Provenance/MasterProductRegistry.h"
12 #include "art/Persistency/Provenance/ProcessHistoryRegistry.h"
13 #include "art/Persistency/Provenance/ProductMetaData.h"
15 #include "canvas/Persistency/Common/EDProduct.h"
16 #include "canvas/Persistency/Common/Wrapper.h"
17 #include "canvas/Persistency/Provenance/BranchDescription.h"
18 #include "canvas/Persistency/Provenance/BranchIDList.h"
19 #include "canvas/Persistency/Provenance/BranchKey.h"
20 #include "canvas/Persistency/Provenance/History.h"
21 #include "canvas/Persistency/Provenance/ParentageRegistry.h"
22 #include "canvas/Persistency/Provenance/ProcessConfiguration.h"
23 #include "canvas/Persistency/Provenance/ProcessHistory.h"
24 #include "canvas/Persistency/Provenance/ProcessHistoryID.h"
25 #include "canvas/Persistency/Provenance/ProductList.h"
26 #include "canvas/Persistency/Provenance/ProductProvenance.h"
27 #include "canvas/Utilities/DebugMacros.h"
29 #include "fhiclcpp/make_ParameterSet.h"
30 #include "fhiclcpp/ParameterSet.h"
31 #include "fhiclcpp/ParameterSetID.h"
32 #include "fhiclcpp/ParameterSetRegistry.h"
36 #include "TBufferFile.h"
38 #include "artdaq/ArtModules/InputUtilities.hh"
39 #include "artdaq-core/Utilities/ExceptionHandler.hh"
107 ArtdaqInput(
const fhicl::ParameterSet& ps, art::ProductRegistryHelper& helper,
108 const art::SourceHelper& pm);
119 void readFile(
const std::string&, art::FileBlock*& fb);
136 bool readNext(art::RunPrincipal*
const inR,
137 art::SubRunPrincipal*
const inSR, art::RunPrincipal*& outR,
138 art::SubRunPrincipal*& outSR, art::EventPrincipal*& outE);
142 readAndConstructPrincipal(std::unique_ptr<TBufferFile>&,
144 art::RunPrincipal*
const,
145 art::SubRunPrincipal*
const,
147 art::SubRunPrincipal*&,
148 art::EventPrincipal*&);
151 void readDataProducts(std::unique_ptr<TBufferFile>&, T*&);
153 void putInPrincipal(RunPrincipal*&, std::unique_ptr<EDProduct>&&,
const BranchDescription&, std::unique_ptr<const ProductProvenance>&&);
155 void putInPrincipal(SubRunPrincipal*&, std::unique_ptr<EDProduct>&&,
const BranchDescription&, std::unique_ptr<const ProductProvenance>&&);
157 void putInPrincipal(EventPrincipal*&, std::unique_ptr<EDProduct>&&,
const BranchDescription&, std::unique_ptr<const ProductProvenance>&&);
161 bool shutdownMsgReceived_;
162 bool outputFileCloseNeeded_;
163 const art::SourceHelper& pm_;
164 U communicationWrapper_;
167 template <
typename U>
170 art::ProductRegistryHelper& helper,
171 const art::SourceHelper& pm)
172 : shutdownMsgReceived_(false)
173 , outputFileCloseNeeded_(false)
175 , communicationWrapper_(ps)
184 TLOG_DEBUG(
"ArtdaqInput") <<
"Begin: ArtdaqInput::ArtdaqInput(" \
185 "const fhicl::ParameterSet& ps, " \
186 "art::ProductRegistryHelper& helper, " \
187 "const art::SourceHelper& pm)\n";
191 std::unique_ptr<TBufferFile> msg(
nullptr);
192 communicationWrapper_.receiveMessage(msg);
196 throw art::Exception(art::errors::DataCorruption) <<
197 "ArtdaqInput: Could not receive message!";
201 unsigned long dummy = 0;
202 msg->ReadULong(dummy);
207 unsigned long ps_cnt = 0;
208 msg->ReadULong(ps_cnt);
210 TLOG_DEBUG(
"ArtdaqInput") <<
"ArtdaqInput: parameter set count: " << ps_cnt;
211 TLOG_DEBUG(
"ArtdaqInput") <<
"ArtdaqInput: reading parameter sets ...";
213 for (
unsigned long I = 0; I < ps_cnt; ++I)
215 std::string pset_str =
"";
216 msg->ReadStdString(pset_str);
219 TLOG_DEBUG(
"ArtdaqInput") <<
"ArtdaqInput: parameter set: " << pset_str;
222 fhicl::ParameterSet pset;
223 fhicl::make_ParameterSet(pset_str, pset);
226 fhicl::ParameterSetRegistry::put(pset);
229 TLOG_DEBUG(
"ArtdaqInput") <<
"ArtdaqInput: finished reading parameter sets.\n";
235 art::ProductList* productlist = ReadObjectAny<art::ProductList>(msg,
"std::map<art::BranchKey,art::BranchDescription>",
"ArtdaqInput::ArtdaqInput");
236 helper.productList(productlist);
239 TLOG_DEBUG(
"ArtdaqInput") <<
"ArtdaqInput: got product list\n";
241 if (art::debugit() >= 1)
244 TLOG_DEBUG(
"ArtdaqInput") <<
"ArtdaqInput: before BranchIDLists\n";
246 BranchIDLists* bil = &BranchIDListRegistry::instance()->data();
247 int max_bli = bil->size();
249 TLOG_DEBUG(
"ArtdaqInput") <<
"ArtdaqInput: max_bli: " << max_bli <<
'\n';
251 for (
int i = 0; i < max_bli; ++i)
253 int max_prdidx = (*bil)[i].size();
255 TLOG_DEBUG(
"ArtdaqInput") <<
"ArtdaqInput: max_prdidx: "
256 << max_prdidx <<
'\n';
258 for (
int j = 0; j < max_prdidx; ++j)
261 TLOG_DEBUG(
"ArtdaqInput") <<
"ArtdaqInput:"
268 <<
static_cast<unsigned long>((*bil)[i][j])
276 art::ProcessHistoryMap* phm = ReadObjectAny<art::ProcessHistoryMap>(msg,
"std::map<const art::Hash<2>,art::ProcessHistory>",
"ArtdaqInput::ArtdaqInput");
280 ProcessHistoryRegistry::put(*phm);
282 printProcessMap(ProcessHistoryRegistry::get(),
"ArtdaqInput's ProcessHistoryRegistry");
287 art::ParentageMap* parentageMap = ReadObjectAny<art::ParentageMap>(msg,
"std::map<const art::Hash<5>,art::Parentage>",
"ArtdaqInput::ArtdaqInput");
290 TLOG_DEBUG(
"ArtdaqInput") <<
"ArtdaqInput: got ParentageMap\n";
292 ParentageRegistry::put(*parentageMap);
297 TLOG_DEBUG(
"ArtdaqInput") <<
"End: ArtdaqInput::ArtdaqInput("
298 "const fhicl::ParameterSet& ps, "
299 "art::ProductRegistryHelper& helper, "
300 "const art::SourceHelper& pm)\n";
304 template <
typename U>
308 template <
typename U>
314 TLOG_DEBUG(
"ArtdaqInput") <<
"Begin/End: ArtdaqInput::closeCurrentFile()\n";
318 template <
typename U>
324 TLOG_DEBUG(
"ArtdaqInput") <<
"Begin: ArtdaqInput::"
325 "readFile(const std::string& name, art::FileBlock*& fb)\n";
327 fb =
new art::FileBlock(art::FileFormatVersion(1,
"ArtdaqInput2013"),
330 TLOG_DEBUG(
"ArtdaqInput") <<
"End: ArtdaqInput::"
331 "readFile(const std::string& name, art::FileBlock*& fb)\n";
335 template <
typename U>
341 TLOG_DEBUG(
"ArtdaqInput") <<
"Begin: ArtdaqInput::hasMoreData()\n";
343 if (shutdownMsgReceived_)
346 TLOG_DEBUG(
"ArtdaqInput") <<
"ArtdaqInput::hasMoreData(): "
347 "returning false on shutdownMsgReceived_.\n";
348 TLOG_DEBUG(
"ArtdaqInput") <<
"End: ArtdaqInput::hasMoreData()\n";
353 TLOG_DEBUG(
"ArtdaqInput") <<
"ArtdaqInput::hasMoreData(): "
354 "returning true on not shutdownMsgReceived_.\n";
355 TLOG_DEBUG(
"ArtdaqInput") <<
"End: ArtdaqInput::hasMoreData()\n";
360 template <
typename U>
364 unsigned long msg_type_code,
365 art::RunPrincipal*
const inR,
366 art::SubRunPrincipal*
const inSR,
367 art::RunPrincipal*& outR,
368 art::SubRunPrincipal*& outSR,
369 art::EventPrincipal*& outE)
374 std::unique_ptr<art::RunAuxiliary> run_aux;
375 std::unique_ptr<art::SubRunAuxiliary> subrun_aux;
376 std::unique_ptr<art::EventAuxiliary> event_aux;
377 std::shared_ptr<History> history;
379 if (msg_type_code == 2)
383 TLOG_DEBUG(
"ArtdaqInput") <<
"readAndConstructPrincipal: "
384 "processing EndRun message ...\n";
387 run_aux.reset(ReadObjectAny<art::RunAuxiliary>(msg,
"art::RunAuxiliary",
388 "ArtdaqInput::readAndConstructPrincipal"));
392 TLOG_DEBUG(
"ArtdaqInput") <<
"readAndConstructPrincipal: "
393 "making flush RunPrincipal ...\n";
395 outR = pm_.makeRunPrincipal(RunID::flushRun(), run_aux->beginTime());
398 TLOG_DEBUG(
"ArtdaqInput") <<
"readAndConstructPrincipal: "
399 "making flush SubRunPrincipal ...\n";
401 outSR = pm_.makeSubRunPrincipal(SubRunID::flushSubRun(),
402 run_aux->beginTime());
405 TLOG_DEBUG(
"ArtdaqInput") <<
"readAndConstructPrincipal: "
406 "making flush EventPrincipal ...\n";
408 outE = pm_.makeEventPrincipal(EventID::flushEvent(),
409 run_aux->endTime(),
true,
410 EventAuxiliary::Any);
413 TLOG_DEBUG(
"ArtdaqInput") <<
"readAndConstructPrincipal: "
414 "finished processing EndRun message.\n";
417 else if (msg_type_code == 3)
421 TLOG_DEBUG(
"ArtdaqInput") <<
"readAndConstructPrincipal: "
422 "processing EndSubRun message ...\n";
425 subrun_aux.reset(ReadObjectAny<art::SubRunAuxiliary>(msg,
"art::SubRunAuxiliary",
426 "ArtdaqInput::readAndConstructPrincipal"));
430 TLOG_DEBUG(
"ArtdaqInput") <<
"readAndConstructPrincipal: "
431 "making flush RunPrincipal ...\n";
433 outR = pm_.makeRunPrincipal(RunID::flushRun(), subrun_aux->beginTime());
450 art::Timestamp currentTime = time(0);
451 if (inR !=
nullptr) { inR->setEndTime(currentTime); }
452 if (inSR !=
nullptr) { inSR->setEndTime(currentTime); }
455 TLOG_DEBUG(
"ArtdaqInput") <<
"readAndConstructPrincipal: "
456 "making flush SubRunPrincipal ...\n";
458 outSR = pm_.makeSubRunPrincipal(SubRunID::flushSubRun(),
459 subrun_aux->beginTime());
462 TLOG_DEBUG(
"ArtdaqInput") <<
"readAndConstructPrincipal: "
463 "making flush EventPrincipal ...\n";
465 outE = pm_.makeEventPrincipal(EventID::flushEvent(),
466 subrun_aux->endTime(),
true,
467 EventAuxiliary::Any);
470 TLOG_DEBUG(
"ArtdaqInput") <<
"readAndConstructPrincipal: "
471 "finished processing EndSubRun message.\n";
474 else if (msg_type_code == 4)
478 TLOG_DEBUG(
"ArtdaqInput") <<
"readAndConstructPrincipal: "
479 "processing Event message ...\n";
482 run_aux.reset(ReadObjectAny<art::RunAuxiliary>(msg,
"art::RunAuxiliary",
483 "ArtdaqInput::readAndConstructPrincipal"));
486 subrun_aux.reset(ReadObjectAny<art::SubRunAuxiliary>(msg,
"art::SubRunAuxiliary",
487 "ArtdaqInput::readAndConstructPrincipal"));
490 event_aux.reset(ReadObjectAny<art::EventAuxiliary>(msg,
"art::EventAuxiliary",
491 "ArtdaqInput::readAndConstructPrincipal"));
493 history.reset(ReadObjectAny<art::History>(msg,
"art::History",
494 "ArtdaqInput::readAndConstructPrincipal"));
498 if (!history->processHistoryID().isValid())
500 throw art::Exception(art::errors::Unknown) <<
501 "readAndConstructPrincipal: processHistoryID of history in "
502 "Event message is invalid!";
505 if ((inR ==
nullptr) || !inR->id().isValid() ||
506 (inR->run() != event_aux->run()))
511 TLOG_DEBUG(
"ArtdaqInput") <<
"readAndConstructPrincipal: making RunPrincipal ...\n";
513 outR = pm_.makeRunPrincipal(*run_aux.get());
515 if ((inSR ==
nullptr) || !inSR->id().isValid() ||
516 (inSR->subRun() != event_aux->subRun()))
521 TLOG_DEBUG(
"ArtdaqInput") <<
"readAndConstructPrincipal: "
522 "making SubRunPrincipal ...\n";
524 outSR = pm_.makeSubRunPrincipal(*subrun_aux.get());
527 TLOG_DEBUG(
"ArtdaqInput") <<
"readAndConstructPrincipal: making EventPrincipal ...\n";
529 outE = pm_.makeEventPrincipal(*event_aux.get(), std::move(history));
532 TLOG_DEBUG(
"ArtdaqInput") <<
"readAndConstructPrincipal: "
533 "finished processing Event message.\n";
538 template <
typename U>
544 unsigned long prd_cnt = 0;
547 TLOG_DEBUG(
"ArtdaqInput") <<
"readDataProducts: reading data product count ...\n";
549 msg->ReadULong(prd_cnt);
551 TLOG_DEBUG(
"ArtdaqInput") <<
"readDataProducts: product count: " << prd_cnt <<
'\n';
557 const ProductList& productList = ProductMetaData::instance().productList();
559 for (
unsigned long I = 0; I < prd_cnt; ++I)
561 std::unique_ptr<BranchKey> bk;
565 TLOG_DEBUG(
"ArtdaqInput") <<
"readDataProducts: Reading branch key.\n";
567 bk.reset(ReadObjectAny<BranchKey>(msg,
"art::BranchKey",
568 "ArtdaqInput::readDataProducts"));
571 if (art::debugit() >= 1)
574 TLOG_DEBUG(
"ArtdaqInput") <<
"readDataProducts: got product class: '"
575 << bk->friendlyClassName_
579 << bk->productInstanceName_
585 ProductList::const_iterator iter;
588 TLOG_DEBUG(
"ArtdaqInput") <<
"readDataProducts: looking up product ...\n";
590 iter = productList.find(*bk);
591 if (iter == productList.end())
593 throw art::Exception(art::errors::ProductNotFound)
594 <<
"No product is registered for\n"
595 <<
" process name: '"
596 << bk->processName_ <<
"'\n"
597 <<
" module label: '"
598 << bk->moduleLabel_ <<
"'\n"
599 <<
" product friendly class name: '"
600 << bk->friendlyClassName_ <<
"'\n"
601 <<
" product instance name: '"
602 << bk->productInstanceName_ <<
"'\n";
607 const BranchDescription& bd = iter->second;
608 std::unique_ptr<EDProduct> prd;
611 TLOG_DEBUG(
"ArtdaqInput") <<
"readDataProducts: Reading product.\n";
619 void* p = msg->ReadObjectAny(TClass::GetClass(bd.wrappedName().c_str()));
621 prd.reset(reinterpret_cast<EDProduct*>(p));
624 std::unique_ptr<const ProductProvenance> prdprov;
627 TLOG_DEBUG(
"ArtdaqInput") <<
"readDataProducts: Reading product provenance.\n";
629 prdprov.reset(ReadObjectAny<ProductProvenance>(msg,
630 "art::ProductProvenance",
631 "ArtdaqInput::readDataProducts"));
635 TLOG_DEBUG(
"ArtdaqInput") <<
"readDataProducts: inserting product: class: '"
636 << bd.friendlyClassName()
640 << bd.productInstanceName()
645 putInPrincipal(outPrincipal, std::move(prd), bd, std::move(prdprov));
650 template <
typename U>
653 putInPrincipal(RunPrincipal*& rp, std::unique_ptr<EDProduct>&& prd,
const BranchDescription& bd, std::unique_ptr<const ProductProvenance>&& prdprov)
655 rp->put(std::move(prd), bd, std::move(prdprov), RangeSet::forRun(rp->id()));
658 template <
typename U>
661 putInPrincipal(SubRunPrincipal*& srp, std::unique_ptr<EDProduct>&& prd,
const BranchDescription& bd, std::unique_ptr<const ProductProvenance>&& prdprov)
663 srp->put(std::move(prd), bd, std::move(prdprov), RangeSet::forSubRun(srp->id()));
666 template <
typename U>
669 putInPrincipal(EventPrincipal*& ep, std::unique_ptr<EDProduct>&& prd,
const BranchDescription& bd, std::unique_ptr<const ProductProvenance>&& prdprov)
671 ep->put(std::move(prd), bd, std::move(prdprov));
675 template <
typename U>
678 readNext(art::RunPrincipal*
const inR, art::SubRunPrincipal*
const inSR,
679 art::RunPrincipal*& outR, art::SubRunPrincipal*& outSR,
680 art::EventPrincipal*& outE)
683 TLOG_DEBUG(
"ArtdaqInput") <<
"Begin: ArtdaqInput::readNext\n";
685 if (outputFileCloseNeeded_)
687 outputFileCloseNeeded_ =
false;
691 TLOG_DEBUG(
"ArtdaqInput") <<
"ArtdaqInput::readNext: "
692 "returning false on outputFileCloseNeeded_\n";
693 TLOG_DEBUG(
"ArtdaqInput") <<
"End: ArtdaqInput::readNext\n";
698 std::unique_ptr<TBufferFile> msg;
699 communicationWrapper_.receiveMessage(msg);
703 shutdownMsgReceived_ =
true;
710 unsigned long msg_type_code = 0;
713 TLOG_DEBUG(
"ArtdaqInput") <<
"ArtdaqInput::readNext: "
714 "getting message type code ...\n";
716 msg->ReadULong(msg_type_code);
718 TLOG_DEBUG(
"ArtdaqInput") <<
"ArtdaqInput::readNext: "
719 "message type: " << msg_type_code <<
'\n';
722 if (msg_type_code == 5)
725 shutdownMsgReceived_ =
true;
727 TLOG_DEBUG(
"ArtdaqInput") <<
"ArtdaqInput::readNext: "
728 "returning false on Shutdown message.\n";
729 TLOG_DEBUG(
"ArtdaqInput") <<
"End: ArtdaqInput::readNext\n";
734 readAndConstructPrincipal(msg, msg_type_code, inR, inSR, outR,
739 if (msg_type_code == 2)
743 readDataProducts(msg, outR);
746 TLOG_DEBUG(
"ArtdaqInput") <<
"ArtdaqInput::readNext: "
747 "returning false on EndRun message.\n";
748 TLOG_DEBUG(
"ArtdaqInput") <<
"End: ArtdaqInput::readNext\n";
752 else if (msg_type_code == 3)
763 if (inR != 0 && inSR != 0 && outR != 0 && outSR != 0)
765 if (inR->id().isFlush() && inSR->id().isFlush() &&
766 outR->id().isFlush() && outSR->id().isFlush())
770 outputFileCloseNeeded_ =
true;
775 readDataProducts(msg, outSR);
778 outputFileCloseNeeded_ =
true;
780 TLOG_DEBUG(
"ArtdaqInput") <<
"readNext: returning true on EndSubRun message.\n";
781 TLOG_DEBUG(
"ArtdaqInput") <<
"End: ArtdaqInput::readNext\n";
785 else if (msg_type_code == 4)
788 readDataProducts(msg, outE);
790 TLOG_DEBUG(
"ArtdaqInput") <<
"readNext: returning true on Event message.\n";
791 TLOG_DEBUG(
"ArtdaqInput") <<
"End: ArtdaqInput::readNext\n";
798 TLOG_DEBUG(
"ArtdaqInput") <<
"readNext: returning false on unknown msg_type_code!\n";
799 TLOG_DEBUG(
"ArtdaqInput") <<
"End: ArtdaqInput::readNext\n";
void printProcessHistoryID(const std::string &label, const T &object)
Print the processHistoryID from the object.
void printProcessMap(const T &mappable, const std::string description)
Print data from a map-like class.