$treeview $search $mathjax $extrastylesheet
artdaq
v3_04_01
$projectbrief
|
$projectbrief
|
$searchbox |
00001 00002 // Class: RandomDelayFilter 00003 // Module Type: filter 00004 // File: RandomDelayFilter_module.cc 00005 // 00006 // Generated at Fri Mar 4 10:45:30 2016 by Eric Flumerfelt using artmod 00007 // from cetpkgsupport v1_09_00. 00009 00010 #define TRACE_NAME "RandomDelayFilter" 00011 00012 #include "art/Framework/Core/EDFilter.h" 00013 #include "art/Framework/Core/ModuleMacros.h" 00014 #include "art/Framework/Principal/Event.h" 00015 #include "art/Framework/Principal/Handle.h" 00016 #include "art/Framework/Principal/Run.h" 00017 #include "art/Framework/Principal/SubRun.h" 00018 #include "canvas/Utilities/InputTag.h" 00019 #include "fhiclcpp/ParameterSet.h" 00020 00021 #include "artdaq/DAQdata/Globals.hh" 00022 00023 #include <memory> 00024 #include <random> 00025 #include <chrono> 00026 00027 namespace artdaq 00028 { 00029 class RandomDelayFilter; 00030 } 00031 00039 class artdaq::RandomDelayFilter : public art::EDFilter 00040 { 00041 public: 00056 explicit RandomDelayFilter(fhicl::ParameterSet const& p); 00057 00061 RandomDelayFilter(RandomDelayFilter const&) = delete; 00062 00066 RandomDelayFilter(RandomDelayFilter&&) = delete; 00067 00072 RandomDelayFilter& operator=(RandomDelayFilter const&) = delete; 00073 00078 RandomDelayFilter& operator=(RandomDelayFilter&&) = delete; 00079 00089 bool filter(art::Event& e) override; 00090 00091 private: 00092 // Random Delay Parameters (min/max for uniform, mean/sigma for normal) 00093 double min_ms_; 00094 double max_ms_; 00095 double mean_ms_; 00096 double sigma_ms_; 00097 00098 int pass_factor_; 00099 double load_factor_; 00100 00101 // Random Engine Setup 00102 std::mt19937 engine_; 00103 std::unique_ptr<std::uniform_real_distribution<double>> uniform_distn_; 00104 std::unique_ptr<std::normal_distribution<double>> normal_distn_; 00105 std::unique_ptr<std::exponential_distribution<double>> exponential_distn_; 00106 std::unique_ptr<std::uniform_int_distribution<int>> pass_distn_; 00107 00108 enum class DistType { 00109 Fixed, 00110 Uniform, 00111 Normal, 00112 Exponential 00113 }; 00114 DistType distribution_type_; 00115 }; 00116 00117 00118 artdaq::RandomDelayFilter::RandomDelayFilter(fhicl::ParameterSet const& p) 00119 : min_ms_(p.get<double>("minimum_delay_ms", 0)) 00120 , max_ms_(p.get<double>("maximum_delay_ms", 1000)) 00121 , mean_ms_(p.get<double>("mean_delay_ms", 500)) 00122 , sigma_ms_(p.get<double>("sigma_delay_ms", 100)) 00123 , pass_factor_(p.get<int>("pass_filter_percentage", 100)) 00124 , load_factor_(p.get<double>("cpu_load_ratio", 0.5)) 00125 , engine_(p.get<int64_t>("random_seed", time(0))) 00126 , pass_distn_(new std::uniform_int_distribution<int>(0, 100)) 00127 { 00128 // Set limits on parameters 00129 if (pass_factor_ > 100) pass_factor_ = 100; 00130 if (pass_factor_ < 0) pass_factor_ = 0; 00131 if (load_factor_ < 0.0) load_factor_ = 0.0; 00132 if (load_factor_ > 1.0) load_factor_ = 1.0; 00133 00134 if (min_ms_ < 0) min_ms_ = 0; 00135 if (min_ms_ > max_ms_) max_ms_ = min_ms_; 00136 if (mean_ms_ < 0) mean_ms_ = 0; 00137 if (sigma_ms_ < 0) sigma_ms_ = 0; 00138 00139 auto type = p.get<std::string>("distribution_type", "Uniform"); 00140 assert(type.size() >= 1); 00141 switch (type[0]) 00142 { 00143 case 'n': 00144 case 'N': 00145 TLOG(TLVL_INFO) << "Generating delay times using Normal distribution with mean " << mean_ms_ << " ms, std. dev. " << sigma_ms_ << " ms, min " << min_ms_ << " ms and max " << max_ms_ << "ms."; 00146 distribution_type_ = DistType::Normal; 00147 if(mean_ms_ < min_ms_) { 00148 TLOG(TLVL_WARNING) << "Mean is smaller than min, setting to min"; 00149 mean_ms_ = min_ms_; 00150 } 00151 mean_ms_ -= min_ms_; // When we sample the distribution, we offset by min_ms_ 00152 normal_distn_.reset(new std::normal_distribution<double>(mean_ms_, sigma_ms_)); 00153 break; 00154 case 'e': 00155 case 'E': 00156 TLOG(TLVL_INFO) << "Generating delay times using Exponential distribution with mean " << mean_ms_ << " ms, min " << min_ms_ << " ms and max " << max_ms_ << " ms."; 00157 distribution_type_ = DistType::Exponential; 00158 if(mean_ms_ < min_ms_) { 00159 TLOG(TLVL_WARNING) << "Mean is smaller than min, setting to min"; 00160 mean_ms_ = min_ms_; 00161 } 00162 mean_ms_ -= min_ms_; // When we sample the distribution, we offset by min_ms_ 00163 if (mean_ms_ == 0) mean_ms_ = 1; 00164 exponential_distn_.reset(new std::exponential_distribution<double>(1/mean_ms_)); 00165 break; 00166 case 'U': 00167 case 'u': 00168 TLOG(TLVL_INFO) << "Generating delay times using Uniform distribution with min " << min_ms_ << " ms and max " << max_ms_ << " ms."; 00169 distribution_type_ = DistType::Uniform; 00170 uniform_distn_.reset(new std::uniform_real_distribution<double>(min_ms_, max_ms_)); 00171 break; 00172 case 'f': 00173 case 'F': 00174 default: 00175 TLOG(TLVL_INFO) << "Delay time set to " << min_ms_ << " ms."; 00176 distribution_type_ = DistType::Fixed; 00177 break; 00178 } 00179 } 00180 00181 bool artdaq::RandomDelayFilter::filter(art::Event& e) 00182 { 00183 double delay = min_ms_; 00184 do { 00185 switch (distribution_type_) 00186 { 00187 case DistType::Normal: 00188 delay += (*normal_distn_)(engine_); 00189 break; 00190 case DistType::Exponential: 00191 delay += (*exponential_distn_)(engine_); 00192 break; 00193 case DistType::Uniform: 00194 delay = (*uniform_distn_)(engine_); 00195 break; 00196 case DistType::Fixed: 00197 break; 00198 } 00199 } while(delay > max_ms_ && delay < min_ms_); 00200 TLOG(TLVL_DEBUG) << "Simulating processing of event " << e.event() << " by delaying " << delay << "ms." ; 00201 00202 usleep(1000 * (1 - load_factor_) * delay); 00203 00204 auto i = 0; 00205 auto now = std::chrono::steady_clock::now(); 00206 while (TimeUtils::GetElapsedTimeMilliseconds(now) < static_cast<size_t>(delay * load_factor_)) 00207 { 00208 i = i + 1 % std::numeric_limits<int>::max(); 00209 } 00210 00211 return (*pass_distn_)(engine_) < pass_factor_; 00212 } 00213 00214 DEFINE_ART_MODULE(artdaq::RandomDelayFilter)