1 #ifndef artdaq_Application_CommandableFragmentGenerator_hh
2 #define artdaq_Application_CommandableFragmentGenerator_hh
4 #include "fhiclcpp/types/Sequence.h"
6 #include "TRACE/tracemf.h"
7 #include "artdaq-core/Data/Fragment.hh"
9 #include "artdaq-core/Plugins/FragmentGenerator.hh"
10 #include "artdaq/DAQrate/FragmentBuffer.hh"
11 #include "artdaq/DAQrate/RequestBuffer.hh"
13 #include "fhiclcpp/types/Atom.h"
14 #include "fhiclcpp/types/Comment.h"
15 #include "fhiclcpp/types/ConfigurationTable.h"
16 #include "fhiclcpp/types/Name.h"
21 #include <boost/thread.hpp>
26 #include <condition_variable>
33 #include <arpa/inet.h>
34 #include <netinet/in.h>
35 #include <sys/socket.h>
36 #include <sys/types.h>
92 fhicl::Atom<std::string>
generator_type{fhicl::Name{
"generator"}, fhicl::Comment{
"Name of the CommandableFragmentGenerator plugin to load"}};
94 fhicl::Atom<Fragment::type_t>
expected_fragment_type{fhicl::Name{
"expected_fragment_type"}, fhicl::Comment{
"The type of Fragments this CFG will be generating. \"Empty\" will auto-detect type based on Fragments generated."}, Fragment::type_t(Fragment::EmptyFragmentType)};
96 fhicl::Atom<size_t>
sleep_on_no_data_us{fhicl::Name{
"sleep_on_no_data_us"}, fhicl::Comment{
"How long to sleep after calling getNext_ if no data is returned"}, 0};
98 fhicl::Atom<bool>
separate_monitoring_thread{fhicl::Name{
"separate_monitoring_thread"}, fhicl::Comment{
"Whether a thread that calls the checkHWStatus_ method should be created"},
false};
100 fhicl::Atom<int64_t>
hardware_poll_interval_us{fhicl::Name{
"hardware_poll_interval_us"}, fhicl::Comment{
"If a separate monitoring thread is used, how often should it call checkHWStatus_"}, 0};
102 fhicl::Atom<int>
board_id{fhicl::Name{
"board_id"}, fhicl::Comment{
"The identification number for this CommandableFragmentGenerator"}};
105 fhicl::Sequence<Fragment::fragment_id_t>
fragment_ids{fhicl::Name(
"fragment_ids"), fhicl::Comment(
"A list of Fragment IDs created by this CommandableFragmentGenerator")};
108 fhicl::Atom<int>
fragment_id{fhicl::Name{
"fragment_id"}, fhicl::Comment{
"The Fragment ID created by this CommandableFragmentGenerator"}, -99};
110 fhicl::Atom<int>
sleep_on_stop_us{fhicl::Name{
"sleep_on_stop_us"}, fhicl::Comment{
"How long to sleep before returning when stop transition is called"}, 0};
141 bool getNext(FragmentPtrs& output)
override final;
159 std::vector<Fragment::fragment_id_t> output;
161 for (
auto&
id : expectedTypes_)
163 output.push_back(
id.first);
237 std::string
ReportCmd(std::string
const& which =
"");
245 return instance_name_for_metrics_;
276 virtual bool metaCommand(std::string
const& command, std::string
const& arg);
284 void SetFragmentBuffer(std::shared_ptr<FragmentBuffer> buffer) { fragmentBuffer_ = buffer; }
323 if (expectedTypes_.size() > 1)
throw cet::exception(
"FragmentID") <<
"fragment_id() was called, indicating that Fragment Generator was expecting one and only one Fragment ID, but " << expectedTypes_.size() <<
" were declared!";
324 return (*expectedTypes_.begin()).first;
364 instance_name_for_metrics_ = name;
383 std::shared_ptr<FragmentBuffer> GetFragmentBuffer() {
return fragmentBuffer_; }
396 std::map<Fragment::fragment_id_t, Fragment::type_t> expectedTypes_;
398 bool useMonitoringThread_;
399 boost::thread monitoringThread_;
400 int64_t monitoringInterval_;
401 std::chrono::steady_clock::time_point lastMonitoringCall_;
402 std::atomic<bool> isHardwareOK_;
407 int run_number_, subrun_number_;
422 std::atomic<bool> should_stop_, exception_;
423 std::string latest_exception_report_;
424 std::atomic<size_t> ev_counter_;
427 std::string instance_name_for_metrics_;
432 int sleep_on_stop_us_;
435 std::shared_ptr<RequestBuffer> requestBuffer_;
436 std::shared_ptr<FragmentBuffer> fragmentBuffer_;
446 virtual bool getNext_(FragmentPtrs& output) = 0;
470 virtual void start() = 0;
488 virtual void stop() = 0;
501 virtual void pause();
519 virtual std::string
report();
fhicl::Atom< Fragment::type_t > expected_fragment_type
"expected_fragment_type" (Default: 231, EmptyFragmentType) : The type of Fragments this CFG will be g...
fhicl::Atom< int > board_id
"board_id" (REQUIRED) : The identification number for this CommandableFragmentGenerator ...
CommandableFragmentGenerator(const fhicl::ParameterSet &ps)
CommandableFragmentGenerator Constructor.
int subrun_number() const
Get the current Subrun number.
virtual void start()=0
If a CommandableFragmentGenerator subclass is reading from a file, and start() is called...
fhicl::Atom< int64_t > hardware_poll_interval_us
"hardware_poll_interval_us" (Default: 0) : If a separate monitoring thread is used, how often should it call checkHWStatus_
virtual bool checkHWStatus_()
Check any relavent hardware status registers. Return false if an error condition exists that should h...
virtual ~CommandableFragmentGenerator()
CommandableFragmentGenerator Destructor.
bool exception() const
Get the current value of the exception flag.
void metricsReportingInstanceName(std::string const &name)
Sets the name for metrics reporting.
std::mutex mutex_
Mutex used to ensure that multiple transition commands do not run at the same time.
void getMonitoringDataLoop()
This function regularly calls checkHWStatus_(), and sets the isHardwareOK flag accordingly.
artdaq::Fragment::fragment_id_t fragment_id() const
Get the Fragment ID of this Fragment generator.
std::string ReportCmd(std::string const &which="")
Get a report about a user-specified run-time quantity.
virtual bool metaCommand(std::string const &command, std::string const &arg)
The meta-command is used for implementing user-specific commands in a CommandableFragmentGenerator.
fhicl::Atom< int > fragment_id
void StopCmd(uint64_t timeout, uint64_t timestamp)
Stop the CommandableFragmentGenerator.
uint64_t timeout() const
Timeout of last command.
void StartCmd(int run, uint64_t timeout, uint64_t timestamp)
Start the CommandableFragmentGenerator.
virtual void pauseNoMutex()
On call to PauseCmd, pauseNoMutex() is called prior to PauseCmd acquiring the mutex ...
bool check_stop()
Routine used by applyRequests to make sure that all outstanding requests have been fulfilled before r...
void ResumeCmd(uint64_t timeout, uint64_t timestamp)
Resume the CommandableFragmentGenerator.
bool getNext(FragmentPtrs &output) overridefinal
getNext calls either applyRequests or getNext_ to get any data that is ready to be sent to the EventB...
std::vector< Fragment::fragment_id_t > fragmentIDs() override
Get the list of Fragment IDs handled by this CommandableFragmentGenerator.
fhicl::Atom< int > sleep_on_stop_us
"sleep_on_stop_us" (Default: 0) : How long to sleep before returning when stop transition is called ...
void PauseCmd(uint64_t timeout, uint64_t timestamp)
Pause the CommandableFragmentGenerator.
fhicl::Sequence< Fragment::fragment_id_t > fragment_ids
virtual std::string metricsReportingInstanceName() const
Get the name used when reporting metrics.
bool should_stop() const
Get the current value of the should_stop flag.
CommandableFragmentGenerator is a FragmentGenerator-derived abstract class that defines the interface...
fhicl::WrappedTable< Config > Parameters
Used for ParameterSet validation (if desired)
virtual bool getNext_(FragmentPtrs &output)=0
Obtain the next group of Fragments, if any are available. Return false if readout cannot continue...
void startMonitoringThread()
Function that launches the monitoring thread (getMonitoringDataLoop())
virtual void pause()
If a CommandableFragmentGenerator subclass is reading from hardware, the implementation of pause() sh...
virtual void resume()
The subrun number will be incremented before a call to resume.
size_t ev_counter() const
Get the current value of the event counter.
fhicl::Atom< size_t > sleep_on_no_data_us
"sleep_on_no_data_us" (Default: 0 (no sleep)) : How long to sleep after calling getNext_ if no data i...
virtual std::string report()
Let's say that the contract with the report() functions is that they return a non-empty string if the...
virtual void stopNoMutex()=0
On call to StopCmd, stopNoMutex() is called prior to StopCmd acquiring the mutex
int board_id() const
Gets the current board_id.
std::shared_ptr< RequestBuffer > GetRequestBuffer()
Get the shared_ptr to the RequestBuffer.
void SetRequestBuffer(std::shared_ptr< RequestBuffer > buffer)
Set the shared_ptr to the RequestBuffer.
void set_exception(bool exception)
Control the exception flag.
uint64_t timestamp() const
Timestamp of last command.
Configuration of the CommandableFragmentGenerator. May be used for parameter validation ...
fhicl::Atom< std::string > generator_type
"generator" (REQUIRED) Name of the CommandableFragmentGenerator plugin to load
size_t ev_counter_inc(size_t step=1)
Increment the event counter.
virtual void stop()=0
If a CommandableFragmentGenerator subclass is reading from a file, calling stop() should arrange that...
virtual std::string reportSpecific(std::string const &what)
Report the status of a specific quantity
int run_number() const
Get the current Run number.
fhicl::Atom< bool > separate_monitoring_thread
"separate_monitoring_thread" (Default: false) : Whether a thread that calls the checkHWStatus_ method...
void joinThreads()
Join any data-taking threads. Should be called when destructing CommandableFragmentGenerator.