12 #include "art/Framework/Art/artapp.h"
13 #include "artdaq-core/Generators/FragmentGenerator.hh"
14 #include "artdaq-core/Data/Fragment.hh"
15 #include "artdaq-core/Utilities/ExceptionHandler.hh"
16 #include "artdaq/DAQdata/GenericFragmentSimulator.hh"
18 #include "artdaq/DAQdata/Globals.hh"
19 #include "artdaq-core/Generators/makeFragmentGenerator.hh"
20 #include "artdaq/Application/makeCommandableFragmentGenerator.hh"
21 #include "artdaq-utilities/Plugins/MetricManager.hh"
22 #include "artdaq-core/Core/SimpleMemoryReader.hh"
23 #include "cetlib/filepath_maker.h"
24 #include "fhiclcpp/ParameterSet.h"
25 #include "fhiclcpp/make_ParameterSet.h"
26 #include <boost/program_options.hpp>
32 #include "artdaq/DAQrate/SharedMemoryEventManager.hh"
33 #include "artdaq/Application/LoadParameterSet.hh"
35 namespace bpo = boost::program_options;
37 volatile int events_to_generate;
38 void sig_handler(
int) { events_to_generate = -1; }
40 template<
typename B,
typename D>
42 dynamic_unique_ptr_cast(std::unique_ptr<B>& p);
44 int main(
int argc,
char * argv[])
try
46 auto pset = LoadParameterSet(argc, argv);
48 int run = pset.get<
int>(
"run_number", 1);
49 bool debug = pset.get<
bool>(
"debug_cout",
false);
50 uint64_t timeout = pset.get<uint64_t>(
"transition_timeout", 30);
51 uint64_t timestamp = 0;
53 artdaq::configureMessageFacility(
"artdaqDriver",
true,debug);
55 fhicl::ParameterSet fragment_receiver_pset = pset.get<fhicl::ParameterSet>(
"fragment_receiver");
57 std::unique_ptr<artdaq::FragmentGenerator>
58 gen(artdaq::makeFragmentGenerator(fragment_receiver_pset.get<std::string>(
"generator"),
59 fragment_receiver_pset));
61 std::unique_ptr<artdaq::CommandableFragmentGenerator> commandable_gen =
64 artdaq::MetricManager metricMan_;
65 metricMan = &metricMan_;
68 fhicl::ParameterSet metric_pset;
70 metric_pset = pset.get<fhicl::ParameterSet>(
"metrics");
74 if (metric_pset.is_empty()) {
75 TLOG_INFO(
"artdaqDriver") <<
"No metric plugins appear to be defined" << TLOG_ENDL;
78 metricMan_.initialize(metric_pset,
"artdaqDriver");
79 metricMan_.do_start();
83 artdaq::FragmentPtrs frags;
88 fhicl::ParameterSet event_builder_pset = pset.get<fhicl::ParameterSet>(
"event_builder");
93 int events_to_generate = pset.get<
int>(
"events_to_generate", 0);
95 artdaq::Fragment::sequence_id_t previous_sequence_id = -1;
97 if (commandable_gen) {
98 commandable_gen->
StartCmd(run, timeout, timestamp);
101 TLOG_ARB(50,
"artdaqDriver") <<
"driver main before store.startRun" << TLOG_ENDL;
108 while ((commandable_gen && commandable_gen->
getNext(frags)) ||
109 (gen && gen->getNext(frags))) {
110 TLOG_ARB(50,
"artdaqDriver") <<
"driver main: getNext returned frags.size()=" << std::to_string(frags.size()) <<
" current event_count=" << event_count << TLOG_ENDL;
111 for (
auto & val : frags) {
112 if (val->sequenceID() != previous_sequence_id) {
114 previous_sequence_id = val->sequenceID();
116 if (events_to_generate != 0 && event_count > events_to_generate) {
117 if (commandable_gen) {
118 commandable_gen->
StopCmd(timeout, timestamp);
122 artdaq::FragmentPtr tempFrag;
123 auto sts = store.AddFragment(std::move(val), 1000000, tempFrag);
126 TLOG_ERROR(
"artdaqDriver") <<
"Fragment was not added after 1s. Check art thread status!" << TLOG_ENDL;
132 if (events_to_generate != 0 && event_count >= events_to_generate) {
133 if (commandable_gen) {
134 commandable_gen->
StopCmd(timeout, timestamp);
140 if (commandable_gen) {
144 bool endSucceeded =
false;
145 int attemptsToEnd = 1;
146 endSucceeded = store.endOfData();
147 while (!endSucceeded && attemptsToEnd < 3) {
149 endSucceeded = store.endOfData();
152 std::cerr <<
"Failed to shut down the reader and the event store "
153 <<
"because the endOfData marker could not be pushed "
154 <<
"onto the queue." << std::endl;
157 metricMan_.do_stop();
160 catch (std::string & x)
162 std::cerr <<
"Exception (type string) caught in artdaqDriver: " << x <<
'\n';
165 catch (
char const * m)
167 std::cerr <<
"Exception (type char const*) caught in artdaqDriver: ";
174 std::cerr <<
"[the value was a null pointer, so no message is available]";
179 artdaq::ExceptionHandler(artdaq::ExceptionHandlerRethrow::no,
180 "Exception caught in artdaqDriver");
184 template<
typename B,
typename D>
186 dynamic_unique_ptr_cast(std::unique_ptr<B>& p)
188 D* result =
dynamic_cast<D*
>(p.get());
192 return std::unique_ptr<D>(result);
The SharedMemoryEventManager is a SharedMemoryManger which tracks events as they are built...
void StopCmd(uint64_t timeout, uint64_t timestamp)
Stop the CommandableFragmentGenerator.
void StartCmd(int run, uint64_t timeout, uint64_t timestamp)
Start the CommandableFragmentGenerator.
bool getNext(FragmentPtrs &output) overridefinal
getNext calls either applyRequests or getNext_ to get any data that is ready to be sent to the EventB...
CommandableFragmentGenerator is a FragmentGenerator-derived abstract class that defines the interface...
void joinThreads()
Join any data-taking threads. Should be called when destructing CommandableFragmentGenerator.