artdaq  v2_03_02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Pages
RandomDelayFilter_module.cc
1 // Class: RandomDelayFilter
3 // Module Type: filter
4 // File: RandomDelayFilter_module.cc
5 //
6 // Generated at Fri Mar 4 10:45:30 2016 by Eric Flumerfelt using artmod
7 // from cetpkgsupport v1_09_00.
9 
10 #include "art/Framework/Core/EDFilter.h"
11 #include "art/Framework/Core/ModuleMacros.h"
12 #include "art/Framework/Principal/Event.h"
13 #include "art/Framework/Principal/Handle.h"
14 #include "art/Framework/Principal/Run.h"
15 #include "art/Framework/Principal/SubRun.h"
16 #include "canvas/Utilities/InputTag.h"
17 #include "fhiclcpp/ParameterSet.h"
18 
19 #include "artdaq/DAQdata/Globals.hh"
20 
21 #include <memory>
22 #include <random>
23 #include <chrono>
24 
25 namespace artdaq
26 {
27  class RandomDelayFilter;
28 }
29 
37 class artdaq::RandomDelayFilter : public art::EDFilter
38 {
39 public:
54  explicit RandomDelayFilter(fhicl::ParameterSet const& p);
55 
59  RandomDelayFilter(RandomDelayFilter const&) = delete;
60 
65 
71 
77 
87  bool filter(art::Event& e) override;
88 
103  void reconfigure(fhicl::ParameterSet const& p) override;
104 
105 private:
106  // Random Delay Parameters (min/max for uniform, mean/sigma for normal)
107  double min_ms_;
108  double max_ms_;
109  double mean_ms_;
110  double sigma_ms_;
111 
112  int pass_factor_;
113  double load_factor_;
114 
115  // Random Engine Setup
116  bool isNormal_;
117  std::mt19937 engine_;
118  std::unique_ptr<std::uniform_real_distribution<double>> uniform_distn_;
119  std::unique_ptr<std::normal_distribution<double>> normal_distn_;
120  std::unique_ptr<std::uniform_int_distribution<int>> pass_distn_;
121 };
122 
123 
124 artdaq::RandomDelayFilter::RandomDelayFilter(fhicl::ParameterSet const& p)
125  : min_ms_(p.get<double>("minimum_delay_ms", 0))
126  , max_ms_(p.get<double>("maximum_delay_ms", 1000))
127  , mean_ms_(p.get<double>("mean_delay_ms", 500))
128  , sigma_ms_(p.get<double>("sigma_delay_ms", 100))
129  , pass_factor_(p.get<int>("pass_filter_percentage", 100))
130  , load_factor_(p.get<double>("cpu_load_ratio", 1.0))
131  , isNormal_(p.get<bool>("use_normal_distribution", false))
132  , engine_(p.get<int64_t>("random_seed", 271828))
133  , pass_distn_(new std::uniform_int_distribution<int>(0, 100))
134 {
135  // Set limits on parameters
136  if (pass_factor_ > 100) pass_factor_ = 100;
137  if (pass_factor_ < 0) pass_factor_ = 0;
138  if (load_factor_ < 0.0) load_factor_ = 0.0;
139  if (load_factor_ > 1.0) load_factor_ = 1.0;
140 
141  if (min_ms_ < 0) min_ms_ = 0;
142  if (min_ms_ > max_ms_) max_ms_ = min_ms_;
143  if (mean_ms_ < 0) mean_ms_ = 0;
144  if (sigma_ms_ < 0) sigma_ms_ = 0;
145 
146  uniform_distn_.reset(new std::uniform_real_distribution<double>(min_ms_, max_ms_));
147  normal_distn_.reset(new std::normal_distribution<double>(mean_ms_, sigma_ms_));
148 }
149 
151 {
152  double delay = isNormal_ ? (*normal_distn_)(engine_) : (*uniform_distn_)(engine_);
153  TLOG_DEBUG("RandomDelayFilter") << "Simulating processing of event " << e.event() << " by delaying " << std::to_string(delay) << "ms." << TLOG_ENDL;
154 
155  usleep(1000 * (1 - load_factor_) * delay);
156 
157  auto i = 0;
158  auto now = std::chrono::steady_clock::now();
159  while (std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - now).count() < delay * load_factor_)
160  {
161  i = i + 1 % std::numeric_limits<int>::max();
162  }
163 
164  return (*pass_distn_)(engine_) < pass_factor_;
165 }
166 
167 void artdaq::RandomDelayFilter::reconfigure(fhicl::ParameterSet const& p)
168 {
169  min_ms_ = p.get<double>("minimum_delay_ms", 0);
170  max_ms_ = p.get<double>("maximum_delay_ms", 1000);
171  mean_ms_ = p.get<double>("mean_delay_ms", 500);
172  sigma_ms_ = p.get<double>("sigma_delay_ms", 100);
173  pass_factor_ = p.get<int>("pass_filter_percentage", 100);
174  load_factor_ = p.get<double>("cpu_load_ratio", 1.0);
175  isNormal_ = p.get<bool>("use_normal_distribution", false);
176  engine_ = std::mt19937(p.get<int64_t>("random_seed", 271828));
177 
178  // Set limits on parameters
179  if (pass_factor_ > 100) pass_factor_ = 100;
180  if (pass_factor_ < 0) pass_factor_ = 0;
181  if (load_factor_ < 0.0) load_factor_ = 0.0;
182  if (load_factor_ > 1.0) load_factor_ = 1.0;
183 
184  if (min_ms_ < 0) min_ms_ = 0;
185  if (min_ms_ > max_ms_) max_ms_ = min_ms_;
186  if (mean_ms_ < 0) mean_ms_ = 0;
187  if (sigma_ms_ < 0) sigma_ms_ = 0;
188 
189  uniform_distn_.reset(new std::uniform_real_distribution<double>(min_ms_, max_ms_));
190  normal_distn_.reset(new std::normal_distribution<double>(mean_ms_, sigma_ms_));
191 }
192 
193 DEFINE_ART_MODULE(artdaq::RandomDelayFilter)
RandomDelayFilter(fhicl::ParameterSet const &p)
RandomDelayFilter Constructor.
bool filter(art::Event &e) override
Filter is a required override of art::EDFilter, and is called for each event.
A filter which delays for a random amount of time, then drops a random fraction of events...
void reconfigure(fhicl::ParameterSet const &p) override
Reconfigure the RandomDelayFilter.
RandomDelayFilter & operator=(RandomDelayFilter const &)=delete
Copy Assignment operator is deleted.