$treeview $search $mathjax $extrastylesheet
artdaq_demo
v3_04_00
$projectbrief
|
$projectbrief
|
$searchbox |
00001 // 00002 // Based off of "ds50driver", a program for testing DarkSide-50 input 00003 // sources, "driver" is an executable designed to make it simple to 00004 // test a fragment generator under development 00005 00006 // Run 'driver --help' to get a description of the 00007 // expected command-line parameters. 00008 // 00009 // 00010 // The current version generates data fragments and passes them 00011 // to an EventStore instance and then to art, if desired. 00012 // 00013 00014 #include "art/Framework/Art/artapp.h" 00015 #include "artdaq-core/Data/Fragment.hh" 00016 #include "artdaq/Application/CommandableFragmentGenerator.hh" 00017 #include "artdaq/Application/makeCommandableFragmentGenerator.hh" 00018 #include "artdaq/DAQrate/EventStore.hh" 00019 #include "artdaq-core/Core/SimpleMemoryReader.hh" 00020 #include "artdaq-core/Utilities/SimpleLookupPolicy.hh" 00021 #include "cetlib/container_algorithms.h" 00022 #include "cetlib/filepath_maker.h" 00023 #include "fhiclcpp/ParameterSet.h" 00024 #include "fhiclcpp/make_ParameterSet.h" 00025 00026 #include <boost/program_options.hpp> 00027 00028 #include <signal.h> 00029 #include <iostream> 00030 #include <memory> 00031 #include <utility> 00032 #include <limits> 00033 00034 using namespace fhicl; 00035 namespace bpo = boost::program_options; 00036 00037 00038 int main(int argc, char* argv[]) try 00039 { 00040 // 15-Dec-2016, KAB: by consensus, we want people to use the "artdaqDriver" 00041 // program (which corresponds to "artdaq/proto/driver.cc"). 00042 if (true) 00043 { 00044 std::cout << "****************************************" << std::endl; 00045 std::cout << "*** \"demo_driver\" has been deprecated (15-Dec-2016)." << std::endl; 00046 std::cout << "*** Please use the \"artdaqDriver\" application that is available from" << std::endl 00047 << "*** the artdaq software package instead of \"demo_driver\"." << std::endl; 00048 exit(1); 00049 } 00050 00051 // Get the input parameters via the boost::program_options library, 00052 // designed to make it relatively simple to define arguments and 00053 // issue errors if argument list is supplied incorrectly 00054 00055 std::ostringstream descstr; 00056 descstr << argv[0] << " <-c <config-file>> <other-options>"; 00057 00058 bpo::options_description desc = descstr.str(); 00059 00060 desc.add_options() 00061 ("config,c", bpo::value<std::string>(), "Configuration file.") 00062 ("help,h", "produce help message"); 00063 00064 bpo::variables_map vm; 00065 00066 try 00067 { 00068 bpo::store(bpo::command_line_parser(argc, argv).options(desc).run(), vm); 00069 bpo::notify(vm); 00070 } 00071 catch (bpo::error const& e) 00072 { 00073 std::cerr << "Exception from command line processing in " << argv[0] 00074 << ": " << e.what() << "\n"; 00075 return -1; 00076 } 00077 00078 if (vm.count("help")) 00079 { 00080 std::cout << desc << std::endl; 00081 return 1; 00082 } 00083 if (!vm.count("config")) 00084 { 00085 std::cerr << "Exception from command line processing in " << argv[0] 00086 << ": no configuration file given.\n" 00087 << "For usage and an options list, please do '" 00088 << argv[0] << " --help" 00089 << "'.\n"; 00090 return 2; 00091 } 00092 00093 // Check the directories defined by the FHICL_FILE_PATH 00094 // environmental variable for the *.fcl file whose name was passed to 00095 // the command line. If not defined, look in the current directory. 00096 00097 ParameterSet complete_pset; 00098 00099 if (getenv("FHICL_FILE_PATH") == nullptr) 00100 { 00101 std::cerr 00102 << "INFO: environment variable FHICL_FILE_PATH was not set. Using \".\"\n"; 00103 setenv("FHICL_FILE_PATH", ".", 0); 00104 } 00105 00106 artdaq::SimpleLookupPolicy lookup_policy("FHICL_FILE_PATH"); 00107 00108 make_ParameterSet(vm["config"].as<std::string>(), lookup_policy, complete_pset); 00109 00110 ParameterSet fragment_receiver_pset = complete_pset.get<ParameterSet>("fragment_receiver"); 00111 ParameterSet event_builder_pset = complete_pset.get<ParameterSet>("event_builder"); 00112 00113 // Use the "generator" parameter from the user-supplied *.fcl 00114 // configuration file to define our fragment generator 00115 00116 std::unique_ptr<artdaq::CommandableFragmentGenerator> const 00117 gen(artdaq::makeCommandableFragmentGenerator(fragment_receiver_pset.get<std::string>("generator"), 00118 fragment_receiver_pset)); 00119 00120 // The instance of the artdaq::EventStore object can either pass 00121 // events to a thread running Art, or to a small executable called 00122 // "SimpleMemoryReader" 00123 00124 bool const want_artapp = event_builder_pset.get<bool>("use_art", false); 00125 00126 std::ostringstream os; 00127 if (!want_artapp) 00128 { 00129 os << event_builder_pset.get<int>("events_expected_in_SimpleMemoryReader"); 00130 } 00131 std::string oss = os.str(); 00132 00133 const char* args[2]{"SimpleMemoryReader", const_cast<char *>(oss.c_str())}; 00134 00135 int es_argc(want_artapp ? argc : 2); 00136 char** es_argv(want_artapp ? argv : const_cast<char**>(args)); 00137 00138 artdaq::EventStore::ART_CMDLINE_FCN* 00139 es_fcn(want_artapp ? &artapp : &artdaq::SimpleMemoryReaderApp); 00140 00141 artdaq::EventStore store(event_builder_pset, event_builder_pset.get<size_t>("expected_fragments_per_event"), 00142 complete_pset.get<artdaq::EventStore::run_id_t>("run_number"), 00143 es_argc, 00144 es_argv, 00145 es_fcn); 00146 00147 int events_to_generate = complete_pset.get<int>("events_to_generate", 0); 00148 int event_count = 0; 00149 artdaq::Fragment::sequence_id_t previous_sequence_id = 0; 00150 00151 uint64_t timeout = 45; 00152 uint64_t timestamp = std::numeric_limits<uint64_t>::max(); 00153 00154 gen.get()->StartCmd(complete_pset.get<artdaq::EventStore::run_id_t>("run_number"), timeout, timestamp); 00155 00156 artdaq::FragmentPtrs frags; 00157 00158 while (events_to_generate >= 0 && gen->getNext(frags)) 00159 { 00160 for (auto& val : frags) 00161 { 00162 std::cout << "Fragment: Seq ID: " << val->sequenceID() << ", Frag ID: " << val->fragmentID() << ", total size in bytes: " << val->size() * sizeof(artdaq::RawDataType) << std::endl; 00163 00164 if (val->sequenceID() != previous_sequence_id) 00165 { 00166 ++event_count; 00167 previous_sequence_id = val->sequenceID(); 00168 } 00169 if (events_to_generate != 0 && event_count > events_to_generate) 00170 gen.get()->StopCmd(timeout, timestamp); 00171 00172 store.insert(std::move(val)); 00173 } 00174 frags.clear(); 00175 00176 if (events_to_generate != 0 && event_count >= events_to_generate) 00177 gen.get()->StopCmd(timeout, timestamp); 00178 } 00179 00180 int readerReturnValue; 00181 bool endSucceeded = false; 00182 int attemptsToEnd = 1; 00183 endSucceeded = store.endOfData(readerReturnValue); 00184 while (! endSucceeded && attemptsToEnd < 3) 00185 { 00186 ++attemptsToEnd; 00187 endSucceeded = store.endOfData(readerReturnValue); 00188 } 00189 if (! endSucceeded) 00190 { 00191 std::cerr << "Failed to shut down the reader and the event store " 00192 << "because the endOfData marker could not be pushed " 00193 << "onto the queue." << std::endl; 00194 } 00195 return readerReturnValue; 00196 } 00197 00198 catch (std::string& x) 00199 { 00200 std::cerr << "Exception (type string) caught in driver: " << x << "\n"; 00201 return 1; 00202 } 00203 00204 catch (char const* m) 00205 { 00206 std::cerr << "Exception (type char const*) caught in driver: " << std::endl; 00207 if (m) 00208 { 00209 std::cerr << m; 00210 } 00211 else 00212 { 00213 std::cerr << "[the value was a null pointer, so no message is available]"; 00214 } 00215 std::cerr << '\n'; 00216 }