12 #define TRACE_NAME "genToArt"
14 #include "artdaq-core/Data/detail/RawFragmentHeader.hh"
15 #include "artdaq-core/Data/Fragment.hh"
16 #include "art/Framework/Art/artapp.h"
17 #include "canvas/Utilities/Exception.h"
18 #include "artdaq-core/Generators/FragmentGenerator.hh"
19 #include "artdaq/DAQdata/GenericFragmentSimulator.hh"
20 #include "artdaq/Generators/CommandableFragmentGenerator.hh"
21 #include "artdaq/DAQrate/SharedMemoryEventManager.hh"
22 #include "artdaq-core/Generators/makeFragmentGenerator.hh"
23 #include "artdaq-core/Core/SimpleMemoryReader.hh"
24 #include "artdaq-core/Utilities/SimpleLookupPolicy.hh"
25 #include "cetlib/container_algorithms.h"
26 #include "fhiclcpp/ParameterSet.h"
27 #include "fhiclcpp/make_ParameterSet.h"
29 #include <boost/program_options.hpp>
38 namespace bpo = boost::program_options;
50 bpo::variables_map& vm)
52 std::ostringstream descstr;
54 <<
" <-c <config-file>> <other-options> [<source-file>]+";
55 bpo::options_description desc(descstr.str());
57 (
"config,c", bpo::value<std::string>(),
"Configuration file.")
58 (
"help,h",
"produce help message");
61 bpo::store(bpo::command_line_parser(argc, argv).options(desc).run(), vm);
64 catch (bpo::error
const& e)
66 TLOG(TLVL_ERROR) <<
"Exception from command line processing in " << argv[0]
72 std::cout << desc << std::endl;
75 if (!vm.count(
"config"))
77 TLOG(TLVL_ERROR) <<
"Exception from command line processing in " << argv[0]
78 <<
": no configuration file given.\n"
79 <<
"For usage and an options list, please do '"
80 << argv[0] <<
" --help"
100 fhicl::ParameterSet
const& ps);
107 bool getNext(artdaq::FragmentPtrs& newFrags);
113 size_t numFragIDs()
const;
121 void start(
int run, uint64_t timeout, uint64_t timestamp)
const
124 if (gen_ptr !=
nullptr) gen_ptr->
StartCmd(run, timeout, timestamp);
131 void stop(uint64_t timeout, uint64_t timestamp)
const
134 if (gen_ptr !=
nullptr) gen_ptr->
StopCmd(timeout, timestamp);
138 bool generateFragments_();
140 std::unique_ptr<artdaq::FragmentGenerator> generator_;
141 size_t const numFragIDs_;
142 std::map<artdaq::Fragment::fragment_id_t,
143 std::deque<artdaq::FragmentPtr>> frags_;
147 ThrottledGenerator(std::string
const& generator,
148 fhicl::ParameterSet
const& ps)
150 generator_(artdaq::makeFragmentGenerator(generator, ps))
151 , numFragIDs_(generator_->fragmentIDs().size())
161 if (frags_.size() && frags_.begin()->second.size())
163 for (
auto& fQp : frags_)
165 assert(fQp.second.size());
166 newFrags.emplace_back(std::move(fQp.second.front()));
167 fQp.second.pop_front();
172 return generateFragments_() &&
getNext(newFrags);
181 artdaq::FragmentPtrs incomingFrags;
182 bool result{
false };
183 while ((result = generator_->getNext(incomingFrags)) &&
184 incomingFrags.empty())
187 for (
auto&& frag : incomingFrags)
189 frags_[frag->fragmentID()].emplace_back(std::move(frag));
227 auto const gta_pset = pset.get<fhicl::ParameterSet>(
"genToArt");
230 std::vector<ThrottledGenerator> generators;
232 auto const fr_pset = gta_pset.get<std::vector<fhicl::ParameterSet>>(
"fragment_receivers");
233 for (
auto const& gen_ps : fr_pset)
235 generators.emplace_back(gen_ps.get<std::string>(
"generator"),
239 artdaq::FragmentPtrs frags;
240 auto eb_pset = gta_pset.get<fhicl::ParameterSet>(
"event_builder", {});
241 size_t expected_frags_per_event = 0;
242 for (
auto& gen : generators)
244 gen.start(1000, 0, 0);
245 expected_frags_per_event += gen.numFragIDs();
247 eb_pset.put_or_replace<
size_t>(
"expected_fragments_per_event", expected_frags_per_event);
250 store.startRun(gta_pset.get<
int>(
"run_number", 1000));
252 auto const events_to_generate =
253 gta_pset.get<artdaq::Fragment::sequence_id_t>(
"events_to_generate", 0xFFFFFFFFFFFFFFFF);
254 auto const reset_sequenceID = pset.get<
bool>(
"reset_sequenceID",
true);
256 for (artdaq::Fragment::sequence_id_t event_count = 1;
257 (events_to_generate == 0xFFFFFFFFFFFFFFFF
258 || event_count <= events_to_generate) && (!done);
261 for (
auto& gen : generators)
263 done |= !gen.getNext(frags);
265 TLOG(TLVL_TRACE) <<
"There are " << frags.size() <<
" Fragments in event " << event_count <<
".";
266 artdaq::Fragment::sequence_id_t current_sequence_id = -1;
267 for (
auto& val : frags)
269 if (reset_sequenceID)
271 TLOG(TLVL_DEBUG) <<
"Setting fragment sequence id to " << event_count;
272 val->setSequenceID(event_count);
274 if (current_sequence_id ==
275 static_cast<artdaq::Fragment::sequence_id_t>(-1))
277 current_sequence_id = val->sequenceID();
279 else if (val->sequenceID() != current_sequence_id)
281 throw art::Exception(art::errors::DataCorruption)
282 <<
"Data corruption: apparently related fragments have "
283 <<
" different sequence IDs: "
286 << current_sequence_id
290 auto start_time = std::chrono::steady_clock::now();
295 artdaq::FragmentPtr tempFrag;
296 sts = store.AddFragment(std::move(val), 1000000, tempFrag);
297 if (!sts && event_count <= 10 && loop_count > 100)
299 TLOG(TLVL_ERROR) <<
"Fragment was not added after " << artdaq::TimeUtils::GetElapsedTime(start_time) <<
" s. Check art thread status!";
303 val = std::move(tempFrag);
312 TLOG(TLVL_TRACE) <<
"Event " << event_count <<
" END";
314 for (
auto& gen : generators)
319 bool endSucceeded = store.endOfData();
331 int main(
int argc,
char* argv[])
try
333 artdaq::configureMessageFacility(
"genToArt");
335 bpo::variables_map vm;
342 fhicl::ParameterSet pset;
343 if (getenv(
"FHICL_FILE_PATH") ==
nullptr)
346 <<
"INFO: environment variable FHICL_FILE_PATH was not set. Using \".\"\n";
347 setenv(
"FHICL_FILE_PATH",
".", 0);
349 artdaq::SimpleLookupPolicy lookup_policy(
"FHICL_FILE_PATH");
350 make_ParameterSet(vm[
"config"].as<std::string>(), lookup_policy, pset);
353 catch (std::string& x)
355 TLOG(TLVL_ERROR) <<
"Exception (type string) caught in genToArt: " << x <<
'\n';
358 catch (
char const* m)
360 TLOG(TLVL_ERROR) <<
"Exception (type char const*) caught in genToArt: ";
363 TLOG(TLVL_ERROR) << m;
367 TLOG(TLVL_ERROR) <<
"[the value was a null pointer, so no message is available]";
void start(int run, uint64_t timeout, uint64_t timestamp) const
Send start signal to FragmentGenerator, if it's a CommandableFragmentGenerator.
The SharedMemoryEventManager is a SharedMemoryManger which tracks events as they are built...
void StopCmd(uint64_t timeout, uint64_t timestamp)
Stop the CommandableFragmentGenerator.
void StartCmd(int run, uint64_t timeout, uint64_t timestamp)
Start the CommandableFragmentGenerator.
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.
CommandableFragmentGenerator is a FragmentGenerator-derived abstract class that defines the interface...
int process_data(fhicl::ParameterSet const &pset)
Run the test, instantiating configured generators and an EventStore.
void stop(uint64_t timeout, uint64_t timestamp) const
Send stop signal to FragmentGenerator, if it's a CommandableFragmentGenerator.
size_t numFragIDs() const
Get the number of Fragment IDs handled by this generator.
ThrottledGenerator: ensure that we only get one fragment per type at a time from the generator...