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 ParameterSet fragment_receiver_pset = pset.get<ParameterSet>("fragment_receiver");
00091
00092 std::unique_ptr<artdaq::FragmentGenerator>
00093 gen(artdaq::makeFragmentGenerator(fragment_receiver_pset.get<std::string>("generator"),
00094 fragment_receiver_pset));
00095
00096 std::unique_ptr<artdaq::CommandableFragmentGenerator> commandable_gen =
00097 dynamic_unique_ptr_cast<artdaq::FragmentGenerator, artdaq::CommandableFragmentGenerator>(gen);
00098
00099 artdaq::configureMessageFacility("artdaqDriver");
00100 artdaq::MetricManager metricMan_;
00101 metricMan = &metricMan_;
00102 my_rank = 0;
00103
00104 fhicl::ParameterSet metric_pset;
00105 try {
00106 metric_pset = pset.get<fhicl::ParameterSet>("metrics");
00107 }
00108 catch (...) {}
00109
00110 if (metric_pset.is_empty()) {
00111 TLOG_INFO("artdaqDriver") << "No metric plugins appear to be defined" << TLOG_ENDL;
00112 }
00113 try {
00114 metricMan_.initialize(metric_pset, "artdaqDriver");
00115 metricMan_.do_start();
00116 }
00117 catch (...) {
00118 }
00119 artdaq::FragmentPtrs frags;
00121
00122
00123
00124 ParameterSet event_builder_pset = pset.get<ParameterSet>("event_builder");
00125 bool const want_artapp(event_builder_pset.get<bool>("use_art", false));
00126 std::ostringstream os;
00127 if (!want_artapp) {
00128 os << event_builder_pset.get<int>("events_expected_in_SimpleQueueReader");
00129 }
00130 std::string const oss(os.str());
00131 const char * args[2]{ "SimpleQueueReader", oss.c_str() };
00132 int es_argc(want_artapp ? argc : 2);
00133 char **es_argv(want_artapp ? argv : const_cast<char**>(args));
00134 artdaq::EventStore::ART_CMDLINE_FCN *
00135 es_fcn(want_artapp ? &artapp : &artdaq::simpleQueueReaderApp);
00136 artdaq::EventStore store(event_builder_pset, event_builder_pset.get<size_t>("expected_fragments_per_event"),
00137 pset.get<artdaq::EventStore::run_id_t>("run_number"),
00138 es_argc,
00139 es_argv,
00140 es_fcn);
00142
00143 int events_to_generate = pset.get<int>("events_to_generate", 0);
00144 int event_count = 0;
00145 artdaq::Fragment::sequence_id_t previous_sequence_id = -1;
00146
00147 if (commandable_gen) {
00148 commandable_gen->StartCmd(run, timeout, timestamp);
00149 }
00150
00151 TRACE( 50, "driver main before store.startRun" );
00152 store.startRun( run );
00153
00154
00155
00156
00157
00158 while ((commandable_gen && commandable_gen->getNext(frags)) ||
00159 (gen && gen->getNext(frags))) {
00160 TRACE( 50, "driver main: getNext returned frags.size()=%zd current event_count=%d"
00161 ,frags.size(),event_count );
00162 for (auto & val : frags) {
00163 if (val->sequenceID() != previous_sequence_id) {
00164 ++event_count;
00165 previous_sequence_id = val->sequenceID();
00166 }
00167 if (events_to_generate != 0 && event_count > events_to_generate) {
00168 if (commandable_gen) {
00169 commandable_gen->StopCmd(timeout, timestamp);
00170 }
00171 break;
00172 }
00173 store.insert(std::move(val));
00174 }
00175 frags.clear();
00176
00177 if (events_to_generate != 0 && event_count >= events_to_generate) {
00178 if (commandable_gen) {
00179 commandable_gen->StopCmd(timeout, timestamp);
00180 }
00181 break;
00182 }
00183 }
00184
00185
00186 int readerReturnValue;
00187 bool endSucceeded = false;
00188 int attemptsToEnd = 1;
00189 endSucceeded = store.endOfData(readerReturnValue);
00190 while (!endSucceeded && attemptsToEnd < 3) {
00191 ++attemptsToEnd;
00192 endSucceeded = store.endOfData(readerReturnValue);
00193 }
00194 if (!endSucceeded) {
00195 std::cerr << "Failed to shut down the reader and the event store "
00196 << "because the endOfData marker could not be pushed "
00197 << "onto the queue." << std::endl;
00198 }
00199
00200 metricMan_.do_stop();
00201 return readerReturnValue;
00202 }
00203 catch (std::string & x)
00204 {
00205 cerr << "Exception (type string) caught in artdaqDriver: " << x << '\n';
00206 return 1;
00207 }
00208 catch (char const * m)
00209 {
00210 cerr << "Exception (type char const*) caught in artdaqDriver: ";
00211 if (m)
00212 {
00213 cerr << m;
00214 }
00215 else
00216 {
00217 cerr << "[the value was a null pointer, so no message is available]";
00218 }
00219 cerr << '\n';
00220 }
00221 catch (...) {
00222 artdaq::ExceptionHandler(artdaq::ExceptionHandlerRethrow::no,
00223 "Exception caught in artdaqDriver");
00224 }
00225
00226
00227 template<typename B, typename D>
00228 std::unique_ptr<D>
00229 dynamic_unique_ptr_cast(std::unique_ptr<B>& p)
00230 {
00231 D* result = dynamic_cast<D*>(p.get());
00232
00233 if (result) {
00234 p.release();
00235 return std::unique_ptr<D>(result);
00236 }
00237 return nullptr;
00238 }