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-core/Core/SimpleMemoryReader.hh"
00023 #include "cetlib/filepath_maker.h"
00024 #include "fhiclcpp/ParameterSet.h"
00025 #include "fhiclcpp/make_ParameterSet.h"
00026 #include <boost/program_options.hpp>
00027
00028 #include <signal.h>
00029 #include <iostream>
00030 #include <memory>
00031 #include <utility>
00032 #include "artdaq/DAQrate/SharedMemoryEventManager.hh"
00033 #include "artdaq/Application/LoadParameterSet.hh"
00034
00035 namespace bpo = boost::program_options;
00036
00037 volatile int events_to_generate;
00038 void sig_handler(int) { events_to_generate = -1; }
00039
00040 template<typename B, typename D>
00041 std::unique_ptr<D>
00042 dynamic_unique_ptr_cast(std::unique_ptr<B>& p);
00043
00044 int main(int argc, char * argv[]) try
00045 {
00046 auto pset = LoadParameterSet(argc, argv);
00047
00048 int run = pset.get<int>("run_number", 1);
00049 bool debug = pset.get<bool>("debug_cout", false);
00050 uint64_t timeout = pset.get<uint64_t>("transition_timeout", 30);
00051 uint64_t timestamp = 0;
00052
00053 artdaq::configureMessageFacility("artdaqDriver",true,debug);
00054
00055 fhicl::ParameterSet fragment_receiver_pset = pset.get<fhicl::ParameterSet>("fragment_receiver");
00056
00057 std::unique_ptr<artdaq::FragmentGenerator>
00058 gen(artdaq::makeFragmentGenerator(fragment_receiver_pset.get<std::string>("generator"),
00059 fragment_receiver_pset));
00060
00061 std::unique_ptr<artdaq::CommandableFragmentGenerator> commandable_gen =
00062 dynamic_unique_ptr_cast<artdaq::FragmentGenerator, artdaq::CommandableFragmentGenerator>(gen);
00063
00064 artdaq::MetricManager metricMan_;
00065 metricMan = &metricMan_;
00066 my_rank = 0;
00067
00068 fhicl::ParameterSet metric_pset;
00069 try {
00070 metric_pset = pset.get<fhicl::ParameterSet>("metrics");
00071 }
00072 catch (...) {}
00073
00074 if (metric_pset.is_empty()) {
00075 TLOG_INFO("artdaqDriver") << "No metric plugins appear to be defined" << TLOG_ENDL;
00076 }
00077 try {
00078 metricMan_.initialize(metric_pset, "artdaqDriver");
00079 metricMan_.do_start();
00080 }
00081 catch (...) {
00082 }
00083 artdaq::FragmentPtrs frags;
00085
00086
00087
00088 fhicl::ParameterSet event_builder_pset = pset.get<fhicl::ParameterSet>("event_builder");
00089
00090 artdaq::SharedMemoryEventManager store(event_builder_pset, pset);
00092
00093 int events_to_generate = pset.get<int>("events_to_generate", 0);
00094 int event_count = 0;
00095 artdaq::Fragment::sequence_id_t previous_sequence_id = -1;
00096
00097 if (commandable_gen) {
00098 commandable_gen->StartCmd(run, timeout, timestamp);
00099 }
00100
00101 TLOG_ARB(50, "artdaqDriver") << "driver main before store.startRun" << TLOG_ENDL;
00102 store.startRun(run);
00103
00104
00105
00106
00107
00108 while ((commandable_gen && commandable_gen->getNext(frags)) ||
00109 (gen && gen->getNext(frags))) {
00110 TLOG_ARB(50, "artdaqDriver") << "driver main: getNext returned frags.size()=" << std::to_string(frags.size()) << " current event_count=" << event_count << TLOG_ENDL;
00111 for (auto & val : frags) {
00112 if (val->sequenceID() != previous_sequence_id) {
00113 ++event_count;
00114 previous_sequence_id = val->sequenceID();
00115 }
00116 if (events_to_generate != 0 && event_count > events_to_generate) {
00117 if (commandable_gen) {
00118 commandable_gen->StopCmd(timeout, timestamp);
00119 }
00120 break;
00121 }
00122 artdaq::FragmentPtr tempFrag;
00123 auto sts = store.AddFragment(std::move(val), 1000000, tempFrag);
00124 if (!sts)
00125 {
00126 TLOG_ERROR("artdaqDriver") << "Fragment was not added after 1s. Check art thread status!" << TLOG_ENDL;
00127 exit(1);
00128 }
00129 }
00130 frags.clear();
00131
00132 if (events_to_generate != 0 && event_count >= events_to_generate) {
00133 if (commandable_gen) {
00134 commandable_gen->StopCmd(timeout, timestamp);
00135 }
00136 break;
00137 }
00138 }
00139
00140 if (commandable_gen) {
00141 commandable_gen->joinThreads();
00142 }
00143
00144 bool endSucceeded = false;
00145 int attemptsToEnd = 1;
00146 endSucceeded = store.endOfData();
00147 while (!endSucceeded && attemptsToEnd < 3) {
00148 ++attemptsToEnd;
00149 endSucceeded = store.endOfData();
00150 }
00151 if (!endSucceeded) {
00152 std::cerr << "Failed to shut down the reader and the event store "
00153 << "because the endOfData marker could not be pushed "
00154 << "onto the queue." << std::endl;
00155 }
00156
00157 metricMan_.do_stop();
00158 return 0;
00159 }
00160 catch (std::string & x)
00161 {
00162 std::cerr << "Exception (type string) caught in artdaqDriver: " << x << '\n';
00163 return 1;
00164 }
00165 catch (char const * m)
00166 {
00167 std::cerr << "Exception (type char const*) caught in artdaqDriver: ";
00168 if (m)
00169 {
00170 std::cerr << m;
00171 }
00172 else
00173 {
00174 std::cerr << "[the value was a null pointer, so no message is available]";
00175 }
00176 std::cerr << '\n';
00177 }
00178 catch (...) {
00179 artdaq::ExceptionHandler(artdaq::ExceptionHandlerRethrow::no,
00180 "Exception caught in artdaqDriver");
00181 }
00182
00183
00184 template<typename B, typename D>
00185 std::unique_ptr<D>
00186 dynamic_unique_ptr_cast(std::unique_ptr<B>& p)
00187 {
00188 D* result = dynamic_cast<D*>(p.get());
00189
00190 if (result) {
00191 p.release();
00192 return std::unique_ptr<D>(result);
00193 }
00194 return nullptr;
00195 }