12 #include "art/Framework/Art/artapp.h"
13 #include "canvas/Utilities/Exception.h"
14 #include "artdaq/Application/MPI2/MPISentry.hh"
15 #include "artdaq-core/Generators/FragmentGenerator.hh"
16 #include "artdaq-core/Data/Fragment.hh"
17 #include "artdaq/DAQdata/GenericFragmentSimulator.hh"
18 #include "artdaq-core/Generators/makeFragmentGenerator.hh"
19 #include "artdaq/DAQrate/EventStore.hh"
20 #include "artdaq-core/Core/SimpleQueueReader.hh"
21 #include "artdaq-core/Utilities/SimpleLookupPolicy.hh"
22 #include "cetlib/container_algorithms.h"
23 #include "fhiclcpp/ParameterSet.h"
24 #include "fhiclcpp/make_ParameterSet.h"
26 #include "boost/program_options.hpp"
36 using namespace fhicl;
37 namespace bpo = boost::program_options;
49 bpo::variables_map& vm)
51 std::ostringstream descstr;
53 <<
" <-c <config-file>> <other-options> [<source-file>]+";
54 bpo::options_description desc(descstr.str());
56 (
"config,c", bpo::value<std::string>(),
"Configuration file.")
57 (
"help,h",
"produce help message");
60 bpo::store(bpo::command_line_parser(argc, argv).options(desc).run(), vm);
63 catch (bpo::error
const& e)
65 std::cerr <<
"Exception from command line processing in " << argv[0]
66 <<
": " << e.what() <<
"\n";
71 std::cout << desc << std::endl;
74 if (!vm.count(
"config"))
76 std::cerr <<
"Exception from command line processing in " << argv[0]
77 <<
": no configuration file given.\n"
78 <<
"For usage and an options list, please do '"
79 << argv[0] <<
" --help"
99 fhicl::ParameterSet
const& ps);
106 bool getNext(artdaq::FragmentPtrs& newFrags);
112 size_t numFragIDs()
const;
115 bool generateFragments_();
117 std::unique_ptr<artdaq::FragmentGenerator> generator_;
118 size_t const numFragIDs_;
119 std::map<artdaq::Fragment::fragment_id_t,
120 std::deque<artdaq::FragmentPtr>> frags_;
124 ThrottledGenerator(std::string
const& generator,
125 fhicl::ParameterSet
const& ps)
127 generator_(artdaq::makeFragmentGenerator(generator, ps))
128 , numFragIDs_(generator_->fragmentIDs().size())
138 if (frags_.size() && frags_.begin()->second.size())
140 for (
auto& fQp : frags_)
142 assert(fQp.second.size());
143 newFrags.emplace_back(std::move(fQp.second.front()));
144 fQp.second.pop_front();
149 return generateFragments_() &&
getNext(newFrags);
158 artdaq::FragmentPtrs incomingFrags;
160 while ((result = generator_->getNext(incomingFrags)) &&
161 incomingFrags.empty()) { }
162 for (
auto&& frag : incomingFrags)
164 frags_[frag->fragmentID()].emplace_back(std::move(frag));
203 fhicl::ParameterSet
const& pset)
205 auto const gta_pset = pset.get<ParameterSet>(
"genToArt");
208 std::vector<ThrottledGenerator> generators;
210 auto const fr_pset = gta_pset.get<std::vector<ParameterSet>>(
"fragment_receivers");
211 for (
auto const& gen_ps : fr_pset)
213 generators.emplace_back(gen_ps.get<std::string>(
"generator"),
217 artdaq::FragmentPtrs frags;
218 auto const eb_pset = gta_pset.get<ParameterSet>(
"event_builder", {});
219 size_t expected_frags_per_event = 0;
220 for (
auto& gen : generators)
222 expected_frags_per_event += gen.numFragIDs();
231 auto const events_to_generate =
232 gta_pset.get<artdaq::Fragment::sequence_id_t>(
"events_to_generate", -1);
233 auto const reset_sequenceID = pset.get<
bool>(
"reset_sequenceID",
true);
235 for (artdaq::Fragment::sequence_id_t event_count = 1;
236 (events_to_generate ==
static_cast<decltype(events_to_generate)
>(-1)
237 || event_count <= events_to_generate) && (!done);
240 for (
auto& gen : generators)
242 done |= !gen.getNext(frags);
244 artdaq::Fragment::sequence_id_t current_sequence_id = -1;
245 for (
auto& val : frags)
247 if (reset_sequenceID)
249 val->setSequenceID(event_count);
251 if (current_sequence_id ==
252 static_cast<artdaq::Fragment::sequence_id_t>(-1))
254 current_sequence_id = val->sequenceID();
256 else if (val->sequenceID() != current_sequence_id)
258 throw art::Exception(art::errors::DataCorruption)
259 <<
"Data corruption: apparently related fragments have "
260 <<
" different sequence IDs: "
263 << current_sequence_id
266 store.
insert(std::move(val));
271 int readerReturnValue;
272 bool endSucceeded = store.
endOfData(readerReturnValue);
275 return readerReturnValue;
284 int main(
int argc,
char* argv[])
try
289 bpo::variables_map vm;
297 if (getenv(
"FHICL_FILE_PATH") ==
nullptr)
300 <<
"INFO: environment variable FHICL_FILE_PATH was not set. Using \".\"\n";
301 setenv(
"FHICL_FILE_PATH",
".", 0);
303 artdaq::SimpleLookupPolicy lookup_policy(
"FHICL_FILE_PATH");
304 make_ParameterSet(vm[
"config"].as<std::string>(), lookup_policy, pset);
307 catch (std::string& x)
309 cerr <<
"Exception (type string) caught in genToArt: " << x <<
'\n';
312 catch (
char const* m)
314 cerr <<
"Exception (type char const*) caught in genToArt: ";
321 cerr <<
"[the value was a null pointer, so no message is available]";
void insert(FragmentPtr pfrag, bool printWarningWhenFragmentIsDropped=true)
Give ownership of the Fragment to the EventStore.
bool endOfData(int &readerReturnValue)
Indicate that the end of input has been reached to the art thread.
The MPISentry class initializes and finalizes the MPI context that the artdaq applciations run in...
int process_cmd_line(int argc, char **argv, bpo::variables_map &vm)
Process the command line.
bool getNext(artdaq::FragmentPtrs &newFrags)
Get the next fragment from the generator.
The EventStore class collects Fragment objects, until it receives a complete event, at which point the event is handed over to the art thread.
size_t numFragIDs() const
Get the number of Fragment IDs handled by this generator.
int process_data(int argc, char **argv, fhicl::ParameterSet const &pset)
Run the test, instantiating configured generators and an EventStore.
RawEvent::run_id_t run_id_t
Copy RawEvent::run_id_t into local scope.
ThrottledGenerator: ensure that we only get one fragment per type at a time from the generator...