24 #include "cheetah/rfim/test_utils/RfimTester.h" 25 #include "cheetah/sigproc/SigProcWriter.h" 26 #include "cheetah/generators/GaussianNoise.h" 27 #include "cheetah/generators/GaussianNoiseConfig.h" 28 #include "cheetah/generators/DispersedPulse.h" 29 #include "cheetah/generators/RfiScenario.h" 30 #include "cheetah/data/TimeFrequency.h" 31 #include "panda/test/TestDir.h" 32 #include <boost/units/systems/si/frequency.hpp> 33 #include <boost/units/systems/si/prefixes.hpp> 47 template <
typename TestTraits>
48 RfimTester<TestTraits>::RfimTester()
49 : cheetah::utils::test::AlgorithmTester<TestTraits>()
53 template <
typename TestTraits>
54 RfimTester<TestTraits>::~RfimTester()
58 template<
typename TestTraits>
59 void RfimTester<TestTraits>::SetUp()
63 template<
typename TestTraits>
64 void RfimTester<TestTraits>::TearDown()
68 template<
typename TestTraits>
69 void RfimTester<TestTraits>::verify_equal(
typename TestTraits::DataType
const& d1,
typename TestTraits::DataType
const& d2)
71 ASSERT_EQ(d1.number_of_samples(), d2.number_of_samples());
72 ASSERT_EQ(d1.number_of_channels(), d2.number_of_channels());
74 for(
auto const val : d1) {
75 ASSERT_DOUBLE_EQ(val, *it++);
79 template<
typename DataType>
81 std::shared_ptr<DataType> generate_time_freq_data(
unsigned number_of_samples,
unsigned number_of_channels)
83 typedef typename DataType::FrequencyType FrequencyType;
85 std::shared_ptr<DataType> data = std::make_shared<DataType>(number_of_samples, number_of_channels);
86 FrequencyType delta( 1.0 * boost::units::si::mega * boost::units::si::hertz);
87 FrequencyType start( 100.0 * boost::units::si::mega * boost::units::si::hertz);
89 data->set_channel_frequencies_const_width(start, delta);
96 template <
typename TypeParam,
typename DeviceType>
97 void test_rfi_algorithm(
99 typename TypeParam::FlaggedDataType::TimeFrequencyFlagsType
const &,
100 typename TypeParam::FlaggedDataType::TimeFrequencyFlagsType
const &)> assertion,
101 DeviceType &device,
typename TypeParam::FlaggedDataType &data)
103 using DataType =
typename TypeParam::DataType;
104 using TimeFrequencyFlags =
typename TypeParam::FlaggedDataType::TimeFrequencyFlagsType;
106 TimeFrequencyFlags expected_flags(data.rfi_flags());
109 std::shared_ptr<typename TypeParam::FlaggedDataType> result = tester.apply_algorithm(device, data.tf_data());
111 assertion(expected_flags, result->rfi_flags());
115 struct TestDataWriter
118 TestDataWriter(std::string
const& prefix,
bool record_files)
119 : _test_dir(!record_files)
120 , _prefix(_test_dir.path() / prefix)
121 , _record(record_files)
124 boost::filesystem::create_directory(_prefix);
127 template<
typename DataType>
128 void write(std::string
const& test_name, DataType
const& data) {
131 boost::filesystem::path dir(_prefix/test_name);
132 if(!boost::filesystem::create_directory(dir)) {
133 panda::Error e(
"unable to create directory:");
137 std::cout <<
"writing to " << dir;
138 sigproc::SigProcWriter<> sigproc_writer(_prefix / test_name);
139 sigproc_writer << data::ExtractTimeFrequencyDataType<DataType>::extract(data);
144 panda::test::TestDir _test_dir;
145 boost::filesystem::path _prefix;
150 template<
int Num,
typename TypeParam,
typename DeviceType,
typename Enable =
void>
152 typedef typename TypeParam::DataType DataType;
154 void exec(DataType
const&, DeviceType&) {
160 template<
int Num,
typename TypeParam,
typename DeviceType>
161 struct RfiScenarioLauncher<Num, TypeParam, DeviceType, typename
std::enable_if<std::is_constructible<generators::RfiScenario<Num, TypeParam>>::value>::type >
163 typedef typename TypeParam::DataType DataType;
164 typedef typename TypeParam::FlaggedDataType FlaggedDataType;
165 typedef typename FlaggedDataType::TimeFrequencyFlagsType TimeFrequencyFlags;
166 typedef typename DataType::NumericalRep NumRepType;
173 std::string
const test_name(
"RfiScenario<" + std::to_string(Num) +
">: " + std::string(Scenario::description));
174 std::cout <<
"running test: " << test_name << std::endl;
179 TestDataWriter file_writer(test_name,
false);
180 file_writer.write(
"tf_data_input", data);
181 test_rfi_algorithm<TypeParam>(
182 [test_name] (TimeFrequencyFlags
const &expected, TimeFrequencyFlags
const &given)
184 SCOPED_TRACE( test_name );
186 std::cout << test_name <<
" metrics\n" 188 <<
"\t" <<
"false +ve=" << m.
num_false_positives() <<
" (" << m.false_positives_percentage() <<
"%)\n" 189 <<
"\t" <<
"false -ve=" << m.
num_false_negatives() <<
" (" << m.false_negatives_percentage() <<
"%)\n" 199 ALGORITHM_TYPED_TEST_P(
RfimTester, gaussian_noise_wth_rfi)
203 typedef typename TypeParam::DataType DataType;
204 typedef typename TypeParam::FlaggedDataType FlaggedDataType;
205 using TimeFrequencyFlags =
typename FlaggedDataType::TimeFrequencyFlagsType;
206 using NumericalRep =
typename DataType::NumericalRep;
207 typename DataType::FrequencyType delta( 1.0 * boost::units::si::mega * boost::units::si::hertz);
208 typename DataType::FrequencyType start( 100.0 * boost::units::si::mega * boost::units::si::hertz);
212 std::shared_ptr<DataType> time_frequency_data(
new DataType(data::DimensionSize<data::Time>(2048), data::DimensionSize<data::Frequency>(1024)));
213 time_frequency_data->sample_interval(
typename DataType::TimeType( 0.01 * boost::units::si::seconds));
214 time_frequency_data->set_channel_frequencies_const_width(start, delta);
216 auto& flags = flagged_time_frequency_data.rfi_flags();
217 std::fill(flags.begin(), flags.end(),
false);
220 noise.next(*time_frequency_data);
224 typedef decltype(device) DeviceType;
228 ALGORITHM_TYPED_TEST_P(
RfimTester, single_pulse_on_gaussian_noise_wth_rfi)
232 typedef typename TypeParam::DataType DataType;
233 typedef typename TypeParam::FlaggedDataType FlaggedDataType;
234 using TimeFrequencyFlags =
typename FlaggedDataType::TimeFrequencyFlagsType;
235 using NumericalRep =
typename DataType::NumericalRep;
236 typename DataType::FrequencyType delta( 1.0 * boost::units::si::mega * boost::units::si::hertz);
237 typename DataType::FrequencyType start( 100.0 * boost::units::si::mega * boost::units::si::hertz);
244 std::shared_ptr<DataType> time_frequency_data(
new DataType(data::DimensionSize<data::Time>(16384), data::DimensionSize<data::Frequency>(1024)));
245 time_frequency_data->set_channel_frequencies_const_width(start, delta);
246 time_frequency_data->sample_interval(
typename DataType::TimeType( 0.01 * boost::units::si::seconds));
250 noise.next(*time_frequency_data);
251 pulse_generator.next(flagged_time_frequency_data);
255 typedef decltype(device) DeviceType;
261 REGISTER_TYPED_TEST_CASE_P(
RfimTester, gaussian_noise_wth_rfi, single_pulse_on_gaussian_noise_wth_rfi);
float correct_percentage() const
return the total of any correct flags as a percentage
float rfi_detected_percentage() const
return the total of any correct flags as a percentage
std::size_t num_correct() const
return the total of any correctly identified flags found
TimeFrequency data with flags representing rfim detection.
Some limits and constants for FLDO.
std::size_t num_false_positives() const
return the total of any false positives detected
Configuration parameters for the DispersedPulse generator.
std::size_t num_false_negatives() const
return the number of any false negatives detected
A class for analysing and storing the results of the difference between two sets of flags representin...
std::size_t num_rfi() const
return the number of rfi flags in the expected data
Collection of RFI scenarios.
Inject a single pulse at a specified dispersion measure.
Specialise to set non-standard pass/fail criteria.