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/DAQrate/EventStore.hh"
23 #include "artdaq-core/Core/SimpleQueueReader.hh"
24 #include "cetlib/container_algorithms.h"
25 #include "cetlib/filepath_maker.h"
26 #include "fhiclcpp/ParameterSet.h"
27 #include "fhiclcpp/make_ParameterSet.h"
28 #include "boost/program_options.hpp"
36 using namespace fhicl;
37 namespace bpo = boost::program_options;
39 volatile int events_to_generate;
40 void sig_handler(
int) { events_to_generate = -1; }
42 template<
typename B,
typename D>
44 dynamic_unique_ptr_cast(std::unique_ptr<B>& p);
46 int main(
int argc,
char * argv[])
try
48 std::ostringstream descstr;
50 <<
" <-c <config-file>> <other-options> [<source-file>]+";
51 bpo::options_description desc(descstr.str());
53 (
"config,c", bpo::value<std::string>(),
"Configuration file.")
54 (
"help,h",
"produce help message");
55 bpo::variables_map vm;
57 bpo::store(bpo::command_line_parser(argc, argv).options(desc).run(), vm);
60 catch (bpo::error
const & e) {
61 std::cerr <<
"Exception from command line processing in " << argv[0]
62 <<
": " << e.what() <<
"\n";
65 if (vm.count(
"help")) {
66 std::cout << desc << std::endl;
69 if (!vm.count(
"config")) {
70 std::cerr <<
"Exception from command line processing in " << argv[0]
71 <<
": no configuration file given.\n"
72 <<
"For usage and an options list, please do '"
73 << argv[0] <<
" --help"
78 if (getenv(
"FHICL_FILE_PATH") ==
nullptr) {
80 <<
"INFO: environment variable FHICL_FILE_PATH was not set. Using \".\"\n";
81 setenv(
"FHICL_FILE_PATH",
".", 0);
83 cet::filepath_lookup_after1 lookup_policy(
"FHICL_FILE_PATH");
84 make_ParameterSet(vm[
"config"].as<std::string>(), lookup_policy, pset);
86 int run = pset.get<
int>(
"run_number", 1);
87 uint64_t timeout = pset.get<uint64_t>(
"transition_timeout", 30);
88 uint64_t timestamp = 0;
90 ParameterSet fragment_receiver_pset = pset.get<ParameterSet>(
"fragment_receiver");
92 std::unique_ptr<artdaq::FragmentGenerator>
93 gen(artdaq::makeFragmentGenerator(fragment_receiver_pset.get<std::string>(
"generator"),
94 fragment_receiver_pset));
96 std::unique_ptr<artdaq::CommandableFragmentGenerator> commandable_gen =
100 artdaq::MetricManager metricMan_;
101 metricMan = &metricMan_;
104 fhicl::ParameterSet metric_pset;
106 metric_pset = pset.get<fhicl::ParameterSet>(
"metrics");
110 if (metric_pset.is_empty()) {
111 TLOG_INFO(
"artdaqDriver") <<
"No metric plugins appear to be defined" << TLOG_ENDL;
114 metricMan_.initialize(metric_pset,
"artdaqDriver");
115 metricMan_.do_start();
119 artdaq::FragmentPtrs frags;
124 ParameterSet event_builder_pset = pset.get<ParameterSet>(
"event_builder");
125 bool const want_artapp(event_builder_pset.get<
bool>(
"use_art",
false));
126 std::ostringstream os;
128 os << event_builder_pset.get<
int>(
"events_expected_in_SimpleQueueReader");
130 std::string
const oss(os.str());
131 const char * args[2]{
"SimpleQueueReader", oss.c_str() };
132 int es_argc(want_artapp ? argc : 2);
133 char **es_argv(want_artapp ? argv : const_cast<char**>(args));
135 es_fcn(want_artapp ? &artapp : &artdaq::simpleQueueReaderApp);
136 artdaq::EventStore store(event_builder_pset, event_builder_pset.get<
size_t>(
"expected_fragments_per_event"),
143 int events_to_generate = pset.get<
int>(
"events_to_generate", 0);
145 artdaq::Fragment::sequence_id_t previous_sequence_id = -1;
147 if (commandable_gen) {
148 commandable_gen->
StartCmd(run, timeout, timestamp);
151 TRACE( 50,
"driver main before store.startRun" );
152 store.startRun( run );
158 while ((commandable_gen && commandable_gen->
getNext(frags)) ||
159 (gen && gen->getNext(frags))) {
160 TRACE( 50,
"driver main: getNext returned frags.size()=%zd current event_count=%d"
161 ,frags.size(),event_count );
162 for (
auto & val : frags) {
163 if (val->sequenceID() != previous_sequence_id) {
165 previous_sequence_id = val->sequenceID();
167 if (events_to_generate != 0 && event_count > events_to_generate) {
168 if (commandable_gen) {
169 commandable_gen->
StopCmd(timeout, timestamp);
173 store.insert(std::move(val));
177 if (events_to_generate != 0 && event_count >= events_to_generate) {
178 if (commandable_gen) {
179 commandable_gen->
StopCmd(timeout, timestamp);
186 int readerReturnValue;
187 bool endSucceeded =
false;
188 int attemptsToEnd = 1;
189 endSucceeded = store.endOfData(readerReturnValue);
190 while (!endSucceeded && attemptsToEnd < 3) {
192 endSucceeded = store.endOfData(readerReturnValue);
195 std::cerr <<
"Failed to shut down the reader and the event store "
196 <<
"because the endOfData marker could not be pushed "
197 <<
"onto the queue." << std::endl;
200 metricMan_.do_stop();
201 return readerReturnValue;
203 catch (std::string & x)
205 cerr <<
"Exception (type string) caught in artdaqDriver: " << x <<
'\n';
208 catch (
char const * m)
210 cerr <<
"Exception (type char const*) caught in artdaqDriver: ";
217 cerr <<
"[the value was a null pointer, so no message is available]";
222 artdaq::ExceptionHandler(artdaq::ExceptionHandlerRethrow::no,
223 "Exception caught in artdaqDriver");
227 template<
typename B,
typename D>
229 dynamic_unique_ptr_cast(std::unique_ptr<B>& p)
231 D* result =
dynamic_cast<D*
>(p.get());
235 return std::unique_ptr<D>(result);
void StopCmd(uint64_t timeout, uint64_t timestamp)
Stop the CommandableFragmentGenerator.
void configureMessageFacility(char const *progname, bool useConsole=true)
Configure and start the message facility. Provide the program name so that messages will be appropria...
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...
The EventStore class collects Fragment objects, until it receives a complete event, at which point the event is handed over to the art thread.
int( ART_CMDLINE_FCN)(int, char **)
An art function that accepts standard C main arguments.
RawEvent::run_id_t run_id_t
Copy RawEvent::run_id_t into local scope.