00001
00002
00003
00004
00005
00006
00007
00009
00010 #include "art/Framework/Core/EDFilter.h"
00011 #include "art/Framework/Core/ModuleMacros.h"
00012 #include "art/Framework/Principal/Event.h"
00013 #include "art/Framework/Principal/Handle.h"
00014 #include "art/Framework/Principal/Run.h"
00015 #include "art/Framework/Principal/SubRun.h"
00016 #include "canvas/Utilities/InputTag.h"
00017 #include "fhiclcpp/ParameterSet.h"
00018
00019 #include "artdaq/DAQdata/Globals.hh"
00020
00021 #include <memory>
00022 #include <random>
00023 #include <chrono>
00024
00025 namespace artdaq
00026 {
00027 class RandomDelayFilter;
00028 }
00029
00037 class artdaq::RandomDelayFilter : public art::EDFilter
00038 {
00039 public:
00054 explicit RandomDelayFilter(fhicl::ParameterSet const& p);
00055
00059 RandomDelayFilter(RandomDelayFilter const&) = delete;
00060
00064 RandomDelayFilter(RandomDelayFilter&&) = delete;
00065
00070 RandomDelayFilter& operator=(RandomDelayFilter const&) = delete;
00071
00076 RandomDelayFilter& operator=(RandomDelayFilter&&) = delete;
00077
00087 bool filter(art::Event& e) override;
00088
00103 void reconfigure(fhicl::ParameterSet const& p) override;
00104
00105 private:
00106
00107 double min_ms_;
00108 double max_ms_;
00109 double mean_ms_;
00110 double sigma_ms_;
00111
00112 int pass_factor_;
00113 double load_factor_;
00114
00115
00116 bool isNormal_;
00117 std::mt19937 engine_;
00118 std::unique_ptr<std::uniform_real_distribution<double>> uniform_distn_;
00119 std::unique_ptr<std::normal_distribution<double>> normal_distn_;
00120 std::unique_ptr<std::uniform_int_distribution<int>> pass_distn_;
00121 };
00122
00123
00124 artdaq::RandomDelayFilter::RandomDelayFilter(fhicl::ParameterSet const& p)
00125 : min_ms_(p.get<double>("minimum_delay_ms", 0))
00126 , max_ms_(p.get<double>("maximum_delay_ms", 1000))
00127 , mean_ms_(p.get<double>("mean_delay_ms", 500))
00128 , sigma_ms_(p.get<double>("sigma_delay_ms", 100))
00129 , pass_factor_(p.get<int>("pass_filter_percentage", 100))
00130 , load_factor_(p.get<double>("cpu_load_ratio", 1.0))
00131 , isNormal_(p.get<bool>("use_normal_distribution", false))
00132 , engine_(p.get<int64_t>("random_seed", 271828))
00133 , pass_distn_(new std::uniform_int_distribution<int>(0, 100))
00134 {
00135
00136 if (pass_factor_ > 100) pass_factor_ = 100;
00137 if (pass_factor_ < 0) pass_factor_ = 0;
00138 if (load_factor_ < 0.0) load_factor_ = 0.0;
00139 if (load_factor_ > 1.0) load_factor_ = 1.0;
00140
00141 if (min_ms_ < 0) min_ms_ = 0;
00142 if (min_ms_ > max_ms_) max_ms_ = min_ms_;
00143 if (mean_ms_ < 0) mean_ms_ = 0;
00144 if (sigma_ms_ < 0) sigma_ms_ = 0;
00145
00146 uniform_distn_.reset(new std::uniform_real_distribution<double>(min_ms_, max_ms_));
00147 normal_distn_.reset(new std::normal_distribution<double>(mean_ms_, sigma_ms_));
00148 }
00149
00150 bool artdaq::RandomDelayFilter::filter(art::Event& e)
00151 {
00152 double delay = isNormal_ ? (*normal_distn_)(engine_) : (*uniform_distn_)(engine_);
00153 TLOG_DEBUG("RandomDelayFilter") << "Simulating processing of event " << e.event() << " by delaying " << std::to_string(delay) << "ms." << TLOG_ENDL;
00154
00155 usleep(1000 * (1 - load_factor_) * delay);
00156
00157 auto i = 0;
00158 auto now = std::chrono::steady_clock::now();
00159 while (std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - now).count() < delay * load_factor_)
00160 {
00161 i = i + 1 % std::numeric_limits<int>::max();
00162 }
00163
00164 return (*pass_distn_)(engine_) < pass_factor_;
00165 }
00166
00167 void artdaq::RandomDelayFilter::reconfigure(fhicl::ParameterSet const& p)
00168 {
00169 min_ms_ = p.get<double>("minimum_delay_ms", 0);
00170 max_ms_ = p.get<double>("maximum_delay_ms", 1000);
00171 mean_ms_ = p.get<double>("mean_delay_ms", 500);
00172 sigma_ms_ = p.get<double>("sigma_delay_ms", 100);
00173 pass_factor_ = p.get<int>("pass_filter_percentage", 100);
00174 load_factor_ = p.get<double>("cpu_load_ratio", 1.0);
00175 isNormal_ = p.get<bool>("use_normal_distribution", false);
00176 engine_ = std::mt19937(p.get<int64_t>("random_seed", 271828));
00177
00178
00179 if (pass_factor_ > 100) pass_factor_ = 100;
00180 if (pass_factor_ < 0) pass_factor_ = 0;
00181 if (load_factor_ < 0.0) load_factor_ = 0.0;
00182 if (load_factor_ > 1.0) load_factor_ = 1.0;
00183
00184 if (min_ms_ < 0) min_ms_ = 0;
00185 if (min_ms_ > max_ms_) max_ms_ = min_ms_;
00186 if (mean_ms_ < 0) mean_ms_ = 0;
00187 if (sigma_ms_ < 0) sigma_ms_ = 0;
00188
00189 uniform_distn_.reset(new std::uniform_real_distribution<double>(min_ms_, max_ms_));
00190 normal_distn_.reset(new std::normal_distribution<double>(mean_ms_, sigma_ms_));
00191 }
00192
00193 DEFINE_ART_MODULE(artdaq::RandomDelayFilter)