00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "art/Framework/Art/artapp.h"
00013 #include "artdaq-core/Generators/FragmentGenerator.hh"
00014 #include "artdaq-core/Data/Fragment.hh"
00015 #include "artdaq-core/Utilities/ExceptionHandler.hh"
00016 #include "artdaq/DAQdata/GenericFragmentSimulator.hh"
00017
00018 #include "artdaq/DAQdata/Globals.hh"
00019 #include "artdaq-core/Generators/makeFragmentGenerator.hh"
00020 #include "artdaq/Application/makeCommandableFragmentGenerator.hh"
00021 #include "artdaq-utilities/Plugins/MetricManager.hh"
00022 #include "artdaq/DAQrate/EventStore.hh"
00023 #include "artdaq-core/Core/SimpleQueueReader.hh"
00024 #include "cetlib/container_algorithms.h"
00025 #include "cetlib/filepath_maker.h"
00026 #include "fhiclcpp/ParameterSet.h"
00027 #include "fhiclcpp/make_ParameterSet.h"
00028 #include <boost/program_options.hpp>
00029
00030 #include <signal.h>
00031 #include <iostream>
00032 #include <memory>
00033 #include <utility>
00034
00035 using namespace std;
00036 using namespace fhicl;
00037 namespace bpo = boost::program_options;
00038
00039 volatile int events_to_generate;
00040 void sig_handler(int) { events_to_generate = -1; }
00041
00042 template<typename B, typename D>
00043 std::unique_ptr<D>
00044 dynamic_unique_ptr_cast(std::unique_ptr<B>& p);
00045
00046 int main(int argc, char * argv[]) try
00047 {
00048 std::ostringstream descstr;
00049 descstr << argv[0]
00050 << " <-c <config-file>> <other-options> [<source-file>]+";
00051 bpo::options_description desc(descstr.str());
00052 desc.add_options()
00053 ("config,c", bpo::value<std::string>(), "Configuration file.")
00054 ("help,h", "produce help message");
00055 bpo::variables_map vm;
00056 try {
00057 bpo::store(bpo::command_line_parser(argc, argv).options(desc).run(), vm);
00058 bpo::notify(vm);
00059 }
00060 catch (bpo::error const & e) {
00061 std::cerr << "Exception from command line processing in " << argv[0]
00062 << ": " << e.what() << "\n";
00063 return -1;
00064 }
00065 if (vm.count("help")) {
00066 std::cout << desc << std::endl;
00067 return 1;
00068 }
00069 if (!vm.count("config")) {
00070 std::cerr << "Exception from command line processing in " << argv[0]
00071 << ": no configuration file given.\n"
00072 << "For usage and an options list, please do '"
00073 << argv[0] << " --help"
00074 << "'.\n";
00075 return 2;
00076 }
00077 ParameterSet pset;
00078 if (getenv("FHICL_FILE_PATH") == nullptr) {
00079 std::cerr
00080 << "INFO: environment variable FHICL_FILE_PATH was not set. Using \".\"\n";
00081 setenv("FHICL_FILE_PATH", ".", 0);
00082 }
00083 cet::filepath_lookup_after1 lookup_policy("FHICL_FILE_PATH");
00084 make_ParameterSet(vm["config"].as<std::string>(), lookup_policy, pset);
00085
00086 int run = pset.get<int>("run_number", 1);
00087 uint64_t timeout = pset.get<uint64_t>("transition_timeout", 30);
00088 uint64_t timestamp = 0;
00089
00090 artdaq::configureMessageFacility("artdaqDriver");
00091
00092 ParameterSet fragment_receiver_pset = pset.get<ParameterSet>("fragment_receiver");
00093
00094 std::unique_ptr<artdaq::FragmentGenerator>
00095 gen(artdaq::makeFragmentGenerator(fragment_receiver_pset.get<std::string>("generator"),
00096 fragment_receiver_pset));
00097
00098 std::unique_ptr<artdaq::CommandableFragmentGenerator> commandable_gen =
00099 dynamic_unique_ptr_cast<artdaq::FragmentGenerator, artdaq::CommandableFragmentGenerator>(gen);
00100
00101 artdaq::MetricManager metricMan_;
00102 metricMan = &metricMan_;
00103 my_rank = 0;
00104
00105 fhicl::ParameterSet metric_pset;
00106 try {
00107 metric_pset = pset.get<fhicl::ParameterSet>("metrics");
00108 }
00109 catch (...) {}
00110
00111 if (metric_pset.is_empty()) {
00112 TLOG_INFO("artdaqDriver") << "No metric plugins appear to be defined" << TLOG_ENDL;
00113 }
00114 try {
00115 metricMan_.initialize(metric_pset, "artdaqDriver");
00116 metricMan_.do_start();
00117 }
00118 catch (...) {
00119 }
00120 artdaq::FragmentPtrs frags;
00122
00123
00124
00125 ParameterSet event_builder_pset = pset.get<ParameterSet>("event_builder");
00126 bool const want_artapp(event_builder_pset.get<bool>("use_art", false));
00127 std::ostringstream os;
00128 if (!want_artapp) {
00129 os << event_builder_pset.get<int>("events_expected_in_SimpleQueueReader");
00130 }
00131 std::string const oss(os.str());
00132 const char * args[2]{ "SimpleQueueReader", oss.c_str() };
00133 int es_argc(want_artapp ? argc : 2);
00134 char **es_argv(want_artapp ? argv : const_cast<char**>(args));
00135 artdaq::EventStore::ART_CMDLINE_FCN *
00136 es_fcn(want_artapp ? &artapp : &artdaq::simpleQueueReaderApp);
00137 artdaq::EventStore store(event_builder_pset, event_builder_pset.get<size_t>("expected_fragments_per_event"),
00138 pset.get<artdaq::EventStore::run_id_t>("run_number"),
00139 es_argc,
00140 es_argv,
00141 es_fcn);
00143
00144 int events_to_generate = pset.get<int>("events_to_generate", 0);
00145 int event_count = 0;
00146 artdaq::Fragment::sequence_id_t previous_sequence_id = -1;
00147
00148 if (commandable_gen) {
00149 commandable_gen->StartCmd(run, timeout, timestamp);
00150 }
00151
00152 TRACE( 50, "driver main before store.startRun" );
00153 store.startRun( run );
00154
00155
00156
00157
00158
00159 while ((commandable_gen && commandable_gen->getNext(frags)) ||
00160 (gen && gen->getNext(frags))) {
00161 TRACE( 50, "driver main: getNext returned frags.size()=%zd current event_count=%d"
00162 ,frags.size(),event_count );
00163 for (auto & val : frags) {
00164 if (val->sequenceID() != previous_sequence_id) {
00165 ++event_count;
00166 previous_sequence_id = val->sequenceID();
00167 }
00168 if (events_to_generate != 0 && event_count > events_to_generate) {
00169 if (commandable_gen) {
00170 commandable_gen->StopCmd(timeout, timestamp);
00171 }
00172 break;
00173 }
00174 store.insert(std::move(val));
00175 }
00176 frags.clear();
00177
00178 if (events_to_generate != 0 && event_count >= events_to_generate) {
00179 if (commandable_gen) {
00180 commandable_gen->StopCmd(timeout, timestamp);
00181 }
00182 break;
00183 }
00184 }
00185
00186
00187 int readerReturnValue;
00188 bool endSucceeded = false;
00189 int attemptsToEnd = 1;
00190 endSucceeded = store.endOfData(readerReturnValue);
00191 while (!endSucceeded && attemptsToEnd < 3) {
00192 ++attemptsToEnd;
00193 endSucceeded = store.endOfData(readerReturnValue);
00194 }
00195 if (!endSucceeded) {
00196 std::cerr << "Failed to shut down the reader and the event store "
00197 << "because the endOfData marker could not be pushed "
00198 << "onto the queue." << std::endl;
00199 }
00200
00201 metricMan_.do_stop();
00202 return readerReturnValue;
00203 }
00204 catch (std::string & x)
00205 {
00206 cerr << "Exception (type string) caught in artdaqDriver: " << x << '\n';
00207 return 1;
00208 }
00209 catch (char const * m)
00210 {
00211 cerr << "Exception (type char const*) caught in artdaqDriver: ";
00212 if (m)
00213 {
00214 cerr << m;
00215 }
00216 else
00217 {
00218 cerr << "[the value was a null pointer, so no message is available]";
00219 }
00220 cerr << '\n';
00221 }
00222 catch (...) {
00223 artdaq::ExceptionHandler(artdaq::ExceptionHandlerRethrow::no,
00224 "Exception caught in artdaqDriver");
00225 }
00226
00227
00228 template<typename B, typename D>
00229 std::unique_ptr<D>
00230 dynamic_unique_ptr_cast(std::unique_ptr<B>& p)
00231 {
00232 D* result = dynamic_cast<D*>(p.get());
00233
00234 if (result) {
00235 p.release();
00236 return std::unique_ptr<D>(result);
00237 }
00238 return nullptr;
00239 }