diff --git a/IB_collab_mode.py b/IB_collab_mode.py index bce4a53..e6ec0b0 100644 --- a/IB_collab_mode.py +++ b/IB_collab_mode.py @@ -15,7 +15,7 @@ from experiment_prototype.experiment_prototype import ExperimentPrototype import borealis_experiments.superdarn_common_fields as scf -from experiment_prototype.decimation_scheme.decimation_scheme import \ +from experiment_prototype.experiment_utils.decimation_scheme import \ DecimationScheme, DecimationStage, create_firwin_filter_by_attenuation @@ -68,14 +68,12 @@ def __init__(self, **kwargs): if kwargs: if 'freq' in kwargs.keys(): freq = int(kwargs['freq']) - self.printing('Using frequency scheduled for {date}: {freq} kHz' - .format(date=datetime.datetime.utcnow().strftime('%Y%m%d %H:%M'), freq=freq)) + print('Using frequency scheduled for {date}: {freq} kHz' # TODO: Log + .format(date=datetime.datetime.utcnow().strftime('%Y%m%d %H:%M'), freq=freq)) else: - self.printing('Frequency not found: using default frequency {freq} kHz' - .format(freq=freq)) + print('Frequency not found: using default frequency {freq} kHz'.format(freq=freq)) # TODO: Log else: - self.printing('Frequency not found: using default frequency {freq} kHz' - .format(freq=freq)) + print('Frequency not found: using default frequency {freq} kHz'.format(freq=freq)) # TODO: Log decimation_scheme = create_15km_scheme() @@ -99,6 +97,7 @@ def __init__(self, **kwargs): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": decimation_scheme, } list_of_slices = [slice_1] @@ -111,7 +110,7 @@ def __init__(self, **kwargs): super().__init__( cpid, txctrfreq=txctrfreq, output_rx_rate=decimation_scheme.output_sample_rate, - rxctrfreq=rxctrfreq, decimation_scheme=decimation_scheme, + rxctrfreq=rxctrfreq, comment_string='ICEBEAR, 5 beam, 2s integration, 15 km') self.add_slice(slice_1) diff --git a/bistatic_test.py b/bistatic_test.py index cd37b0d..d86e46d 100644 --- a/bistatic_test.py +++ b/bistatic_test.py @@ -61,7 +61,7 @@ def __init__(self, **kwargs): "freq": freq, # kHz "scanbound": [i * 3.7 for i in range(len(scf.STD_16_BEAM_ANGLE))], # align each aveperiod to 3.7s boundary "wait_for_first_scanbound": False, - "align_sequences": True # align start of sequence to tenths of a second + "align_sequences": True, # align start of sequence to tenths of a second } if 'listen_to' in kwargs.keys() and 'beam_order' in kwargs.keys(): # Mutually exclusive arguments diff --git a/borealis_paper.py b/borealis_paper.py index 38e238a..a7cb297 100644 --- a/borealis_paper.py +++ b/borealis_paper.py @@ -37,7 +37,8 @@ def __init__(self): "rx_beam_order": [0], "tx_beam_order": [0], "freq" : 13100, - "acf" : True + "acf" : True, + } slice2 = copy.deepcopy(default_slice) diff --git a/eeaao.py b/eeaao.py new file mode 100644 index 0000000..abf3aaa --- /dev/null +++ b/eeaao.py @@ -0,0 +1,109 @@ +#!/usr/bin/python + +""" + eeaao + ~~~~~~~~~~~~~ + The mode is a flexible multistatic multifrequency full FOV mode. + Transmit and receive frequencies are configured via command line arguments. + + :copyright: 2023 SuperDARN Canada + :author: Remington Rohel +""" +import copy + +import borealis_experiments.superdarn_common_fields as scf +from experiment_prototype.experiment_prototype import ExperimentPrototype + + +class EEAAO(ExperimentPrototype): + """ + This experiment is configurable via arguments. The TX and RX frequencies in kHz must be specified by kwargs. + All TX frequencies specified will also be used as RX frequencies, and at least one frequency must be specified as + either an RX or TX frequency. + """ + def __init__(self, **kwargs): + """ + kwargs: + tx_freqs: str, list of frequencies in kHz to transmit on. Format as "[10500,12000]" or "10500,12000" + rx_freqs: str, list of frequencies in kHz to receive on. Format as "[10600,12200]" or "10600,12200" + """ + cpid = 3777 + + def parse_freqs_from_string(freqs): + freq_list = [] + if freqs: + for f in freqs.strip('[]').split(','): + freq_list.append(int(f)) + return freq_list + + tx_freqs = parse_freqs_from_string(kwargs.get('tx_freqs', '')) # Default to no frequencies specified + rx_freqs = parse_freqs_from_string(kwargs.get('rx_freqs', '')) # Default to no frequencies specified + + all_freqs = set(tx_freqs).union(set(rx_freqs)) + if len(all_freqs) == 0: + raise ValueError(f"No RX or TX frequencies specified.\t" + f"tx_freqs: {kwargs.get('tx_freqs', '')}\t" + f"rx_freqs: {kwargs.get('rx_freqs', '')}") + + if len(set(tx_freqs)) != len(tx_freqs): + raise ValueError(f"Duplicate TX frequencies specified: {tx_freqs}") + if len(set(rx_freqs)) != len(rx_freqs): + raise ValueError(f"Duplicate RX frequencies specified: {rx_freqs}") + + # Calculate center frequency + max_freq = max(all_freqs) + min_freq = min(all_freqs) + center_freq = (max_freq + min_freq) / 2.0 # Center frequency set to middle of the range + + comment_string = f"TX freqs: {tx_freqs}, RX freqs: {rx_freqs}" + + super().__init__(cpid, txctrfreq=center_freq, rxctrfreq=center_freq, comment_string=comment_string) + + default_slice = { + "pulse_sequence": scf.SEQUENCE_7P, + "tau_spacing": scf.TAU_SPACING_7P, + "pulse_len": scf.PULSE_LEN_45KM, + "num_ranges": scf.STD_NUM_RANGES, + "first_range": scf.STD_FIRST_RANGE, + "intt": scf.INTT_7P, # duration of an integration, in ms + "beam_angle": scf.STD_16_BEAM_ANGLE, + "rx_beam_order": [scf.STD_16_FORWARD_BEAM_ORDER], # All beams + "scanbound": [i * 3.7 for i in range(len(scf.STD_16_BEAM_ANGLE))], # align each aveperiod to 3.7s boundary + "wait_for_first_scanbound": False, + "align_sequences": True, # align start of sequence to tenths of a second + } + + num_antennas = scf.options.main_antenna_count + left_half_antennas = [i for i in range(num_antennas // 2)] + right_half_antennas = [i for i in range(num_antennas // 2, num_antennas)] + all_antennas = [i for i in range(num_antennas)] + + all_slices = [] + for i, freq in enumerate(tx_freqs): + new_slice = copy.deepcopy(default_slice) + new_slice['freq'] = freq + new_slice['tx_antenna_pattern'] = scf.easy_widebeam + if len(tx_freqs) == 2: # Use 8-antenna wide-beam mode if only transmitting on two frequencies + if i == 0: + new_slice['tx_antennas'] = left_half_antennas + else: + new_slice['tx_antennas'] = right_half_antennas + else: # Use 16-antenna wide-beam mode otherwise + new_slice['tx_antennas'] = all_antennas + new_slice['tx_beam_order'] = [0] + new_slice['comment'] = f"TX slice with frequency {freq}" + all_slices.append(new_slice) + + # Add the slices to the experiment + for freq in rx_freqs: + if freq in tx_freqs: # Already listening on this frequency, skip + continue + new_slice = copy.deepcopy(default_slice) + new_slice['freq'] = freq + new_slice['rxonly'] = True + new_slice['comment'] = f"RX slice with frequency {freq}" + all_slices.append(new_slice) + + self.add_slice(all_slices[0]) + for this_slice in all_slices[1:]: + self.add_slice(this_slice, {0: 'CONCURRENT'}) diff --git a/epop2023.py b/epop2023.py new file mode 100644 index 0000000..e2a1da1 --- /dev/null +++ b/epop2023.py @@ -0,0 +1,61 @@ +#!/usr/bin/python +""" +Copyright SuperDARN Canada 2023 +This mode was made for collaboration with the RRI instrument on the CASSIOPE satellite +by request of Dr. Kuldeep Pandey in February 2023. +""" + +import numpy as np + +import borealis_experiments.superdarn_common_fields as scf +from experiment_prototype.experiment_prototype import ExperimentPrototype + + +def boresight(frequency_khz, tx_antennas, antenna_spacing_m): + """tx_antenna_pattern function for boresight transmission.""" + num_antennas = scf.options.main_antenna_count + pattern = np.zeros((1, num_antennas), dtype=np.complex64) + pattern[0, tx_antennas] = 1.0 + 0.0j + return pattern + + +class Epop2023(ExperimentPrototype): + def __init__(self, **kwargs): + """ + kwargs: + + freq: int, kHz + + """ + cpid = 3813 + super().__init__(cpid) + + num_ranges = scf.STD_NUM_RANGES + if scf.options.site_id in ["cly", "rkn", "inv"]: + num_ranges = scf.POLARDARN_NUM_RANGES + + # default frequency set here + freq = scf.COMMON_MODE_FREQ_1 + + if kwargs: + if 'freq' in kwargs.keys(): + freq = int(kwargs['freq']) + + print('Frequency set to {}'.format(freq)) + + slice_0 = { # slice_id = 0 + "pulse_sequence": scf.SEQUENCE_7P, + "tau_spacing": scf.TAU_SPACING_7P, + "pulse_len": scf.PULSE_LEN_45KM, + "num_ranges": num_ranges, + "first_range": scf.STD_FIRST_RANGE, + "intt": 3500, # duration of an integration, in ms + "beam_angle": [0.0], # boresight only + "rx_beam_order": [0], # boresight only + "tx_beam_order": [0], # only one pattern + "tx_antenna_pattern": boresight, + "freq": freq, # kHz + "align_sequences": True, # align start of sequence to tenths of a second + } + + self.add_slice(slice_0) \ No newline at end of file diff --git a/epopsound.py b/epopsound.py index 02ad083..1b4062f 100644 --- a/epopsound.py +++ b/epopsound.py @@ -47,9 +47,8 @@ def __init__(self, **kwargs): if 'marker_period' in kwargs.keys(): marker_period = int(kwargs['marker_period']) - self.printing('Freqs (kHz): {}, Start Beam: {}, Stop Beam: {}, ' - 'Marker Period: {}, ' - .format(freqs, startbeam, stopbeam, marker_period)) + print('Freqs (kHz): {}, Start Beam: {}, Stop Beam: {}, Marker Period: {}, ' # TODO: Log + .format(freqs, startbeam, stopbeam, marker_period)) if scf.options.site_id in ["cly", "rkn", "inv"]: num_ranges = scf.POLARDARN_NUM_RANGES @@ -84,7 +83,7 @@ def __init__(self, **kwargs): "tx_beam_order": beams_to_use, "acf": True, "xcf": True, - "acfint": True + "acfint": True, } for freq in freqs: diff --git a/epopsound_one_beam.py b/epopsound_one_beam.py index fdecb5b..6dcd87e 100644 --- a/epopsound_one_beam.py +++ b/epopsound_one_beam.py @@ -45,9 +45,7 @@ def __init__(self, **kwargs): if 'marker_period' in kwargs.keys(): marker_period = int(kwargs['marker_period']) - self.printing('Freqs (kHz): {}, Beam: {}, ' - 'Marker Period: {}' - .format(freqs, beam, marker_period)) + print('Freqs (kHz): {}, Beam: {}, Marker Period: {}'.format(freqs, beam, marker_period)) # TODO: Log center_freq = int(sum(freqs)/len(freqs)) @@ -67,7 +65,7 @@ def __init__(self, **kwargs): "beam_angle": scf.STD_16_BEAM_ANGLE, "acf": True, "xcf": True, - "acfint": True + "acfint": True, } for num, freq in enumerate(freqs): @@ -95,8 +93,7 @@ def __init__(self, **kwargs): slices.append(new_slice) - super().__init__(cpid=cpid, txctrfreq=center_freq, rxctrfreq=center_freq, - comment_string=Epopsound.__doc__) + super().__init__(cpid=cpid, txctrfreq=center_freq, rxctrfreq=center_freq, comment_string=Epopsound.__doc__) self.add_slice(slices[0]) if len(slices) > 1: diff --git a/experiment_archive/normalscan.py b/experiment_archive/normalscan.py index 1e2e11c..9fd445e 100644 --- a/experiment_archive/normalscan.py +++ b/experiment_archive/normalscan.py @@ -2,7 +2,7 @@ # write an experiment that creates a new control program. from experiment_prototype.experiment_prototype import ExperimentPrototype -from experiment_prototype.decimation_scheme.decimation_scheme import DecimationStage, DecimationScheme +from experiment_prototype.experiment_utils.decimation_scheme import DecimationStage, DecimationScheme from borealis_experiments.test_decimation_schemes import * class Normalscan(ExperimentPrototype): diff --git a/experiment_archive/test_decimation_schemes.py b/experiment_archive/test_decimation_schemes.py index f2273f8..1de9729 100644 --- a/experiment_archive/test_decimation_schemes.py +++ b/experiment_archive/test_decimation_schemes.py @@ -3,7 +3,7 @@ import os import sys -from experiment_prototype.decimation_scheme.decimation_scheme import DecimationStage, DecimationScheme, \ +from experiment_prototype.experiment_utils.decimation_scheme import DecimationStage, DecimationScheme, \ create_firwin_filter_by_num_taps, create_firwin_filter_by_attenuation diff --git a/experiment_archive/test_filters_1.py b/experiment_archive/test_filters_1.py index 604af79..e5dc769 100644 --- a/experiment_archive/test_filters_1.py +++ b/experiment_archive/test_filters_1.py @@ -6,7 +6,7 @@ sys.path.append(os.environ['BOREALISPATH']) # write an experiment that creates a new control program. from experiment_prototype.experiment_prototype import ExperimentPrototype -from experiment_prototype.decimation_scheme.decimation_scheme import DecimationStage, DecimationScheme +from experiment_prototype.experiment_utils.decimation_scheme import DecimationStage, DecimationScheme from borealis_experiments.test_decimation_schemes import * class OneBox(ExperimentPrototype): diff --git a/experiment_archive/test_scheme_9.py b/experiment_archive/test_scheme_9.py index f65a163..df6ebad 100644 --- a/experiment_archive/test_scheme_9.py +++ b/experiment_archive/test_scheme_9.py @@ -6,7 +6,7 @@ sys.path.append(os.environ['BOREALISPATH']) # write an experiment that creates a new control program. from experiment_prototype.experiment_prototype import ExperimentPrototype -from experiment_prototype.decimation_scheme.decimation_scheme import DecimationStage, DecimationScheme +from experiment_prototype.experiment_utils.decimation_scheme import DecimationStage, DecimationScheme from borealis_experiments.test_decimation_schemes import * class TestScheme9(ExperimentPrototype): diff --git a/experiment_archive/test_scheme_9_acfs.py b/experiment_archive/test_scheme_9_acfs.py index 8a59c8c..73e9af4 100644 --- a/experiment_archive/test_scheme_9_acfs.py +++ b/experiment_archive/test_scheme_9_acfs.py @@ -6,7 +6,7 @@ sys.path.append(os.environ['BOREALISPATH']) # write an experiment that creates a new control program. from experiment_prototype.experiment_prototype import ExperimentPrototype -from experiment_prototype.decimation_scheme.decimation_scheme import DecimationStage, DecimationScheme +from experiment_prototype.experiment_utils.decimation_scheme import DecimationStage, DecimationScheme from borealis_experiments.test_decimation_schemes import * class TestScheme9ACFs(ExperimentPrototype): diff --git a/experiment_archive/twofsound.py b/experiment_archive/twofsound.py index 0117338..150027c 100644 --- a/experiment_archive/twofsound.py +++ b/experiment_archive/twofsound.py @@ -9,7 +9,7 @@ #import test from experiment_prototype.experiment_prototype import ExperimentPrototype -from experiment_prototype.decimation_scheme.decimation_scheme import DecimationStage, DecimationScheme +from experiment_prototype.experiment_utils.decimation_scheme import DecimationStage, DecimationScheme from borealis_experiments.test_decimation_schemes import * class Twofsound(ExperimentPrototype): diff --git a/full_fov.py b/full_fov.py index c6b2a33..84a2662 100644 --- a/full_fov.py +++ b/full_fov.py @@ -37,7 +37,7 @@ def __init__(self, **kwargs): if 'freq' in kwargs.keys(): freq = kwargs['freq'] - self.printing('Frequency set to {}'.format(freq)) + print('Frequency set to {}'.format(freq)) # TODO: Log num_antennas = scf.options.main_antenna_count @@ -56,6 +56,6 @@ def __init__(self, **kwargs): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs - "align_sequences": True # align start of sequence to tenths of a second + "align_sequences": True, # align start of sequence to tenths of a second }) diff --git a/full_fov_15km.py b/full_fov_15km.py index fe5b1f5..27e9bab 100644 --- a/full_fov_15km.py +++ b/full_fov_15km.py @@ -13,7 +13,7 @@ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype -from experiment_prototype.decimation_scheme.decimation_scheme import \ +from experiment_prototype.experiment_utils.decimation_scheme import \ DecimationScheme, DecimationStage, create_firwin_filter_by_attenuation @@ -60,7 +60,7 @@ def __init__(self, **kwargs): cpid = 3801 decimation_scheme = create_15km_scheme() - super().__init__(cpid, output_rx_rate=decimation_scheme.output_sample_rate, decimation_scheme=decimation_scheme, + super().__init__(cpid, output_rx_rate=decimation_scheme.output_sample_rate, comment_string='Full FOV 15km Resolution Experiment') num_ranges = scf.STD_NUM_RANGES * 3 # Each range is a third of the usual size, want same spatial extent @@ -72,7 +72,7 @@ def __init__(self, **kwargs): if 'freq' in kwargs.keys(): freq = kwargs['freq'] - self.printing('Frequency set to {}'.format(freq)) + print('Frequency set to {}'.format(freq)) # TODO: Log num_antennas = scf.options.main_antenna_count @@ -88,5 +88,6 @@ def __init__(self, **kwargs): "tx_beam_order": [0], # only one pattern "tx_antenna_pattern": scf.easy_widebeam, "freq": freq, # kHz + "decimation_scheme": create_15km_scheme(), }) diff --git a/full_fov_2freq.py b/full_fov_2freq.py index b9a2cb9..b34ab78 100644 --- a/full_fov_2freq.py +++ b/full_fov_2freq.py @@ -63,7 +63,7 @@ def __init__(self, **kwargs): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs - "align_sequences": True # align start of sequence to tenths of a second + "align_sequences": True, # align start of sequence to tenths of a second } # Transmit on the second frequency on the right half of the array diff --git a/full_fov_3freq.py b/full_fov_3freq.py index a0f56c1..dd666ed 100644 --- a/full_fov_3freq.py +++ b/full_fov_3freq.py @@ -62,7 +62,7 @@ def __init__(self, **kwargs): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs - "align_sequences": True # align start of sequence to tenths of a second + "align_sequences": True, # align start of sequence to tenths of a second } # Transmit on the second frequency on the right half of the array diff --git a/full_fov_comparison.py b/full_fov_comparison.py index 244149b..b88bff3 100644 --- a/full_fov_comparison.py +++ b/full_fov_comparison.py @@ -48,7 +48,7 @@ def __init__(self, **kwargs): if 'freq' in kwargs.keys(): freq = kwargs['freq'] - self.printing('Frequency set to {}'.format(freq)) + print('Frequency set to {}'.format(freq)) # TODO: Log num_antennas = scf.options.main_antenna_count @@ -66,7 +66,7 @@ def __init__(self, **kwargs): "freq": freq, # kHz "align_sequences": True, # align start of sequence to tenths of a second "scanbound": scf.easy_scanbound(scf.INTT_7P, scf.STD_16_BEAM_ANGLE), - "wait_for_first_scanbound": False + "wait_for_first_scanbound": False, } slice_1 = copy.deepcopy(slice_0) diff --git a/fullscanstepmode.py b/fullscanstepmode.py index f804a1e..b2d5b1c 100644 --- a/fullscanstepmode.py +++ b/fullscanstepmode.py @@ -89,7 +89,7 @@ def move_freqs(direction): "acf": True, "xcf": True, # cross-correlation processing "acfint" : True, # interferometer acfs - "comment" : FullScanStepMode.__doc__ + "comment" : FullScanStepMode.__doc__, } slices.append(s) diff --git a/haarpscan.py b/haarpscan.py index f4b6557..a7ddc43 100644 --- a/haarpscan.py +++ b/haarpscan.py @@ -43,7 +43,7 @@ def __init__(self, **kwargs): if 'freq' in kwargs.keys(): freq = kwargs['freq'] - self.printing('Frequency set to {}'.format(freq)) + print('Frequency set to {}'.format(freq)) # TODO: Log self.add_slice({ # slice_id = 0, there is only one slice. "pulse_sequence": scf.SEQUENCE_7P, diff --git a/impttest.py b/impttest.py index 9edc657..f267c3f 100644 --- a/impttest.py +++ b/impttest.py @@ -21,6 +21,7 @@ def phase_encode(beam_iter, sequence_num, num_pulses): return np.random.uniform(-180.0, 180, num_pulses) + class ImptTest(ExperimentPrototype): def __init__(self): diff --git a/interleavesound.py b/interleavesound.py index 73b6379..bbe6be1 100644 --- a/interleavesound.py +++ b/interleavesound.py @@ -76,12 +76,12 @@ def __init__(self): }) sum_of_freq = 0 + all_freqs = [] for slice in slices: - sum_of_freq += slice['freq'] # kHz, oscillator mixer frequency on the USRP for TX - rxctrfreq = txctrfreq = int(sum_of_freq / len(slices)) + all_freqs.append(slice['freq']) # kHz, oscillator mixer frequency on the USRP for TX + rxctrfreq = txctrfreq = int((max(all_freqs) + min(all_freqs)) / 2) - super().__init__(cpid, txctrfreq=txctrfreq, rxctrfreq=rxctrfreq, - comment_string=InterleaveSound.__doc__) + super().__init__(cpid, txctrfreq=txctrfreq, rxctrfreq=rxctrfreq, comment_string=InterleaveSound.__doc__) self.add_slice(slices[0]) self.add_slice(slices[1], {0: 'SCAN'}) diff --git a/listening_normalscan_1.py b/listening_normalscan_1.py index 448f466..0ea8c11 100644 --- a/listening_normalscan_1.py +++ b/listening_normalscan_1.py @@ -65,4 +65,5 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "rxonly": True, }, interfacing_dict={0: 'SCAN'}) diff --git a/listening_normalscan_2.py b/listening_normalscan_2.py index 8b181e9..0f5911a 100644 --- a/listening_normalscan_2.py +++ b/listening_normalscan_2.py @@ -69,4 +69,5 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "rxonly": True, }, interfacing_dict={0: 'CONCURRENT'}) diff --git a/narrow_wide_comparison.py b/narrow_wide_comparison.py index 35d483c..31e44a0 100644 --- a/narrow_wide_comparison.py +++ b/narrow_wide_comparison.py @@ -49,7 +49,7 @@ def __init__(self, **kwargs): if 'freq' in kwargs.keys(): freq = kwargs['freq'] - self.printing('Frequency set to {}'.format(freq)) + print('Frequency set to {}'.format(freq)) # TODO: Log slice_0 = { # slice_id = 0 "pulse_sequence": scf.SEQUENCE_7P, @@ -65,7 +65,7 @@ def __init__(self, **kwargs): "freq": freq, # kHz "align_sequences": True, # align start of sequence to tenths of a second "scanbound": scf.easy_scanbound(scf.INTT_7P, scf.STD_16_BEAM_ANGLE), - "wait_for_first_scanbound": False + "wait_for_first_scanbound": False, } slice_1 = copy.deepcopy(slice_0) diff --git a/normalscan.py b/normalscan.py index fcdf9f7..f9bffa2 100644 --- a/normalscan.py +++ b/normalscan.py @@ -41,7 +41,7 @@ def __init__(self, **kwargs): if 'freq' in kwargs.keys(): freq = kwargs['freq'] - self.printing('Frequency set to {}'.format(freq)) + print('Frequency set to {}'.format(freq)) # TODO: Log self.add_slice({ # slice_id = 0, there is only one slice. "pulse_sequence": scf.SEQUENCE_7P, diff --git a/normalscan_aligned.py b/normalscan_aligned.py index 34f27cb..ddd9c6a 100644 --- a/normalscan_aligned.py +++ b/normalscan_aligned.py @@ -41,7 +41,7 @@ def __init__(self, **kwargs): if 'freq' in kwargs.keys(): freq = kwargs['freq'] - self.printing('Frequency set to {}'.format(freq)) + print('Frequency set to {}'.format(freq)) # TODO: Log self.add_slice({ # slice_id = 0, there is only one slice. "pulse_sequence": scf.SEQUENCE_7P, @@ -58,6 +58,6 @@ def __init__(self, **kwargs): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs - "align_sequences": True # align start of sequence to tenths of a second + "align_sequences": True, # align start of sequence to tenths of a second }) diff --git a/normalscan_intn.py b/normalscan_intn.py index 73f6e27..6f24511 100644 --- a/normalscan_intn.py +++ b/normalscan_intn.py @@ -41,7 +41,7 @@ def __init__(self, **kwargs): if 'freq' in kwargs.keys(): freq = kwargs['freq'] - self.printing('Frequency set to {}'.format(freq)) + print('Frequency set to {}'.format(freq)) # TODO: Log self.add_slice({ # slice_id = 0, there is only one slice. "pulse_sequence": scf.SEQUENCE_7P, diff --git a/normalscan_ppo_test.py b/normalscan_ppo_test.py index 71f5b21..6d5fd02 100644 --- a/normalscan_ppo_test.py +++ b/normalscan_ppo_test.py @@ -47,7 +47,7 @@ def __init__(self, **kwargs): if 'freq' in kwargs.keys(): freq = kwargs['freq'] - self.printing('Frequency set to {}'.format(freq)) + print('Frequency set to {}'.format(freq)) # TODO: Log self.add_slice({ # slice_id = 0, there is only one slice. "pulse_sequence": scf.SEQUENCE_7P, @@ -64,6 +64,6 @@ def __init__(self, **kwargs): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs - "pulse_phase_offset": phase_encode + "pulse_phase_offset": phase_encode, }) diff --git a/politescan.py b/politescan.py index be22da4..80f95ec 100644 --- a/politescan.py +++ b/politescan.py @@ -38,4 +38,5 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "rxonly": True, }) diff --git a/politescan2.py b/politescan2.py index f081131..2d6f640 100644 --- a/politescan2.py +++ b/politescan2.py @@ -49,6 +49,7 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "rxonly": True, }) self.add_slice({ # slice_id = 1, receive only @@ -66,4 +67,5 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "rxonly": True, }, interfacing_dict={0: 'CONCURRENT'}) diff --git a/power_meter_mode.py b/power_meter_mode.py index d685f3b..769179f 100644 --- a/power_meter_mode.py +++ b/power_meter_mode.py @@ -32,7 +32,7 @@ def __init__(self, **kwargs): if 'freq' in kwargs.keys(): freq = kwargs['freq'] - self.printing('Frequency set to {}'.format(freq)) + print('Frequency set to {}'.format(freq)) # TODO: Log self.add_slice({ # slice_id = 0, there is only one slice. "pulse_sequence": [0], diff --git a/pulse_interfacing_test.py b/pulse_interfacing_test.py index d760473..63fd466 100644 --- a/pulse_interfacing_test.py +++ b/pulse_interfacing_test.py @@ -35,7 +35,7 @@ def __init__(self): "beam_angle": [0.0], "rx_beam_order": beams_to_use, "tx_beam_order": beams_to_use, - "freq" : 10500 # kHz + "freq" : 10500, # kHz } slice_1 = copy.deepcopy(slice_0) diff --git a/pulse_phase_offset_decoding_test.py b/pulse_phase_offset_decoding_test.py index c12c43f..c011642 100644 --- a/pulse_phase_offset_decoding_test.py +++ b/pulse_phase_offset_decoding_test.py @@ -39,5 +39,5 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs - "pulse_phase_offset": phase_encode + "pulse_phase_offset": phase_encode, }) diff --git a/tauscan.py b/tauscan.py index e99fafd..2eac568 100644 --- a/tauscan.py +++ b/tauscan.py @@ -50,7 +50,7 @@ def __init__(self): "acf" : True, "xcf" : True, "acfint" : True, - "comment" : Tauscan.__doc__ + "comment" : Tauscan.__doc__, } self.add_slice(slice_1) diff --git a/testing_archive/test_beam_order_too_long.py b/testing_archive/deprecated_tests/test_beam_order_too_long.py similarity index 85% rename from testing_archive/test_beam_order_too_long.py rename to testing_archive/deprecated_tests/test_beam_order_too_long.py index 7c44018..41d3763 100644 --- a/testing_archive/test_beam_order_too_long.py +++ b/testing_archive/deprecated_tests/test_beam_order_too_long.py @@ -11,6 +11,8 @@ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -44,5 +46,10 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "pass" diff --git a/testing_archive/test_clrfrqrng_not_list.py b/testing_archive/deprecated_tests/test_clrfrqrng_not_list.py similarity index 83% rename from testing_archive/test_clrfrqrng_not_list.py rename to testing_archive/deprecated_tests/test_clrfrqrng_not_list.py index 2144131..5f1ca0b 100644 --- a/testing_archive/test_clrfrqrng_not_list.py +++ b/testing_archive/deprecated_tests/test_clrfrqrng_not_list.py @@ -9,6 +9,8 @@ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from experiment_prototype.experiment_exception import ExperimentException class TestExperiment(ExperimentPrototype): @@ -42,5 +44,10 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ExperimentException, "pass" diff --git a/testing_archive/test_first_range_not_float.py b/testing_archive/deprecated_tests/test_first_range_not_float.py similarity index 85% rename from testing_archive/test_first_range_not_float.py rename to testing_archive/deprecated_tests/test_first_range_not_float.py index a4536d3..4d264ac 100644 --- a/testing_archive/test_first_range_not_float.py +++ b/testing_archive/deprecated_tests/test_first_range_not_float.py @@ -9,6 +9,8 @@ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -42,5 +44,10 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "pass" diff --git a/testing_archive/test_scanbound_bad_len.py b/testing_archive/deprecated_tests/test_scanbound_bad_len.py similarity index 83% rename from testing_archive/test_scanbound_bad_len.py rename to testing_archive/deprecated_tests/test_scanbound_bad_len.py index 4acc702..ab6ab8d 100644 --- a/testing_archive/test_scanbound_bad_len.py +++ b/testing_archive/deprecated_tests/test_scanbound_bad_len.py @@ -11,6 +11,8 @@ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -45,5 +47,10 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "Slice 0 must have scanbound of same length as the beam order" diff --git a/testing_archive/deprecated_tests/test_scheme_9.py b/testing_archive/deprecated_tests/test_scheme_9.py index f65a163..df6ebad 100644 --- a/testing_archive/deprecated_tests/test_scheme_9.py +++ b/testing_archive/deprecated_tests/test_scheme_9.py @@ -6,7 +6,7 @@ sys.path.append(os.environ['BOREALISPATH']) # write an experiment that creates a new control program. from experiment_prototype.experiment_prototype import ExperimentPrototype -from experiment_prototype.decimation_scheme.decimation_scheme import DecimationStage, DecimationScheme +from experiment_prototype.experiment_utils.decimation_scheme import DecimationStage, DecimationScheme from borealis_experiments.test_decimation_schemes import * class TestScheme9(ExperimentPrototype): diff --git a/testing_archive/deprecated_tests/test_scheme_9_acfs.py b/testing_archive/deprecated_tests/test_scheme_9_acfs.py index 8a59c8c..73e9af4 100644 --- a/testing_archive/deprecated_tests/test_scheme_9_acfs.py +++ b/testing_archive/deprecated_tests/test_scheme_9_acfs.py @@ -6,7 +6,7 @@ sys.path.append(os.environ['BOREALISPATH']) # write an experiment that creates a new control program. from experiment_prototype.experiment_prototype import ExperimentPrototype -from experiment_prototype.decimation_scheme.decimation_scheme import DecimationStage, DecimationScheme +from experiment_prototype.experiment_utils.decimation_scheme import DecimationStage, DecimationScheme from borealis_experiments.test_decimation_schemes import * class TestScheme9ACFs(ExperimentPrototype): diff --git a/testing_archive/test_too_many_slices.py b/testing_archive/deprecated_tests/test_too_many_slices.py similarity index 92% rename from testing_archive/test_too_many_slices.py rename to testing_archive/deprecated_tests/test_too_many_slices.py index 17f7ef6..7258f4c 100644 --- a/testing_archive/test_too_many_slices.py +++ b/testing_archive/deprecated_tests/test_too_many_slices.py @@ -12,8 +12,10 @@ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype -from experiment_prototype.decimation_scheme.decimation_scheme import \ +from experiment_prototype.experiment_utils.decimation_scheme import \ DecimationScheme, DecimationStage, create_firwin_filter_by_attenuation +from experiment_prototype.experiment_exception import ExperimentException + class TestExperiment(ExperimentPrototype): @@ -40,9 +42,7 @@ def __init__(self): # changed from 10e3/3->10e3 decimation_scheme = (DecimationScheme(rates[0], rates[-1]/dm_rates[-1], stages=all_stages)) - super(TestExperiment, self).__init__( - cpid, output_rx_rate=decimation_scheme.output_sample_rate, - decimation_scheme=decimation_scheme) + super(TestExperiment, self).__init__(cpid, output_rx_rate=decimation_scheme.output_sample_rate) if scf.IS_FORWARD_RADAR: beams_to_use = scf.STD_16_FORWARD_BEAM_ORDER @@ -69,6 +69,7 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": decimation_scheme, } # The check for too many slices is like so: # effective_length = 2^x => the next power of two for how many taps there are in a stage @@ -102,3 +103,7 @@ def __init__(self): self.add_slice(copy.deepcopy(slice_1),interfacing_dict={0: 'SCAN'}) self.add_slice(copy.deepcopy(slice_1),interfacing_dict={0: 'SCAN'}) self.add_slice(copy.deepcopy(slice_1),interfacing_dict={0: 'SCAN'}) + + @classmethod + def error_message(cls): + return ExperimentException, "pass" diff --git a/testing_archive/deprecated_tests/test_txfreq_not_num.py b/testing_archive/deprecated_tests/test_txfreq_not_num.py index 906e052..f2f725f 100644 --- a/testing_archive/deprecated_tests/test_txfreq_not_num.py +++ b/testing_archive/deprecated_tests/test_txfreq_not_num.py @@ -8,7 +8,7 @@ frequencies .* for the radar license and be within range given center frequencies \(.* kHz\), sampling rates \(.* kHz\), and transition band \(.* kHz\) -NOTE: This test is covered by test_rxfreq_not_num.py since rxfreq and txfreq were combined to freq +NOTE: This test is covered by test_freq_not_num.py since rxfreq and txfreq were combined to freq """ import borealis_experiments.superdarn_common_fields as scf diff --git a/testing_archive/deprecated_tests/test_txfreq_too_high.py b/testing_archive/deprecated_tests/test_txfreq_too_high.py index 0f0c8af..ff12cbe 100644 --- a/testing_archive/deprecated_tests/test_txfreq_too_high.py +++ b/testing_archive/deprecated_tests/test_txfreq_too_high.py @@ -8,7 +8,7 @@ frequencies .* for the radar license and be within range given center frequencies \(.* kHz\), sampling rates \(.* kHz\), and transition band \(.* kHz\) -NOTE: This test is covered by test_rxfreq_not_num.py since rxfreq and txfreq were combined to freq +NOTE: This test is covered by test_freq_not_num.py since rxfreq and txfreq were combined to freq """ import borealis_experiments.superdarn_common_fields as scf diff --git a/testing_archive/deprecated_tests/test_txfreq_too_low.py b/testing_archive/deprecated_tests/test_txfreq_too_low.py index d82c013..f6d59fb 100644 --- a/testing_archive/deprecated_tests/test_txfreq_too_low.py +++ b/testing_archive/deprecated_tests/test_txfreq_too_low.py @@ -8,7 +8,7 @@ frequencies .* for the radar license and be within range given center frequencies \(.* kHz\), sampling rates \(.* kHz\), and transition band \(.* kHz\) -NOTE: This test is covered by test_rxfreq_not_num.py since rxfreq and txfreq were combined to freq +NOTE: This test is covered by test_freq_not_num.py since rxfreq and txfreq were combined to freq """ import borealis_experiments.superdarn_common_fields as scf diff --git a/testing_archive/test_wavetype_not_defined.py b/testing_archive/deprecated_tests/test_wavetype_not_defined.py similarity index 100% rename from testing_archive/test_wavetype_not_defined.py rename to testing_archive/deprecated_tests/test_wavetype_not_defined.py diff --git a/testing_archive/test_avg_method_dne.py b/testing_archive/test_avg_method_dne.py index b5c4cee..40f9b6c 100644 --- a/testing_archive/test_avg_method_dne.py +++ b/testing_archive/test_avg_method_dne.py @@ -3,12 +3,12 @@ """ Experiment fault: Setting averaging_method to an invalid method -Expected exception: - Averaging method .* not valid method. Possible methods are .* """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -43,5 +43,13 @@ def __init__(self): "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs "averaging_method": 'not_a_method', ### This is not a valid method + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, \ + "averaging_method\n" \ + " unexpected value; permitted: 'mean', 'median' " \ + "\(type=value_error.const; given=not_a_method; permitted=\('mean', 'median'\)\)" diff --git a/testing_archive/test_bad_interface.py b/testing_archive/test_bad_interface.py index 16b0b70..bfcd9b8 100644 --- a/testing_archive/test_bad_interface.py +++ b/testing_archive/test_bad_interface.py @@ -3,14 +3,15 @@ """ Experiment fault: Interfacing two slices with an invalid interface type -Expected exception: - Interface value with slice .* not valid. Types available are """ import copy import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from experiment_prototype.experiment_exception import ExperimentException +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -44,6 +45,7 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) slice_2 = copy.deepcopy(slice_1) @@ -52,3 +54,7 @@ def __init__(self): ### Interface type is not in the interface_types list self.add_slice(slice_2, interfacing_dict={0:'THISWILLBREAK'}) + @classmethod + def error_message(cls): + return ExperimentException,\ + "Interface value with slice 0: THISWILLBREAK not valid. Types available are: \('SCAN', 'AVEPERIOD', 'SEQUENCE', 'CONCURRENT'\)" diff --git a/testing_archive/test_bad_interfacing.py b/testing_archive/test_bad_interfacing.py index 935c1e9..4b28b46 100644 --- a/testing_archive/test_bad_interfacing.py +++ b/testing_archive/test_bad_interfacing.py @@ -3,15 +3,14 @@ """ Experiment fault: Invalid interfacing between three different slices -Expected exception: - The interfacing values of new slice cannot be reconciled. Interfacing with slice .* and with - slice .* does not make sense with existing interface between slices of .* """ import copy import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from experiment_prototype.experiment_exception import ExperimentException class TestExperiment(ExperimentPrototype): @@ -45,6 +44,7 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) ### Interfacing between slices is not internally consistent. Here we add slice_2 and slice_3, @@ -55,3 +55,8 @@ def __init__(self): self.add_slice(slice_2, interfacing_dict={0:'CONCURRENT'}) self.add_slice(slice_3, interfacing_dict={0:'CONCURRENT', 1:'SCAN'}) + @classmethod + def error_message(cls): + return ExperimentException,\ + "The interfacing values of new slice cannot be reconciled. Interfacing with slice 0: CONCURRENT and " \ + "with slice 1: SCAN does not make sense with existing interface between slices of None: CONCURRENT" diff --git a/testing_archive/test_bad_slice.py b/testing_archive/test_bad_slice.py index 9c4e004..f8f9745 100644 --- a/testing_archive/test_bad_slice.py +++ b/testing_archive/test_bad_slice.py @@ -3,12 +3,9 @@ """ Experiment fault: Adding a slice that isn't a dictionary of parameters -Expected exception: - Attempt to add a slice failed - .* is not a dictionary of slice parameters """ - -import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_exception import ExperimentException class TestExperiment(ExperimentPrototype): @@ -17,15 +14,10 @@ def __init__(self): cpid = 1 super(TestExperiment, self).__init__(cpid) - if scf.IS_FORWARD_RADAR: - beams_to_use = scf.STD_16_FORWARD_BEAM_ORDER - else: - beams_to_use = scf.STD_16_REVERSE_BEAM_ORDER - - if scf.options.site_id in ["cly", "rkn", "inv"]: - num_ranges = scf.POLARDARN_NUM_RANGES - if scf.options.site_id in ["sas", "pgr"]: - num_ranges = scf.STD_NUM_RANGES - - ### exp_slice is not a dictionary of slice parameters + # exp_slice is not a dictionary of slice parameters self.add_slice('garbage') + + @classmethod + def error_message(cls): + return ExperimentException,\ + "Attempt to add a slice failed - garbage is not a dictionary of slice parameters" diff --git a/testing_archive/test_bad_slice_id.py b/testing_archive/test_bad_slice_id.py index e927998..1d26412 100644 --- a/testing_archive/test_bad_slice_id.py +++ b/testing_archive/test_bad_slice_id.py @@ -3,14 +3,14 @@ """ Experiment fault: Interfacing between two slices with an unknown slice ID -Expected exception: - Cannot add slice: the interfacing_dict set interfacing to an unknown slice .* not in slice ids """ import copy import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from experiment_prototype.experiment_exception import ExperimentException class TestExperiment(ExperimentPrototype): @@ -44,9 +44,15 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) slice_2 = copy.deepcopy(slice_1) slice_2['freq'] = scf.COMMON_MODE_FREQ_2 ### Interfacing dict has interfacing set to an unknown sibling slice ID self.add_slice(slice_2, interfacing_dict={99:'SCAN'}) + + @classmethod + def error_message(cls): + return ExperimentException,\ + "Cannot add slice: the interfacing_dict set interfacing to an unknown slice 99 not in slice ids \[0\]" diff --git a/testing_archive/test_beam_angle_dne.py b/testing_archive/test_beam_angle_dne.py index 6c1b5f1..9d893b4 100644 --- a/testing_archive/test_beam_angle_dne.py +++ b/testing_archive/test_beam_angle_dne.py @@ -3,12 +3,11 @@ """ Experiment fault: No beam_angle set in slice -Expected exception: - Slice must specify beam_angle that must be a list of numbers \(ints or floats\) which are angles of degrees off boresight \(positive E of N\) """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme class TestExperiment(ExperimentPrototype): @@ -42,5 +41,10 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return TypeError, "__init__\(\) missing 1 required positional argument: 'beam_angle'" diff --git a/testing_archive/test_beam_angle_dups.py b/testing_archive/test_beam_angle_dups.py index 073f98a..f9cee03 100644 --- a/testing_archive/test_beam_angle_dups.py +++ b/testing_archive/test_beam_angle_dups.py @@ -3,12 +3,12 @@ """ Experiment fault: beam_angle contains duplicates -Expected exception: - Slice .* beam angles has duplicate directions """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -43,5 +43,11 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "beam_angle\n" \ + " the list has duplicated items \(type=value_error.list.unique_items\)" diff --git a/testing_archive/test_beam_angle_not_increasing.py b/testing_archive/test_beam_angle_not_increasing.py index 2cdbf73..d214038 100644 --- a/testing_archive/test_beam_angle_not_increasing.py +++ b/testing_archive/test_beam_angle_not_increasing.py @@ -3,12 +3,12 @@ """ Experiment fault: beam_angle not increasing -Expected exception: - Slice .* beam_angle not increasing clockwise \(E of N is positive\) """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -26,7 +26,8 @@ def __init__(self): num_ranges = scf.POLARDARN_NUM_RANGES if scf.options.site_id in ["sas", "pgr"]: num_ranges = scf.STD_NUM_RANGES - reversedlist = [-26.25, -22.75, -19.25, -15.75, -12.25, -8.75,-5.25, -1.75, 1.75, 5.25, 8.75, 12.25, 15.75, 19.25, 22.75, 26.25] + reversedlist = [-26.25, -22.75, -19.25, -15.75, -12.25, -8.75, -5.25, -1.75, + 1.75, 5.25, 8.75, 12.25, 15.75, 19.25, 22.75, 26.25] reversedlist.reverse() slice_1 = { # slice_id = 0, there is only one slice. "pulse_sequence": scf.SEQUENCE_7P, @@ -43,5 +44,12 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "beam_angle\n" \ + " not increasing: \[26.25, 22.75, 19.25, 15.75, 12.25, 8.75, 5.25, 1.75, -1.75, " \ + "-5.25, -8.75, -12.25, -15.75, -19.25, -22.75, -26.25\] \(type=value_error\)" \ No newline at end of file diff --git a/testing_archive/test_beam_angle_not_list.py b/testing_archive/test_beam_angle_not_list.py index c5bc0c9..cf203b8 100644 --- a/testing_archive/test_beam_angle_not_list.py +++ b/testing_archive/test_beam_angle_not_list.py @@ -3,13 +3,12 @@ """ Experiment fault: beam_angle not a list -Expected exception: - Slice must specify beam_angle that must be a list of numbers \(ints or floats\) which are angles - of degrees off boresight \(positive E of N\) """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -43,5 +42,11 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "beam_angle\n" \ + " value is not a valid list \(type=type_error.list\)" diff --git a/testing_archive/test_beam_angle_not_num.py b/testing_archive/test_beam_angle_not_num.py index 7d43d72..ed81170 100644 --- a/testing_archive/test_beam_angle_not_num.py +++ b/testing_archive/test_beam_angle_not_num.py @@ -3,13 +3,12 @@ """ Experiment fault: beam_angle not all numbers -Expected exception: - .*Slice must specify beam_angle that must be a list of numbers \(ints or floats\) which are - angles of degrees off boresight \(positive E of N\) """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -43,5 +42,13 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "beam_angle -> 2\n" \ + " value is not a valid float \(type=type_error.float\)\n" \ + "beam_angle -> 2\n" \ + " value is not a valid integer \(type=type_error.integer\)" diff --git a/testing_archive/test_beam_order_bad_index.py b/testing_archive/test_beam_order_bad_index.py index 28f01b2..ab38722 100644 --- a/testing_archive/test_beam_order_bad_index.py +++ b/testing_archive/test_beam_order_bad_index.py @@ -3,12 +3,12 @@ """ Experiment fault: rx_beam_order invalid index -Expected exception: - Beam number .* could not index in beam_angle list of length .*. Slice: .* """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -36,11 +36,18 @@ def __init__(self): "intt": 3500, # duration of an integration, in ms "beam_angle": scf.STD_16_BEAM_ANGLE, "rx_beam_order": [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,90], # At least one is larger than the len(beam_angle) - "tx_beam_order": [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15], # At least one is larger than the len(beam_angle) + "tx_beam_order": [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15], "scanbound": [i * 3.5 for i in range(len(beams_to_use))], #1 min scan "freq" : scf.COMMON_MODE_FREQ_1, #kHz "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "rx_beam_order -> 15\n" \ + " Beam number 90 could not index in beam_angle list of length 16. Slice: 0 " \ + "\(type=value_error\)" diff --git a/testing_archive/test_beam_order_dne.py b/testing_archive/test_beam_order_dne.py index a57f94c..0fc10a1 100644 --- a/testing_archive/test_beam_order_dne.py +++ b/testing_archive/test_beam_order_dne.py @@ -3,13 +3,11 @@ """ Experiment fault: rx_beam_order not specified in slice -Expected exception: - Slice must specify rx_beam_order that must be a list of ints or lists \(of ints\) corresponding - to the order of the angles in the beam_angle list """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme class TestExperiment(ExperimentPrototype): @@ -43,5 +41,10 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return TypeError, "__init__\(\) missing 1 required positional argument: 'rx_beam_order'" diff --git a/testing_archive/test_beam_order_lists_bad_index.py b/testing_archive/test_beam_order_lists_bad_index.py index 34ef1db..a11816e 100644 --- a/testing_archive/test_beam_order_lists_bad_index.py +++ b/testing_archive/test_beam_order_lists_bad_index.py @@ -3,12 +3,12 @@ """ Experiment fault: rx_beam_order index invalid -Expected exception: - Beam number .* could not index in beam_angle list of length .*. Slice: .* """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -43,5 +43,12 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "rx_beam_order -> 0\n" \ + " Beam number 55 could not index in beam_angle list of length 16. Slice: 0 " \ + "\(type=value_error\)" diff --git a/testing_archive/test_beam_order_lists_not_ints.py b/testing_archive/test_beam_order_lists_not_ints.py index 5abea67..d629ee1 100644 --- a/testing_archive/test_beam_order_lists_not_ints.py +++ b/testing_archive/test_beam_order_lists_not_ints.py @@ -3,13 +3,12 @@ """ Experiment fault: rx_beam_order list values not integers -Expected exception: - Slice must specify rx_beam_order that must be a list of ints or lists \(of ints\) corresponding - to the order of the angles in the beam_angle list """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -43,5 +42,25 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "rx_beam_order -> 0 -> 0\n" \ + " value is not a valid integer \(type=type_error.integer\)\n" \ + "rx_beam_order -> 0 -> 1\n" \ + " value is not a valid integer \(type=type_error.integer\)\n" \ + "rx_beam_order -> 0 -> 2\n" \ + " value is not a valid integer \(type=type_error.integer\)\n" \ + "rx_beam_order -> 0\n" \ + " value is not a valid integer \(type=type_error.integer\)\n" \ + "rx_beam_order -> 1 -> 0\n" \ + " value is not a valid integer \(type=type_error.integer\)\n" \ + "rx_beam_order -> 1\n" \ + " value is not a valid integer \(type=type_error.integer\)\n" \ + "rx_beam_order -> 2 -> 0\n" \ + " value is not a valid integer \(type=type_error.integer\)\n" \ + "rx_beam_order -> 2\n" \ + " value is not a valid integer \(type=type_error.integer\)" diff --git a/testing_archive/test_beam_order_not_ints_or_lists.py b/testing_archive/test_beam_order_not_ints_or_lists.py index 21a5755..c7477ed 100644 --- a/testing_archive/test_beam_order_not_ints_or_lists.py +++ b/testing_archive/test_beam_order_not_ints_or_lists.py @@ -3,13 +3,12 @@ """ Experiment fault: rx_beam_order list values not lists or integers -Expected exception: - Slice must specify rx_beam_order that must be a list of ints or lists \(of ints\) corresponding - to the order of the angles in the beam_angle list """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -43,5 +42,25 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "rx_beam_order -> 0\n" \ + " value is not a valid list \(type=type_error.list\)\n" \ + "rx_beam_order -> 0\n" \ + " value is not a valid integer \(type=type_error.integer\)\n" \ + "rx_beam_order -> 1\n" \ + " value is not a valid list \(type=type_error.list\)\n" \ + "rx_beam_order -> 1\n" \ + " value is not a valid integer \(type=type_error.integer\)\n" \ + "rx_beam_order -> 2\n" \ + " value is not a valid list \(type=type_error.list\)\n" \ + "rx_beam_order -> 2\n" \ + " value is not a valid integer \(type=type_error.integer\)\n" \ + "rx_beam_order -> 3\n" \ + " value is not a valid list \(type=type_error.list\)\n" \ + "rx_beam_order -> 3\n" \ + " value is not a valid integer \(type=type_error.integer\)" diff --git a/testing_archive/test_beam_order_not_list.py b/testing_archive/test_beam_order_not_list.py index c2a86bd..9329c73 100644 --- a/testing_archive/test_beam_order_not_list.py +++ b/testing_archive/test_beam_order_not_list.py @@ -3,13 +3,12 @@ """ Experiment fault: rx_beam_order not a list -Expected exception: - Slice must specify rx_beam_order that must be a list of ints or lists \(of ints\) corresponding - to the order of the angles in the beam_angle list """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -43,5 +42,11 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "rx_beam_order\n" \ + " value is not a valid list \(type=type_error.list\)" diff --git a/testing_archive/test_clrfrqrng_not_2.py b/testing_archive/test_clrfrqrng_not_2.py index 16e8863..b28d006 100644 --- a/testing_archive/test_clrfrqrng_not_2.py +++ b/testing_archive/test_clrfrqrng_not_2.py @@ -3,12 +3,12 @@ """ Experiment fault: clrfrqrange not a range of length 2 -Expected exception: - clrfrqrange must be an integer list of length = 2 """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -42,5 +42,12 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "clrfrqrange\n" \ + " ensure this value has at least 2 items " \ + "\(type=value_error.list.min_items; limit_value=2\)" diff --git a/testing_archive/test_clrfrqrng_not_inc.py b/testing_archive/test_clrfrqrng_not_inc.py index f017773..89004e3 100644 --- a/testing_archive/test_clrfrqrng_not_inc.py +++ b/testing_archive/test_clrfrqrng_not_inc.py @@ -3,14 +3,12 @@ """ Experiment fault: clrfrqrange not increasing -Expected exception: - clrfrqrange must be between min and max tx frequencies .* and rx frequencies .* according to - license and/or center frequencies / sampling rates / transition bands, and must have lower - frequency first """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -44,5 +42,14 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "clrfrqrange\n" \ + " Slice 0 clrfrqrange must be between min and max tx frequencies " \ + "\(10250000.01117587, 13750000.01117587\) and rx frequencies \(10250000.01117587, " \ + "13750000.01117587\) according to license and/or center frequencies / sampling rates " \ + "/ transition bands, and must have lower frequency first. \(type=value_error\)" diff --git a/testing_archive/test_clrfrqrng_not_ints.py b/testing_archive/test_clrfrqrng_not_ints.py index 0c092f9..df534ce 100644 --- a/testing_archive/test_clrfrqrng_not_ints.py +++ b/testing_archive/test_clrfrqrng_not_ints.py @@ -3,12 +3,12 @@ """ Experiment fault: clrfrqrange list of non-integers -Expected exception: - clrfrqrange must be an integer list of length = 2 """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -42,5 +42,13 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "clrfrqrange -> 0\n" \ + " value is not a valid integer \(type=type_error.integer\)\n" \ + "clrfrqrange -> 1\n" \ + " value is not a valid integer \(type=type_error.integer\)" diff --git a/testing_archive/test_clrfrqrng_too_high.py b/testing_archive/test_clrfrqrng_too_high.py index bdc3dc6..261db82 100644 --- a/testing_archive/test_clrfrqrng_too_high.py +++ b/testing_archive/test_clrfrqrng_too_high.py @@ -3,14 +3,12 @@ """ Experiment fault: clrfrqrange too high -Expected exception: - clrfrqrange must be between min and max tx frequencies .* and rx frequencies .* according to - license and/or center frequencies / sampling rates / transition bands, and must have lower - frequency first """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -44,5 +42,15 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "clrfrqrange -> 0\n" \ + " ensure this value is less than or equal to 20000.0 " \ + "\(type=value_error.number.not_le; limit_value=20000.0\)\n" \ + "clrfrqrange -> 1\n" \ + " ensure this value is less than or equal to 20000.0 " \ + "\(type=value_error.number.not_le; limit_value=20000.0\)" diff --git a/testing_archive/test_clrfrqrng_too_low.py b/testing_archive/test_clrfrqrng_too_low.py index 91f0ca9..44590c5 100644 --- a/testing_archive/test_clrfrqrng_too_low.py +++ b/testing_archive/test_clrfrqrng_too_low.py @@ -3,14 +3,12 @@ """ Experiment fault: clrfrqrange too low -Expected exception: - clrfrqrange must be between min and max tx frequencies .* and rx frequencies .* according to - license and/or center frequencies / sampling rates / transition bands, and must have lower - frequency first """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -44,5 +42,15 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "clrfrqrange -> 0\n" \ + " ensure this value is greater than or equal to 8000.0 " \ + "\(type=value_error.number.not_ge; limit_value=8000.0\)\n" \ + "clrfrqrange -> 1\n" \ + " ensure this value is greater than or equal to 8000.0 " \ + "\(type=value_error.number.not_ge; limit_value=8000.0\)" diff --git a/testing_archive/test_cpid_int.py b/testing_archive/test_cpid_int.py index 359edae..9bac770 100644 --- a/testing_archive/test_cpid_int.py +++ b/testing_archive/test_cpid_int.py @@ -3,12 +3,12 @@ """ Experiment fault: cpid not an integer -Expected exception: - CPID must be a unique int """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from experiment_prototype.experiment_exception import ExperimentException class TestExperiment(ExperimentPrototype): @@ -42,5 +42,10 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ExperimentException, "CPID must be a unique int" diff --git a/testing_archive/test_cpid_pos.py b/testing_archive/test_cpid_pos.py index 0fdfcec..d6a0fd1 100644 --- a/testing_archive/test_cpid_pos.py +++ b/testing_archive/test_cpid_pos.py @@ -3,14 +3,12 @@ """ Experiment fault: cpid negative integer -Expected exception: - The CPID should be a positive number in the experiment. Borealis will determine if it should be - negative based on the scheduling mode. Only experiments run during discretionary time will have - negative CPIDs. """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from experiment_prototype.experiment_exception import ExperimentException class TestExperiment(ExperimentPrototype): @@ -44,5 +42,13 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ExperimentException,\ + "The CPID should be a positive number in the experiment. Borealis will determine if it should be " \ + "negative based on the scheduling mode. Only experiments run during discretionary time will have " \ + "negative CPIDs." diff --git a/testing_archive/test_cpid_unique.py b/testing_archive/test_cpid_unique.py index c642ca3..8abb445 100644 --- a/testing_archive/test_cpid_unique.py +++ b/testing_archive/test_cpid_unique.py @@ -3,12 +3,12 @@ """ Experiment fault: cpid non unique integer -Expected exception: - CPID must be unique. .* is in use by another local experiment """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from experiment_prototype.experiment_exception import ExperimentException class TestExperiment(ExperimentPrototype): @@ -42,5 +42,10 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ExperimentException, "CPID must be unique. 151 is in use by another local experiment" diff --git a/testing_archive/test_del_slice_dne.py b/testing_archive/test_del_slice_dne.py index 413af0b..bc8aa5c 100644 --- a/testing_archive/test_del_slice_dne.py +++ b/testing_archive/test_del_slice_dne.py @@ -3,12 +3,12 @@ """ Experiment fault: Removing a slice that doesn't exist -Expected exception: - Cannot remove slice id .* : it does not exist in slice dictionary """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from experiment_prototype.experiment_exception import ExperimentException class TestExperiment(ExperimentPrototype): @@ -42,7 +42,11 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) self.del_slice(7) ### Non-existent slice ID should fail + @classmethod + def error_message(cls): + return ExperimentException, "Cannot remove slice id 7 : it does not exist in slice dictionary" diff --git a/testing_archive/test_dm_rate_not_int.py b/testing_archive/test_dm_rate_not_int.py index fa9ae50..af29394 100644 --- a/testing_archive/test_dm_rate_not_int.py +++ b/testing_archive/test_dm_rate_not_int.py @@ -3,14 +3,14 @@ """ Experiment fault: Non-integer decimation rate -Expected exception: - Decimation rate is not an integer """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype -from experiment_prototype.decimation_scheme.decimation_scheme import \ +from experiment_prototype.experiment_utils.decimation_scheme import \ DecimationScheme, DecimationStage, create_firwin_filter_by_attenuation +from experiment_prototype.experiment_exception import ExperimentException + class TestExperiment(ExperimentPrototype): @@ -63,5 +63,10 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": decimation_scheme, } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ExperimentException, "Decimation rate is not an integer" diff --git a/testing_archive/test_edit_slice_bad_param.py b/testing_archive/test_edit_slice_bad_param.py index 98f1297..2ef6eae 100644 --- a/testing_archive/test_edit_slice_bad_param.py +++ b/testing_archive/test_edit_slice_bad_param.py @@ -3,12 +3,12 @@ """ Experiment fault: Editing slice with invalid parameter -Expected exception: - Cannot edit slice ID .*: .* is not a valid slice parameter """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from experiment_prototype.experiment_exception import ExperimentException class TestExperiment(ExperimentPrototype): @@ -42,7 +42,11 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) self.edit_slice(0, tx_freak=scf.COMMON_MODE_FREQ_2) ### Non-existent param should fail + @classmethod + def error_message(cls): + return ExperimentException, "Cannot edit slice ID 0: tx_freak is not a valid slice parameter" diff --git a/testing_archive/test_edit_slice_dne.py b/testing_archive/test_edit_slice_dne.py index 8064724..96cd1dd 100644 --- a/testing_archive/test_edit_slice_dne.py +++ b/testing_archive/test_edit_slice_dne.py @@ -3,12 +3,12 @@ """ Experiment fault: Editing a slice that doesn't exist -Expected exception: - Trying to edit .* but it does not exist in Slice_IDs list """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from experiment_prototype.experiment_exception import ExperimentException class TestExperiment(ExperimentPrototype): @@ -42,7 +42,11 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) self.edit_slice(7, freq=scf.COMMON_MODE_FREQ_2) ### Non-existent slice ID should fail + @classmethod + def error_message(cls): + return ExperimentException, "Trying to edit 7 but it does not exist in Slice_IDs list." diff --git a/testing_archive/test_edit_slice_improperly.py b/testing_archive/test_edit_slice_improperly.py new file mode 100644 index 0000000..be4b68f --- /dev/null +++ b/testing_archive/test_edit_slice_improperly.py @@ -0,0 +1,40 @@ +#!/usr/bin/python + +""" +Experiment fault: + Editing a slice without using edit_slice +""" +import borealis_experiments.superdarn_common_fields as scf +from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme + + +class TestExperiment(ExperimentPrototype): + + def __init__(self): + cpid = 1 + super().__init__(cpid) + + beams_to_use = scf.STD_16_FORWARD_BEAM_ORDER + num_ranges = scf.STD_NUM_RANGES + + slice_1 = { # slice_id = 0, there is only one slice. + "pulse_sequence": scf.SEQUENCE_7P, + "tau_spacing": scf.TAU_SPACING_7P, + "pulse_len": scf.PULSE_LEN_45KM, + "num_ranges": num_ranges, + "first_range": scf.STD_FIRST_RANGE, + "intt": 3500, # duration of an integration, in ms + "beam_angle": scf.STD_16_BEAM_ANGLE, + "rx_beam_order": beams_to_use, + "tx_beam_order": beams_to_use, + "freq": scf.COMMON_MODE_FREQ_1, #kHz + "decimation_scheme": create_default_scheme(), + } + self.add_slice(slice_1) + setattr(self.slice_dict[0], 'gibberish', 'asdlkfj') + # self.slice_dict[0].check_slice() + + @classmethod + def error_message(cls): + return TypeError, "__init__\(\) got an unexpected keyword argument 'gibberish'" diff --git a/testing_archive/test_finalstage_bad_outputrate.py b/testing_archive/test_finalstage_bad_outputrate.py index 57583fb..136e1eb 100644 --- a/testing_archive/test_finalstage_bad_outputrate.py +++ b/testing_archive/test_finalstage_bad_outputrate.py @@ -3,15 +3,14 @@ """ Experiment fault: Building decimation stage with bad output rate -Expected exception: - Last decimation stage .* does not have output rate .* equal to - requested output data rate .* """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype -from experiment_prototype.decimation_scheme.decimation_scheme import \ +from experiment_prototype.experiment_utils.decimation_scheme import \ DecimationScheme, DecimationStage, create_firwin_filter_by_attenuation +from experiment_prototype.experiment_exception import ExperimentException + class TestExperiment(ExperimentPrototype): @@ -66,5 +65,12 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": decimation_scheme, } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ExperimentException, \ + "Last decimation stage 3 does not have output rate 3333.3333333333335 equal to requested output data " \ + "rate 20000.0" diff --git a/testing_archive/test_first_range_dne.py b/testing_archive/test_first_range_dne.py index 5619997..f5b6962 100644 --- a/testing_archive/test_first_range_dne.py +++ b/testing_archive/test_first_range_dne.py @@ -3,12 +3,11 @@ """ Experiment fault: first_range not specified in slice -Expected exception: - Slice must specify first_range in km that must be a number """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme class TestExperiment(ExperimentPrototype): @@ -42,5 +41,10 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return TypeError, "__init__\(\) missing 1 required positional argument: 'first_range'" diff --git a/testing_archive/test_rxfreq_not_num.py b/testing_archive/test_freq_not_num.py similarity index 75% rename from testing_archive/test_rxfreq_not_num.py rename to testing_archive/test_freq_not_num.py index 6eaa36a..c6ba0c8 100644 --- a/testing_archive/test_rxfreq_not_num.py +++ b/testing_archive/test_freq_not_num.py @@ -3,13 +3,13 @@ """ Experiment fault: freq set to a non-number -Expected exception: - freq must be a number \(kHz\) between rx min and max frequencies .* for the radar license and be - within range given center frequency .* kHz, sampling rate .* kHz, and transition band .* kHz """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError + class TestExperiment(ExperimentPrototype): @@ -37,9 +37,16 @@ def __init__(self): "beam_angle": scf.STD_16_BEAM_ANGLE, "rx_beam_order": beams_to_use, "scanbound": [i * 3.5 for i in range(len(beams_to_use))], #1 min scan - "freq" : '12005', ### not an int or float + "freq" : 'twelve thousand', ### not an int or float "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), + "rxonly": True, } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "freq\n" \ + " value is not a valid float \(type=type_error.float\)" diff --git a/testing_archive/test_txfreq_restricted.py b/testing_archive/test_freq_restricted.py similarity index 83% rename from testing_archive/test_txfreq_restricted.py rename to testing_archive/test_freq_restricted.py index 447c974..977237b 100644 --- a/testing_archive/test_txfreq_restricted.py +++ b/testing_archive/test_freq_restricted.py @@ -3,12 +3,12 @@ """ Experiment fault: freq within restricted range -Expected exception: - freq is within a restricted frequency range .* """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -43,5 +43,10 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "freq is within a restricted frequency range \(13155, 13617\)" diff --git a/testing_archive/test_rxfreq_too_high.py b/testing_archive/test_freq_too_high.py similarity index 75% rename from testing_archive/test_rxfreq_too_high.py rename to testing_archive/test_freq_too_high.py index a561f5a..46162c5 100644 --- a/testing_archive/test_rxfreq_too_high.py +++ b/testing_archive/test_freq_too_high.py @@ -3,13 +3,13 @@ """ Experiment fault: freq above max freq -Expected exception: - freq must be a number \(kHz\) between rx min and max frequencies .* for the radar license and be - within range given center frequency .* kHz, sampling rate .* kHz, and transition band .* kHz """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError + class TestExperiment(ExperimentPrototype): @@ -41,5 +41,13 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), + "rxonly": True, } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "freq\n" \ + " ensure this value is less than or equal to 20000.0 " \ + "\(type=value_error.number.not_le; limit_value=20000.0\)" diff --git a/testing_archive/test_rxfreq_too_low.py b/testing_archive/test_freq_too_low.py similarity index 75% rename from testing_archive/test_rxfreq_too_low.py rename to testing_archive/test_freq_too_low.py index c9fa3a5..52dad20 100644 --- a/testing_archive/test_rxfreq_too_low.py +++ b/testing_archive/test_freq_too_low.py @@ -3,13 +3,13 @@ """ Experiment fault: freq below min freq -Expected exception: - freq must be a number \(kHz\) between rx min and max frequencies .* for the radar license and be - within range given center frequency .* kHz, sampling rate .* kHz, and transition band .* kHz """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError + class TestExperiment(ExperimentPrototype): @@ -41,5 +41,13 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), + "rxonly": True, } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "freq\n" \ + " ensure this value is less than or equal to 20000.0 " \ + "\(type=value_error.number.not_le; limit_value=20000.0\)" diff --git a/testing_archive/test_int_antenna_dne.py b/testing_archive/test_int_antenna_dne.py index 1e82b8a..9b6c4ed 100644 --- a/testing_archive/test_int_antenna_dne.py +++ b/testing_archive/test_int_antenna_dne.py @@ -3,12 +3,12 @@ """ Experiment fault: rx_int_antennas specify an antenna that doesn't exist -Expected exception: - Slice .* specifies interferometer array antenna numbers over config max .* """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -42,6 +42,12 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs - "rx_int_antennas": [0,1,2,18] ### int antenna 18 DNE, should fail + "rx_int_antennas": [0,1,2,18], ### int antenna 18 DNE, should fail + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "rx_int_antennas -> 3\n" \ + " ensure this value is less than 4 \(type=value_error.number.not_lt; limit_value=4\)" diff --git a/testing_archive/test_int_antenna_dups.py b/testing_archive/test_int_antenna_dups.py index ab1cfe9..099af8b 100644 --- a/testing_archive/test_int_antenna_dups.py +++ b/testing_archive/test_int_antenna_dups.py @@ -3,12 +3,12 @@ """ Experiment fault: rx_int_antennas contain duplicate antenna numbers -Expected exception: - Slice .* RX main antennas has duplicate antennas """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -42,6 +42,14 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs - "rx_int_antennas": [0,0,1,2,3] ### 0 duplicated, should fail + "rx_int_antennas": [0,0,1,2,3], ### 0 duplicated, should fail + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "rx_int_antennas\n" \ + " ensure this value has at most 4 items " \ + "\(type=value_error.list.max_items; limit_value=4\)" + diff --git a/testing_archive/test_intn_not_int.py b/testing_archive/test_intn_not_int.py index d728d62..fb32b09 100644 --- a/testing_archive/test_intn_not_int.py +++ b/testing_archive/test_intn_not_int.py @@ -3,12 +3,12 @@ """ Experiment fault: intn not an integer -Expected exception: - intn must be an integer """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -42,5 +42,11 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "intn\n" \ + " value is not a valid integer \(type=type_error.integer\)" diff --git a/testing_archive/test_intt_longer_than_scanbound.py b/testing_archive/test_intt_longer_than_scanbound.py index 5426fc0..35bbc1b 100644 --- a/testing_archive/test_intt_longer_than_scanbound.py +++ b/testing_archive/test_intt_longer_than_scanbound.py @@ -3,12 +3,12 @@ """ Experiment fault: intt longer than single scanbound time -Expected exception: - Slice .* intt .*ms longer than scanbound time .*s """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -42,5 +42,11 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "scanbound\n" \ + " Slice 0 intt 3600.0ms longer than scanbound time 3.5s \(type=value_error\)" diff --git a/testing_archive/test_intt_longer_than_scanbounds.py b/testing_archive/test_intt_longer_than_scanbounds.py index a30e68c..ab1f620 100644 --- a/testing_archive/test_intt_longer_than_scanbounds.py +++ b/testing_archive/test_intt_longer_than_scanbounds.py @@ -3,12 +3,12 @@ """ Experiment fault: intt longer than one of multiple scanbound times -Expected exception: - Slice .* intt .*ms longer than one of the scanbound times """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -42,5 +42,11 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "scanbound\n" \ + " Slice 0 intt 3600.0ms longer than one of the scanbound times \(type=value_error\)" diff --git a/testing_archive/test_intt_not_num.py b/testing_archive/test_intt_not_num.py index 6c5c5a3..4ee83ab 100644 --- a/testing_archive/test_intt_not_num.py +++ b/testing_archive/test_intt_not_num.py @@ -3,12 +3,12 @@ """ Experiment fault: intt not a number -Expected exception: - intt must be a number """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -42,5 +42,11 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "intt\n" \ + " value is not a valid float \(type=type_error.float\)" diff --git a/testing_archive/test_intt_too_low.py b/testing_archive/test_intt_too_low.py index 9442b75..fba7cda 100644 --- a/testing_archive/test_intt_too_low.py +++ b/testing_archive/test_intt_too_low.py @@ -3,12 +3,12 @@ """ Experiment fault: intt too low for pulse sequence length -Expected exception: - Slice .* : pulse sequence is too long for integration time given """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -38,10 +38,16 @@ def __init__(self): "beam_angle": scf.STD_16_BEAM_ANGLE, "rx_beam_order": beams_to_use, "tx_beam_order": beams_to_use, - "scanbound": [i * 3.5 for i in range(len(beams_to_use))], #1 min scan "freq" : scf.COMMON_MODE_FREQ_1, #kHz "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "intt\n" \ + " Slice 0: pulse sequence is too long for integration time given " \ + "\(type=value_error\)" diff --git a/testing_archive/test_lag_table_bad.py b/testing_archive/test_lag_table_bad.py index f9bff7b..4d9e11f 100644 --- a/testing_archive/test_lag_table_bad.py +++ b/testing_archive/test_lag_table_bad.py @@ -3,14 +3,14 @@ """ Experiment fault: Adding a pulse that doesn't exist to lag table -Expected exception: - Lag .* not valid; One of the pulses does not exist in the sequence """ import itertools import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -39,21 +39,24 @@ def __init__(self): "beam_angle": scf.STD_16_BEAM_ANGLE, "rx_beam_order": beams_to_use, "tx_beam_order": beams_to_use, - "scanbound": [i * 3.5 for i in range(len(beams_to_use))], #1 min scan - "freq" : scf.COMMON_MODE_FREQ_1, #kHz + "scanbound": [i * 3.5 for i in range(len(beams_to_use))], # 1 min scan + "freq" : scf.COMMON_MODE_FREQ_1, # kHz "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } lag_table = list(itertools.combinations(slice_1['pulse_sequence'], 2)) - lag_table.append([slice_1['pulse_sequence'][0], slice_1[ - 'pulse_sequence'][0]]) # lag 0 - lag_table.append([99,0]) ### Should fail on this!! + lag_table.append([slice_1['pulse_sequence'][0], slice_1['pulse_sequence'][0]]) # lag 0 + lag_table.append([99, 0]) ### Should fail on this!! # sort by lag number lag_table = sorted(lag_table, key=lambda x: x[1] - x[0]) - lag_table.append([slice_1['pulse_sequence'][-1], slice_1[ - 'pulse_sequence'][-1]]) # alternate lag 0 + lag_table.append([slice_1['pulse_sequence'][-1], slice_1['pulse_sequence'][-1]]) # alternate lag 0 slice_1['lag_table'] = lag_table self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "Lag \[99, 0\] not valid; One of the pulses does not exist in the sequence. Slice: 0" diff --git a/testing_archive/test_mismatched_dm_schemes.py b/testing_archive/test_mismatched_dm_schemes.py new file mode 100644 index 0000000..08b1271 --- /dev/null +++ b/testing_archive/test_mismatched_dm_schemes.py @@ -0,0 +1,75 @@ +#!/usr/bin/python + +""" +Experiment fault: + CONCURRENT interfaced slices have different DecimationSchemes +""" +import copy + +import borealis_experiments.superdarn_common_fields as scf +from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import \ + DecimationScheme, DecimationStage, create_firwin_filter_by_attenuation, create_default_scheme +from experiment_prototype.experiment_exception import ExperimentException + + +class TestExperiment(ExperimentPrototype): + + def __init__(self): + cpid = 1 + ### dm_rate is not an integer + rates = [5.0e6, 500.0e3, 500.0e3/6, 50.0e3/3] + dm_rates = [10, 6, 5, 5] # default scheme is [10, 5, 6, 5] + transition_widths = [150.0e3, 40.0e3, 15.0e3, 1.0e3] + cutoffs = [20.0e3, 10.0e3, 10.0e3, 5.0e3] + ripple_dbs = [150.0, 80.0, 35.0, 9.0] + scaling_factors = [10.0, 100.0, 100.0, 100.0] + all_stages = [] + for stage in range(0, len(rates)): + filter_taps = list( + scaling_factors[stage] * create_firwin_filter_by_attenuation( + rates[stage], transition_widths[stage], cutoffs[stage], + ripple_dbs[stage])) + all_stages.append(DecimationStage(stage, rates[stage], + dm_rates[stage], filter_taps)) + + # changed from 10e3/3->10e3 + decimation_scheme = (DecimationScheme(rates[0], rates[-1]/dm_rates[-1], stages=all_stages)) + super(TestExperiment, self).__init__(cpid, output_rx_rate=decimation_scheme.output_sample_rate) + + if scf.IS_FORWARD_RADAR: + beams_to_use = scf.STD_16_FORWARD_BEAM_ORDER + else: + beams_to_use = scf.STD_16_REVERSE_BEAM_ORDER + + if scf.options.site_id in ["cly", "rkn", "inv"]: + num_ranges = scf.POLARDARN_NUM_RANGES + if scf.options.site_id in ["sas", "pgr"]: + num_ranges = scf.STD_NUM_RANGES + + slice_1 = { # slice_id = 0 + "pulse_sequence": scf.SEQUENCE_7P, + "tau_spacing": scf.TAU_SPACING_7P, + "pulse_len": scf.PULSE_LEN_45KM, + "num_ranges": num_ranges, + "first_range": scf.STD_FIRST_RANGE, + "intt": 3500, # duration of an integration, in ms + "beam_angle": scf.STD_16_BEAM_ANGLE, + "rx_beam_order": beams_to_use, + "tx_beam_order": beams_to_use, + "scanbound": [i * 3.5 for i in range(len(beams_to_use))], #1 min scan + "freq" : scf.COMMON_MODE_FREQ_1, #kHz + "acf": True, + "xcf": True, # cross-correlation processing + "acfint": True, # interferometer acfs + "decimation_scheme": decimation_scheme, + } + self.add_slice(slice_1) + slice_2 = copy.deepcopy(slice_1) + slice_2['decimation_scheme'] = create_default_scheme() + self.add_slice(slice_2, {0: "CONCURRENT"}) + + @classmethod + def error_message(cls): + return ExperimentException, \ + "Slices 0 and 1 are CONCURRENT interfaced and do not have the same decimation scheme" diff --git a/testing_archive/test_mismatched_dm_schemes_aveperiod.py b/testing_archive/test_mismatched_dm_schemes_aveperiod.py new file mode 100644 index 0000000..6281264 --- /dev/null +++ b/testing_archive/test_mismatched_dm_schemes_aveperiod.py @@ -0,0 +1,69 @@ +#!/usr/bin/python + +""" +No fault expected, SEQUENCE interfaced slices are allowed to have different DecimationSchemes +""" +import copy + +import borealis_experiments.superdarn_common_fields as scf +from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import \ + DecimationScheme, DecimationStage, create_firwin_filter_by_attenuation, create_default_scheme +from experiment_prototype.experiment_exception import ExperimentException + + +class TestExperiment(ExperimentPrototype): + + def __init__(self): + cpid = 1 + ### dm_rate is not an integer + rates = [5.0e6, 500.0e3, 500.0e3/6, 50.0e3/3] + dm_rates = [10, 6, 5, 5] + transition_widths = [150.0e3, 40.0e3, 15.0e3, 1.0e3] + cutoffs = [20.0e3, 10.0e3, 10.0e3, 5.0e3] + ripple_dbs = [150.0, 80.0, 35.0, 9.0] + scaling_factors = [10.0, 100.0, 100.0, 100.0] + all_stages = [] + for stage in range(0, len(rates)): + filter_taps = list( + scaling_factors[stage] * create_firwin_filter_by_attenuation( + rates[stage], transition_widths[stage], cutoffs[stage], + ripple_dbs[stage])) + all_stages.append(DecimationStage(stage, rates[stage], + dm_rates[stage], filter_taps)) + + # changed from 10e3/3->10e3 + decimation_scheme = (DecimationScheme(rates[0], rates[-1]/dm_rates[-1], stages=all_stages)) + super(TestExperiment, self).__init__(cpid, output_rx_rate=decimation_scheme.output_sample_rate) + + if scf.IS_FORWARD_RADAR: + beams_to_use = scf.STD_16_FORWARD_BEAM_ORDER + else: + beams_to_use = scf.STD_16_REVERSE_BEAM_ORDER + + if scf.options.site_id in ["cly", "rkn", "inv"]: + num_ranges = scf.POLARDARN_NUM_RANGES + if scf.options.site_id in ["sas", "pgr"]: + num_ranges = scf.STD_NUM_RANGES + + slice_1 = { # slice_id = 0 + "pulse_sequence": scf.SEQUENCE_7P, + "tau_spacing": scf.TAU_SPACING_7P, + "pulse_len": scf.PULSE_LEN_45KM, + "num_ranges": num_ranges, + "first_range": scf.STD_FIRST_RANGE, + "intt": 3500, # duration of an integration, in ms + "beam_angle": scf.STD_16_BEAM_ANGLE, + "rx_beam_order": beams_to_use, + "tx_beam_order": beams_to_use, + "scanbound": [i * 3.5 for i in range(len(beams_to_use))], #1 min scan + "freq" : scf.COMMON_MODE_FREQ_1, #kHz + "acf": True, + "xcf": True, # cross-correlation processing + "acfint": True, # interferometer acfs + "decimation_scheme": decimation_scheme, + } + self.add_slice(slice_1) + slice_2 = copy.deepcopy(slice_1) + slice_2['decimation_scheme'] = create_default_scheme() + self.add_slice(slice_2, {0: "SEQUENCE"}) diff --git a/testing_archive/test_no_class.py b/testing_archive/test_no_class.py index 12bb53a..80362c8 100644 --- a/testing_archive/test_no_class.py +++ b/testing_archive/test_no_class.py @@ -3,11 +3,10 @@ """ Experiment fault: Experiment isn't a class -Expected exception: - No experiment classes are present that are built from parent class ExperimentPrototype - exiting """ import borealis_experiments.superdarn_common_fields as scf +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme ### class TestExperiment(ExperimentPrototype): @@ -41,5 +40,6 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) diff --git a/testing_archive/test_no_freq_set.py b/testing_archive/test_no_freq_set.py index 13167cd..21b204e 100644 --- a/testing_archive/test_no_freq_set.py +++ b/testing_archive/test_no_freq_set.py @@ -3,12 +3,12 @@ """ Experiment fault: Slice has no freq or clrfrqrange -Expected exception: - A freq or clrfrqrange must be specified in a slice """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -41,6 +41,7 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } ### No freq or clrfrqrange @@ -57,3 +58,7 @@ def __init__(self): except: pass self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "A freq or clrfrqrange must be specified in a slice. Slice: 0 \(type=value_error\)" diff --git a/testing_archive/test_no_inheritance.py b/testing_archive/test_no_inheritance.py index 040f8fe..a4cca97 100644 --- a/testing_archive/test_no_inheritance.py +++ b/testing_archive/test_no_inheritance.py @@ -3,11 +3,11 @@ """ Experiment fault: Experiment doesn't inherit from ExperimentPrototype -Expected exception: - No experiment classes are present that are built from parent class ExperimentPrototype - exiting """ import borealis_experiments.superdarn_common_fields as scf +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from experiment_prototype.experiment_exception import ExperimentException class TestExperiment(): ### Doesn't inherit from ExperimentPrototype @@ -41,5 +41,10 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ExperimentException, "pass" diff --git a/testing_archive/test_no_intt_intn.py b/testing_archive/test_no_intt_intn.py index 596364c..d1df713 100644 --- a/testing_archive/test_no_intt_intn.py +++ b/testing_archive/test_no_intt_intn.py @@ -3,12 +3,12 @@ """ Experiment fault: No intt or intn -Expected exception: - Slice .* has transmission but no intt or intn """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -41,5 +41,10 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "Slice must specify either an intn \(unitless\) or intt in ms. Slice: 0" diff --git a/testing_archive/test_no_slices.py b/testing_archive/test_no_slices.py index a3ea698..030beae 100644 --- a/testing_archive/test_no_slices.py +++ b/testing_archive/test_no_slices.py @@ -3,12 +3,12 @@ """ Experiment fault: Experiment has no slices -Expected exception: - Invalid num_slices less than 1 """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from experiment_prototype.experiment_exception import ExperimentException class TestExperiment(ExperimentPrototype): @@ -28,3 +28,7 @@ def __init__(self): num_ranges = scf.STD_NUM_RANGES ### Don't add any slices + + @classmethod + def error_message(cls): + return ExperimentException, "Invalid num_slices less than 1" diff --git a/testing_archive/test_num_ranges_dne.py b/testing_archive/test_num_ranges_dne.py index 4d719f6..03fa748 100644 --- a/testing_archive/test_num_ranges_dne.py +++ b/testing_archive/test_num_ranges_dne.py @@ -3,12 +3,11 @@ """ Experiment fault: num_ranges not set in slice -Expected exception: - Slice must specify num_ranges that must be an integer """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme class TestExperiment(ExperimentPrototype): @@ -42,5 +41,10 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return TypeError, "__init__\(\) missing 1 required positional argument: 'num_ranges'" diff --git a/testing_archive/test_num_ranges_not_int.py b/testing_archive/test_num_ranges_not_int.py index 87621c5..4f493d7 100644 --- a/testing_archive/test_num_ranges_not_int.py +++ b/testing_archive/test_num_ranges_not_int.py @@ -3,12 +3,12 @@ """ Experiment fault: num_ranges not an integer -Expected exception: - Slice must specify num_ranges that must be an integer """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -42,5 +42,11 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "num_ranges\n" \ + " value is not a valid integer \(type=type_error.integer\)" diff --git a/testing_archive/test_output_rxrate_high.py b/testing_archive/test_output_rxrate_high.py index e28ecec..13356fb 100644 --- a/testing_archive/test_output_rxrate_high.py +++ b/testing_archive/test_output_rxrate_high.py @@ -3,12 +3,12 @@ """ Experiment fault: output_rx_rate higher than max sample rate -Expected exception: - Experiment's output sample rate is too high """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from experiment_prototype.experiment_exception import ExperimentException class TestExperiment(ExperimentPrototype): @@ -43,5 +43,10 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ExperimentException, "Experiment's output sample rate is too high: 100001.0 greater than max 100000.0." diff --git a/testing_archive/test_ppo_bad_length.py b/testing_archive/test_ppo_bad_length.py new file mode 100644 index 0000000..30d3d50 --- /dev/null +++ b/testing_archive/test_ppo_bad_length.py @@ -0,0 +1,48 @@ +#!/usr/bin/python + +""" +Experiment fault: + pulse_phase_offset return value does not have shape equal to (num_pulses,) +""" + +import numpy as np + +import borealis_experiments.superdarn_common_fields as scf +from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError + + +def phase_encode(beam_iter, sequence_num, num_pulses): + return np.random.uniform(-180.0, 180, num_pulses-1) # length is not num_pulses + + +class TestExperiment(ExperimentPrototype): + + def __init__(self): + cpid = 1 + + default_slice = { # slice_id = 0, the first slice + "pulse_sequence": scf.SEQUENCE_8P, + "tau_spacing": scf.TAU_SPACING_8P, + "pulse_len": scf.PULSE_LEN_45KM, + "num_ranges": scf.STD_NUM_RANGES, + "first_range": scf.STD_FIRST_RANGE, + "intt": scf.INTT_8P, + "beam_angle": [1.75], + "rx_beam_order": [0], + "tx_beam_order": [0], + "freq": 13100, + "decimation_scheme": create_default_scheme(), + "pulse_phase_offset": phase_encode + } + + super().__init__(cpid) + + self.add_slice(default_slice) + + @classmethod + def error_message(cls): + return ValidationError, "pulse_phase_offset\n" \ + " Slice 0 Phase encoding return dimension must be equal to number of pulses " \ + "\(type=value_error\)" \ No newline at end of file diff --git a/testing_archive/test_ppo_not_1d.py b/testing_archive/test_ppo_not_1d.py new file mode 100644 index 0000000..e9a1060 --- /dev/null +++ b/testing_archive/test_ppo_not_1d.py @@ -0,0 +1,47 @@ +#!/usr/bin/python + +""" +Experiment fault: + pulse_phase_offset return value is not 1-dimensional +""" + +import numpy as np + +import borealis_experiments.superdarn_common_fields as scf +from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError + + +def phase_encode(beam_iter, sequence_num, num_pulses): + return np.random.uniform(-180.0, 180, num_pulses).reshape(1, num_pulses) + + +class TestExperiment(ExperimentPrototype): + + def __init__(self): + cpid = 1 + + default_slice = { # slice_id = 0, the first slice + "pulse_sequence": scf.SEQUENCE_8P, + "tau_spacing": scf.TAU_SPACING_8P, + "pulse_len": scf.PULSE_LEN_45KM, + "num_ranges": scf.STD_NUM_RANGES, + "first_range": scf.STD_FIRST_RANGE, + "intt": scf.INTT_8P, + "beam_angle": [1.75], + "rx_beam_order": [0], + "tx_beam_order": [0], + "freq": 13100, + "decimation_scheme": create_default_scheme(), + "pulse_phase_offset": phase_encode + } + + super().__init__(cpid) + + self.add_slice(default_slice) + + @classmethod + def error_message(cls): + return ValidationError, "pulse_phase_offset\n" \ + " Slice 0 Phase encoding return must be 1 dimensional \(type=value_error\)" \ No newline at end of file diff --git a/testing_archive/test_ppo_np.py b/testing_archive/test_ppo_np.py new file mode 100644 index 0000000..bd0db8d --- /dev/null +++ b/testing_archive/test_ppo_np.py @@ -0,0 +1,47 @@ +#!/usr/bin/python + +""" +Experiment fault: + pulse_phase_offset return value is not a numpy array +""" + +import numpy as np + +import borealis_experiments.superdarn_common_fields as scf +from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError + + +def phase_encode(beam_iter, sequence_num, num_pulses): + return np.random.uniform(-180.0, 180, num_pulses).tolist() + + +class TestExperiment(ExperimentPrototype): + + def __init__(self): + cpid = 1 + + default_slice = { # slice_id = 0, the first slice + "pulse_sequence": scf.SEQUENCE_8P, + "tau_spacing": scf.TAU_SPACING_8P, + "pulse_len": scf.PULSE_LEN_45KM, + "num_ranges": scf.STD_NUM_RANGES, + "first_range": scf.STD_FIRST_RANGE, + "intt": scf.INTT_8P, + "beam_angle": [1.75], + "rx_beam_order": [0], + "tx_beam_order": [0], + "freq": 13100, + "decimation_scheme": create_default_scheme(), + "pulse_phase_offset": phase_encode + } + + super().__init__(cpid) + + self.add_slice(default_slice) + + @classmethod + def error_message(cls): + return ValidationError, "pulse_phase_offset\n" \ + " Slice 0 Phase encoding return is not numpy array \(type=value_error\)" \ No newline at end of file diff --git a/testing_archive/test_pulse_len_bad.py b/testing_archive/test_pulse_len_bad.py index 3d5ef11..e416ed3 100644 --- a/testing_archive/test_pulse_len_bad.py +++ b/testing_archive/test_pulse_len_bad.py @@ -3,36 +3,27 @@ """ Experiment fault: pulse_len invalid -Expected exception: - For an experiment slice with real-time acfs, pulse length must be equal \(within 1 us\) to - 1\/output_rx_rate to make acfs valid. Current pulse length is .* us, output rate is .* Hz """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): def __init__(self): cpid = 1 - super(TestExperiment, self).__init__(cpid) + super().__init__(cpid) - if scf.IS_FORWARD_RADAR: - beams_to_use = scf.STD_16_FORWARD_BEAM_ORDER - else: - beams_to_use = scf.STD_16_REVERSE_BEAM_ORDER - - if scf.options.site_id in ["cly", "rkn", "inv"]: - num_ranges = scf.POLARDARN_NUM_RANGES - if scf.options.site_id in ["sas", "pgr"]: - num_ranges = scf.STD_NUM_RANGES + beams_to_use = scf.STD_16_FORWARD_BEAM_ORDER slice_1 = { # slice_id = 0, there is only one slice. "pulse_sequence": scf.SEQUENCE_7P, "tau_spacing": scf.TAU_SPACING_7P, - "pulse_len": int(1/self.output_rx_rate) + 1, ### pulse_len must be the same as 1/output_rx_rate (within floating point error) - "num_ranges": num_ranges, + "pulse_len": int(1/self.output_rx_rate*1e6) + 1, ### pulse_len must be the same as 1/output_rx_rate (within floating point error) + "num_ranges": scf.STD_NUM_RANGES, "first_range": scf.STD_FIRST_RANGE, "intt": 3500, # duration of an integration, in ms "beam_angle": scf.STD_16_BEAM_ANGLE, @@ -43,5 +34,12 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "For an experiment slice with real-time acfs, pulse length must be equal \(within 1 " \ + "us\) to 1/output_rx_rate to make acfs valid. Current pulse length is 301 us, output" \ + " rate is 3333.3333333333335 Hz. Slice: 0 \(type=value_error\)" diff --git a/testing_archive/test_pulse_len_dne.py b/testing_archive/test_pulse_len_dne.py index e05f65e..db35a6b 100644 --- a/testing_archive/test_pulse_len_dne.py +++ b/testing_archive/test_pulse_len_dne.py @@ -3,12 +3,11 @@ """ Experiment fault: pulse_len not specified in slice -Expected exception: - Slice must specify pulse_len in us that must be an integer """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme class TestExperiment(ExperimentPrototype): @@ -42,5 +41,10 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return TypeError, "__init__\(\) missing 1 required positional argument: 'pulse_len'" diff --git a/testing_archive/test_pulse_len_not_int.py b/testing_archive/test_pulse_len_not_int.py index f9e080d..f010af8 100644 --- a/testing_archive/test_pulse_len_not_int.py +++ b/testing_archive/test_pulse_len_not_int.py @@ -3,12 +3,12 @@ """ Experiment fault: pulse_len not an integer -Expected exception: - Slice must specify pulse_len in us that must be an integer """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -42,5 +42,11 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "pulse_len\n" \ + " value is not a valid integer \(type=type_error.integer\)" diff --git a/testing_archive/test_pulse_len_too_high.py b/testing_archive/test_pulse_len_too_high.py index 7f2df18..af069ff 100644 --- a/testing_archive/test_pulse_len_too_high.py +++ b/testing_archive/test_pulse_len_too_high.py @@ -3,12 +3,12 @@ """ Experiment fault: pulse_len too high -Expected exception: - Slice .* pulse length greater than tau_spacing """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -42,5 +42,13 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "tau_spacing\n" \ + " Slice 0 correlation lags will be off because tau_spacing 100 us is not a " \ + "multiple of the output rx sampling period \(1/output_rx_rate 3333.3333333333335 " \ + "Hz\). \(type=value_error\)" diff --git a/testing_archive/test_pulse_len_too_low.py b/testing_archive/test_pulse_len_too_low.py index 4f8bbb7..8ce58ae 100644 --- a/testing_archive/test_pulse_len_too_low.py +++ b/testing_archive/test_pulse_len_too_low.py @@ -3,14 +3,14 @@ """ Experiment fault: pulse_len too small -Expected exception: - Slice .* pulse length too small """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype -from experiment_prototype.decimation_scheme.decimation_scheme import \ +from experiment_prototype.experiment_utils.decimation_scheme import \ DecimationScheme, DecimationStage, create_firwin_filter_by_attenuation +from pydantic import ValidationError + class TestExperiment(ExperimentPrototype): @@ -34,9 +34,7 @@ def __init__(self): # changed from 10e3/3->10e3 decimation_scheme = (DecimationScheme(rates[0], rates[-1]/dm_rates[-1], stages=all_stages)) - super(TestExperiment, self).__init__( - cpid, output_rx_rate=decimation_scheme.output_sample_rate, - decimation_scheme=decimation_scheme) + super(TestExperiment, self).__init__(cpid, output_rx_rate=decimation_scheme.output_sample_rate) if scf.IS_FORWARD_RADAR: beams_to_use = scf.STD_16_FORWARD_BEAM_ORDER @@ -65,5 +63,12 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": decimation_scheme, } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "pulse_len\n" \ + " ensure this value is greater than or equal to 100.0 " \ + "\(type=value_error.number.not_ge; limit_value=100.0\)" diff --git a/testing_archive/test_rx_antenna_dne.py b/testing_archive/test_rx_antenna_dne.py index 0115958..ea25e72 100644 --- a/testing_archive/test_rx_antenna_dne.py +++ b/testing_archive/test_rx_antenna_dne.py @@ -3,12 +3,12 @@ """ Experiment fault: Specify rx_main_antennas number of antenna that doesn't exist -Expected exception: - Slice .* specifies RX main array antenna numbers over config max .* """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -42,6 +42,13 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs - "rx_main_antennas": [0,1,2,3,4,5,6,7,8,23] ### antenna 23 DNE, should fail + "rx_main_antennas": [0,1,2,3,4,5,6,7,8,23], ### antenna 23 DNE, should fail + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "rx_main_antennas -> 9\n" \ + " ensure this value is less than 16 " \ + "\(type=value_error.number.not_lt; limit_value=16\)" diff --git a/testing_archive/test_rx_antenna_dups.py b/testing_archive/test_rx_antenna_dups.py index 8114800..10edb24 100644 --- a/testing_archive/test_rx_antenna_dups.py +++ b/testing_archive/test_rx_antenna_dups.py @@ -3,12 +3,12 @@ """ Experiment fault: rx_main_antennas containing duplicate antennas -Expected exception: - Slice .* RX main antennas has duplicate antennas """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -42,6 +42,13 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs - "rx_main_antennas": [0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15] ### 0 is dup'd, should fail + "rx_main_antennas": [0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15], ### 0 is dup'd, should fail + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "rx_main_antennas\n" \ + " ensure this value has at most 16 items " \ + "\(type=value_error.list.max_items; limit_value=16\)" diff --git a/testing_archive/test_rx_int_antenna_invalid.py b/testing_archive/test_rx_int_antenna_invalid.py new file mode 100644 index 0000000..79e5fa8 --- /dev/null +++ b/testing_archive/test_rx_int_antenna_invalid.py @@ -0,0 +1,45 @@ +#!/usr/bin/python + +""" +Experiment fault: + tx_antennas has invalid values (above and below the allowed range) +""" + +import borealis_experiments.superdarn_common_fields as scf +from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError + + +class TestExperiment(ExperimentPrototype): + + def __init__(self): + cpid = 1 + super().__init__(cpid) + + beams_to_use = scf.STD_16_FORWARD_BEAM_ORDER + num_ranges = scf.STD_NUM_RANGES + + slice_1 = { # slice_id = 0, there is only one slice. + "pulse_sequence": scf.SEQUENCE_7P, + "tau_spacing": scf.TAU_SPACING_7P, + "pulse_len": scf.PULSE_LEN_45KM, + "num_ranges": num_ranges, + "first_range": scf.STD_FIRST_RANGE, + "intt": 3500, # duration of an integration, in ms + "beam_angle": scf.STD_16_BEAM_ANGLE, + "rx_beam_order": beams_to_use, + "tx_beam_order": beams_to_use, + "freq": scf.COMMON_MODE_FREQ_1, #kHz + "rx_int_antennas": [-1, 1, 2, 4], ### antenna -1 and 4 are out of range + "decimation_scheme": create_default_scheme(), + } + self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "rx_int_antennas -> 0\n" \ + " ensure this value is greater than or equal to 0 \(type=value_error.number.not_ge; " \ + "limit_value=0\)\n" \ + "rx_int_antennas -> 3\n" \ + " ensure this value is less than 4 \(type=value_error.number.not_lt; limit_value=4\)" diff --git a/testing_archive/test_rx_main_antenna_invalid.py b/testing_archive/test_rx_main_antenna_invalid.py new file mode 100644 index 0000000..de50b6e --- /dev/null +++ b/testing_archive/test_rx_main_antenna_invalid.py @@ -0,0 +1,45 @@ +#!/usr/bin/python + +""" +Experiment fault: + tx_antennas has invalid values (above and below the allowed range) +""" + +import borealis_experiments.superdarn_common_fields as scf +from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError + + +class TestExperiment(ExperimentPrototype): + + def __init__(self): + cpid = 1 + super().__init__(cpid) + + beams_to_use = scf.STD_16_FORWARD_BEAM_ORDER + num_ranges = scf.STD_NUM_RANGES + + slice_1 = { # slice_id = 0, there is only one slice. + "pulse_sequence": scf.SEQUENCE_7P, + "tau_spacing": scf.TAU_SPACING_7P, + "pulse_len": scf.PULSE_LEN_45KM, + "num_ranges": num_ranges, + "first_range": scf.STD_FIRST_RANGE, + "intt": 3500, # duration of an integration, in ms + "beam_angle": scf.STD_16_BEAM_ANGLE, + "rx_beam_order": beams_to_use, + "tx_beam_order": beams_to_use, + "freq": scf.COMMON_MODE_FREQ_1, #kHz + "rx_main_antennas": [-1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16], ### antenna -1 and 16 are out of range + "decimation_scheme": create_default_scheme(), + } + self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "rx_main_antennas -> 0\n" \ + " ensure this value is greater than or equal to 0 \(type=value_error.number.not_ge; " \ + "limit_value=0\)\n" \ + "rx_main_antennas -> 15\n" \ + " ensure this value is less than 16 \(type=value_error.number.not_lt; limit_value=16\)" diff --git a/testing_archive/test_rxbw_not_divisible.py b/testing_archive/test_rxbw_not_divisible.py index 2cf498e..5c5c706 100644 --- a/testing_archive/test_rxbw_not_divisible.py +++ b/testing_archive/test_rxbw_not_divisible.py @@ -3,12 +3,12 @@ """ Experiment fault: rx_bandwidth not divisible by usrp clock rate -Expected exception: - Experiment's receive bandwidth .* is not possible as it must be an integer divisor of USRP master clock rate """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from experiment_prototype.experiment_exception import ExperimentException class TestExperiment(ExperimentPrototype): @@ -44,5 +44,12 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ExperimentException, \ + "Experiment's receive bandwidth 3141590.0 is not possible as it must be an integer divisor of USRP " \ + "master clock rate 100000000.0" diff --git a/testing_archive/test_rxonly_dne.py b/testing_archive/test_rxonly_dne.py new file mode 100644 index 0000000..6fffe4f --- /dev/null +++ b/testing_archive/test_rxonly_dne.py @@ -0,0 +1,40 @@ +#!/usr/bin/python + +""" +Experiment fault: + rxonly not specified alongside and no tx_beam_order specified either. rxonly must be manually set to True + for receive-only modes. +""" + +import numpy as np + +import borealis_experiments.superdarn_common_fields as scf +from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError + + +class TestExperiment(ExperimentPrototype): + + def __init__(self): + cpid = 1 + super().__init__(cpid) + + slice_1 = { # slice_id = 0, there is only one slice. + "pulse_sequence": scf.SEQUENCE_7P, + "tau_spacing": scf.TAU_SPACING_7P, + "pulse_len": scf.PULSE_LEN_45KM, + "num_ranges": scf.STD_NUM_RANGES, + "first_range": scf.STD_FIRST_RANGE, + "intt": 3500, # duration of an integration, in ms + "beam_angle": scf.STD_16_BEAM_ANGLE, + "rx_beam_order": scf.STD_16_FORWARD_BEAM_ORDER, + "freq": scf.COMMON_MODE_FREQ_1, # kHz + "decimation_scheme": create_default_scheme(), + } + self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "__root__\n" \ + " rxonly specified as False but tx_beam_order not given. Slice: 0 \(type=value_error\)" diff --git a/testing_archive/test_rxrate_high.py b/testing_archive/test_rxrate_high.py index 1543e64..2809575 100644 --- a/testing_archive/test_rxrate_high.py +++ b/testing_archive/test_rxrate_high.py @@ -3,12 +3,12 @@ """ Experiment fault: rx_bandwidth too large -Expected exception: - Experiment's receive bandwidth is too large """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from experiment_prototype.experiment_exception import ExperimentException class TestExperiment(ExperimentPrototype): @@ -44,5 +44,11 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ExperimentException, \ + "Experiment's receive bandwidth is too large: 25000000.0 greater than max 5000000.0." diff --git a/testing_archive/test_scanbound_but_no_intt.py b/testing_archive/test_scanbound_but_no_intt.py index 4e8b0b2..0d63dc8 100644 --- a/testing_archive/test_scanbound_but_no_intt.py +++ b/testing_archive/test_scanbound_but_no_intt.py @@ -3,12 +3,12 @@ """ Experiment fault: scanbound specified by not intt -Expected exception: - Slice .* must have intt enabled to use scanbound """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -43,5 +43,11 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "scanbound\n" \ + " Slice 0 must have intt enabled to use scanbound \(type=value_error\)" diff --git a/testing_archive/test_scanbound_dne.py b/testing_archive/test_scanbound_dne.py index 5964f7e..de2c72a 100644 --- a/testing_archive/test_scanbound_dne.py +++ b/testing_archive/test_scanbound_dne.py @@ -3,12 +3,12 @@ """ Experiment fault: scanbound not specified for all slices -Expected exception: - If one slice has a scanbound, they all must to avoid up to minute-long downtimes. """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from experiment_prototype.experiment_exception import ExperimentException class TestExperiment(ExperimentPrototype): @@ -42,6 +42,7 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } slice_2 = { # slice_id = 1 "pulse_sequence": scf.SEQUENCE_8P, @@ -58,7 +59,11 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) self.add_slice(slice_2, interfacing_dict={0: 'SCAN'}) ### no scanbound on second slice, should fail + @classmethod + def error_message(cls): + return ExperimentException, "If one slice has a scanbound, they all must to avoid up to minute-long downtimes." diff --git a/testing_archive/test_scanbound_negative.py b/testing_archive/test_scanbound_negative.py index 2ffd165..cc6aec0 100644 --- a/testing_archive/test_scanbound_negative.py +++ b/testing_archive/test_scanbound_negative.py @@ -3,12 +3,12 @@ """ Experiment fault: scanbound containing negative values -Expected exception: - Slice .* scanbound times must be non-negative """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -42,5 +42,54 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "scanbound -> 1\n" \ + " ensure this value is greater than or equal to 0 " \ + "\(type=value_error.number.not_ge; limit_value=0\)\n" \ + "scanbound -> 2\n" \ + " ensure this value is greater than or equal to 0 " \ + "\(type=value_error.number.not_ge; limit_value=0\)\n" \ + "scanbound -> 3\n" \ + " ensure this value is greater than or equal to 0 " \ + "\(type=value_error.number.not_ge; limit_value=0\)\n" \ + "scanbound -> 4\n" \ + " ensure this value is greater than or equal to 0 " \ + "\(type=value_error.number.not_ge; limit_value=0\)\n" \ + "scanbound -> 5\n" \ + " ensure this value is greater than or equal to 0 " \ + "\(type=value_error.number.not_ge; limit_value=0\)\n" \ + "scanbound -> 6\n" \ + " ensure this value is greater than or equal to 0 " \ + "\(type=value_error.number.not_ge; limit_value=0\)\n" \ + "scanbound -> 7\n" \ + " ensure this value is greater than or equal to 0 " \ + "\(type=value_error.number.not_ge; limit_value=0\)\n" \ + "scanbound -> 8\n" \ + " ensure this value is greater than or equal to 0 " \ + "\(type=value_error.number.not_ge; limit_value=0\)\n" \ + "scanbound -> 9\n" \ + " ensure this value is greater than or equal to 0 " \ + "\(type=value_error.number.not_ge; limit_value=0\)\n" \ + "scanbound -> 10\n" \ + " ensure this value is greater than or equal to 0 " \ + "\(type=value_error.number.not_ge; limit_value=0\)\n" \ + "scanbound -> 11\n" \ + " ensure this value is greater than or equal to 0 " \ + "\(type=value_error.number.not_ge; limit_value=0\)\n" \ + "scanbound -> 12\n" \ + " ensure this value is greater than or equal to 0 " \ + "\(type=value_error.number.not_ge; limit_value=0\)\n" \ + "scanbound -> 13\n" \ + " ensure this value is greater than or equal to 0 " \ + "\(type=value_error.number.not_ge; limit_value=0\)\n" \ + "scanbound -> 14\n" \ + " ensure this value is greater than or equal to 0 " \ + "\(type=value_error.number.not_ge; limit_value=0\)\n" \ + "scanbound -> 15\n" \ + " ensure this value is greater than or equal to 0 " \ + "\(type=value_error.number.not_ge; limit_value=0\)" diff --git a/testing_archive/test_scanbound_not_increasing.py b/testing_archive/test_scanbound_not_increasing.py index 4a54726..607fc37 100644 --- a/testing_archive/test_scanbound_not_increasing.py +++ b/testing_archive/test_scanbound_not_increasing.py @@ -3,12 +3,12 @@ """ Experiment fault: scanbound non-increasing values -Expected exception: - Slice .* scanbound times must be increasing """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -42,5 +42,10 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "Slice 0 scanbound times must be increasing" diff --git a/testing_archive/test_seq_not_increasing.py b/testing_archive/test_seq_not_increasing.py index 2e6681e..68688ff 100644 --- a/testing_archive/test_seq_not_increasing.py +++ b/testing_archive/test_seq_not_increasing.py @@ -3,12 +3,12 @@ """ Experiment fault: pulse_sequence not increasing -Expected exception: - Slice .* pulse_sequence not increasing """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -42,5 +42,11 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "pulse_sequence\n" \ + " not increasing: \[14, 0, 19, 21, 40\] \(type=value_error\)" diff --git a/testing_archive/test_sequence_dne.py b/testing_archive/test_sequence_dne.py index b395641..ec32736 100644 --- a/testing_archive/test_sequence_dne.py +++ b/testing_archive/test_sequence_dne.py @@ -3,12 +3,11 @@ """ Experiment fault: No pulse_sequence specified -Expected exception: - Slice must specify pulse_sequence that must be a list of integers """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme class TestExperiment(ExperimentPrototype): @@ -42,5 +41,10 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return TypeError, "__init__\(\) missing 1 required positional argument: 'pulse_sequence'" diff --git a/testing_archive/test_sequence_not_int.py b/testing_archive/test_sequence_not_int.py index 6b67ff3..60ff864 100644 --- a/testing_archive/test_sequence_not_int.py +++ b/testing_archive/test_sequence_not_int.py @@ -3,12 +3,12 @@ """ Experiment fault: pulse_sequence containing non-integer values -Expected exception: - Slice must specify pulse_sequence that must be a list of integers """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -42,5 +42,17 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "pulse_sequence -> 0\n" \ + " value is not a valid integer \(type=type_error.integer\)\n" \ + "pulse_sequence -> 1\n" \ + " value is not a valid integer \(type=type_error.integer\)\n" \ + "pulse_sequence -> 2\n" \ + " value is not a valid integer \(type=type_error.integer\)\n" \ + "pulse_sequence -> 3\n" \ + " value is not a valid integer \(type=type_error.integer\)" diff --git a/testing_archive/test_sequence_not_list.py b/testing_archive/test_sequence_not_list.py index 138372b..0e273c8 100644 --- a/testing_archive/test_sequence_not_list.py +++ b/testing_archive/test_sequence_not_list.py @@ -3,12 +3,12 @@ """ Experiment fault: pulse_sequence not a list -Expected exception: - Slice must specify pulse_sequence that must be a list of integers """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -42,5 +42,11 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "pulse_sequence\n" \ + " value is not a valid list \(type=type_error.list\)" diff --git a/testing_archive/test_slices_beam_order_bad.py b/testing_archive/test_slices_beam_order_bad.py index 3d8580e..aa674da 100644 --- a/testing_archive/test_slices_beam_order_bad.py +++ b/testing_archive/test_slices_beam_order_bad.py @@ -3,15 +3,14 @@ """ Experiment fault: invalid beam_order for slice interfacing -Expected exception: - Slices .* and .* are SEQUENCE or CONCURRENT interfaced but do not have the same number of - averaging periods in their beam order """ import copy import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from experiment_prototype.experiment_exception import ExperimentException class TestExperiment(ExperimentPrototype): @@ -44,9 +43,16 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } slice_2 = copy.deepcopy(slice_1) slice_2['rx_beam_order'] = [0, 1, 2, 3, 4, 5, 6, 7] ### Only half of the beams, should fail slice_2['tx_beam_order'] = [0, 1, 2, 3, 4, 5, 6, 7] self.add_slice(slice_1) self.add_slice(slice_2, interfacing_dict={0:'CONCURRENT'}) + + @classmethod + def error_message(cls): + return ExperimentException, \ + "Slices 0 and 1 are SEQUENCE or CONCURRENT interfaced but do not have the same number of averaging " \ + "periods in their beam order" diff --git a/testing_archive/test_slices_intn_bad.py b/testing_archive/test_slices_intn_bad.py index 50d992a..f8b8a51 100644 --- a/testing_archive/test_slices_intn_bad.py +++ b/testing_archive/test_slices_intn_bad.py @@ -3,14 +3,14 @@ """ Experiment fault: interfacing slices have different intn -Expected exception: - Slices .* and .* are SEQUENCE or CONCURRENT interfaced and do not have the same NAVE goal intn """ import copy import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from experiment_prototype.experiment_exception import ExperimentException class TestExperiment(ExperimentPrototype): @@ -43,6 +43,7 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } slice_2 = copy.deepcopy(slice_1) del slice_2['intt'] @@ -51,3 +52,8 @@ def __init__(self): slice_1['intn'] = 9 ### Different intn targets, should fail self.add_slice(slice_1) self.add_slice(slice_2, interfacing_dict={0:'CONCURRENT'}) + + @classmethod + def error_message(cls): + return ExperimentException, \ + "Slices 0 and 1 are SEQUENCE or CONCURRENT interfaced and do not have the same NAVE goal intn" diff --git a/testing_archive/test_slices_intt_bad.py b/testing_archive/test_slices_intt_bad.py index 17bdf74..bbf113b 100644 --- a/testing_archive/test_slices_intt_bad.py +++ b/testing_archive/test_slices_intt_bad.py @@ -3,15 +3,14 @@ """ Experiment fault: Interfacing slices have different intt -Expected exception: - Slices .* and .* are SEQUENCE or CONCURRENT interfaced and do not have the same Averaging Period - duration intt """ import copy import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from experiment_prototype.experiment_exception import ExperimentException class TestExperiment(ExperimentPrototype): @@ -45,6 +44,7 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } slice_2 = copy.deepcopy(slice_1) try: @@ -59,3 +59,9 @@ def __init__(self): slice_1['intt'] = 3490 ### Different intt durations, should fail self.add_slice(slice_1) self.add_slice(slice_2, interfacing_dict={0:'CONCURRENT'}) + + @classmethod + def error_message(cls): + return ExperimentException, \ + "Slices 0 and 1 are SEQUENCE or CONCURRENT interfaced and do not have the same Averaging Period " \ + "duration intt" diff --git a/testing_archive/test_slices_scanbound_bad.py b/testing_archive/test_slices_scanbound_bad.py index ccbfb54..7e14c0b 100644 --- a/testing_archive/test_slices_scanbound_bad.py +++ b/testing_archive/test_slices_scanbound_bad.py @@ -3,12 +3,12 @@ """ Experiment fault: Interfacing slices have different scanbound values -Expected exception: - Scan boundary not the same between slices .* and .* for AVEPERIOD or CONCURRENT interfaced slices """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from experiment_prototype.experiment_exception import ExperimentException class TestExperiment(ExperimentPrototype): @@ -42,6 +42,7 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } slice_2 = { # slice_id = 1 "pulse_sequence": scf.SEQUENCE_8P, @@ -59,7 +60,12 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) self.add_slice(slice_2, interfacing_dict={0: 'CONCURRENT'}) + @classmethod + def error_message(cls): + return ExperimentException, \ + "Scan boundary not the same between slices 0 and 1 for AVEPERIOD or CONCURRENT interfaced slices" diff --git a/testing_archive/test_stage0_bad_inputrate.py b/testing_archive/test_stage0_bad_inputrate.py index 8dcf30b..aa0c6b1 100644 --- a/testing_archive/test_stage0_bad_inputrate.py +++ b/testing_archive/test_stage0_bad_inputrate.py @@ -3,14 +3,15 @@ """ Experiment fault: Decimation stage 0 invalid input rate -Expected exception: - Decimation stage 0 does not have input rate .* equal to USRP sampling rate .* """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype -from experiment_prototype.decimation_scheme.decimation_scheme import \ +from experiment_prototype.experiment_utils.decimation_scheme import \ DecimationScheme, DecimationStage, create_firwin_filter_by_attenuation +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from experiment_prototype.experiment_exception import ExperimentException + class TestExperiment(ExperimentPrototype): @@ -62,5 +63,11 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": decimation_scheme, } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ExperimentException, \ + "Decimation stage 0 does not have input rate 5100000.0 equal to USRP sampling rate 5200000.0" diff --git a/testing_archive/test_stagex_bad_outputrate.py b/testing_archive/test_stagex_bad_outputrate.py index ff10ec3..3211d40 100644 --- a/testing_archive/test_stagex_bad_outputrate.py +++ b/testing_archive/test_stagex_bad_outputrate.py @@ -3,14 +3,15 @@ """ Experiment fault: Decimation stage x invalid output rate -Expected exception: - Decimation stage .* output rate .* does not equal next stage .* input rate .* """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype -from experiment_prototype.decimation_scheme.decimation_scheme import \ +from experiment_prototype.experiment_utils.decimation_scheme import \ DecimationScheme, DecimationStage, create_firwin_filter_by_attenuation +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from experiment_prototype.experiment_exception import ExperimentException + class TestExperiment(ExperimentPrototype): @@ -64,5 +65,11 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": decimation_scheme, } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ExperimentException, \ + "Decimation stage 0 output rate 500000.0 does not equal next stage 1 input rate 250000.0" diff --git a/testing_archive/test_taps_not_list.py b/testing_archive/test_taps_not_list.py index 6483db7..7aabeae 100644 --- a/testing_archive/test_taps_not_list.py +++ b/testing_archive/test_taps_not_list.py @@ -3,14 +3,15 @@ """ Experiment fault: Decimation stage filter taps not a list -Expected exception: - Filter taps .* of type .* must be a list in decimation stage .* """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype -from experiment_prototype.decimation_scheme.decimation_scheme import \ +from experiment_prototype.experiment_utils.decimation_scheme import \ DecimationScheme, DecimationStage, create_firwin_filter_by_attenuation +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from experiment_prototype.experiment_exception import ExperimentException + class TestExperiment(ExperimentPrototype): @@ -64,5 +65,11 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": decimation_scheme, } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ExperimentException, \ + "Filter taps {0.06289466724896364, -0.0010733131978737358, 0.0034739473230933704, 0.08225352451182923, 3.8736815548755935e-08, -0.0003365289888721362, 3.4897229020296903e-07, 0.0695951435514344, -0.000480057381930764, -0.0024009882540009953, 1.525146324717017e-08, 9.601880324662872e-06, 6.608587739736533e-07, -0.00016656726614700716, -0.0022723317036880673, -0.0016715904235526304, -0.0006259778310093054, -0.0002094213323572842, 0.07634050450522707, 0.0106603162082833, -0.0023209924921151776, -0.0022170321752018897, 0.02202242256928963, 0.07742532989277437, 0.01961658218455495, 8.656110753604306e-06, -0.0015284578439195467, 0.00311186718534993, 0.05246321634635108, 5.916082120294521e-06, 2.206181197828724e-06, 8.31958089807559e-06, -0.0009494006071805216, -0.0023741416143331384, -9.158646873676331e-06, 0.044474664856345325, -0.0006911903688554466, -0.0008710245542883229, -0.0009898869300578451, 0.0012238590423045022, -2.6700248795790924e-05, 0.01448547446571537, -4.6927550412560446e-05, 5.587216209820598e-06, 3.998349768150298e-07, -0.0019527138712386045, 0.039488918105640064, 0.0646579013169585, 0.022850152522714638, 9.727379207166697e-06, -0.0012398028883716249, 0.08248346019377377, -0.000295966757047972, -0.0001301713473561059, 5.265893055101848e-06, 6.936630970229283e-06, -1.7930139381572334e-20, 1.145744914222454e-06, 0.0817809903523374, 2.0236773618653963e-06, 7.283516730366471e-06, 0.0018003197798039563, -0.00022500176418186612, 5.862064728909546e-07, 6.592084651684843e-06, 0.01733226200494296, -0.0023448070313587697, 0.006409896594214745, 0.018841320531247194, -9.949928935860894e-05, -0.0020416727959042917, 1.072105188825564e-05, -0.00134044547650692, -0.00024151879218492644, 0.008413656338717823, 1.1462731497374251e-07, 0.006888224518248666, -0.0024464487464716965, 8.313013071426383e-07, 5.180756075436137e-07, 0.04748202391696512, 0.07322733954560626, 0.005497987864126837, -3.604067103754201e-05, -0.0013869177812535149, 1.630849982118407e-07, 0.007381582840818176, -0.0017308486273283738, 0.05047951717977588, 0.05637020863639402, 0.057330221475522074, -2.256329274414122e-05, -0.0005354982526097347, 0.07516197231547955, 0.07886881128252848, 0.07970377954383184, 0.029888851116174845, 0.0009547146941380543, 1.3730619869641689e-07, 0.05344857851244929, -0.002167116474271743, 1.0151210931692294e-05, 1.0968593941858368e-05, -0.0005949127718093778, 0.02040535791763117, 0.01126006210510896, -0.00045378543991217744, 0.05540278724658995, 0.08235405470373033, 0.04048044299550955, 1.6908671985746142e-06, 0.05442867261903071, 0.00045346041199266593, 2.1692138188908925e-08, 0.012505081755886823, 0.0355690403475698, -0.00020926850658720052, 0.008952470327740493, -0.0019241158571979655, -0.0010936785623917133, 2.3997275272667507e-06, -0.0001416384354536527, 6.893936394546042e-06, -0.0005646791231571291, 0.05147329442618035, -0.0018316094229349966, -0.0007962628392915341, -0.0012944378446069925, -6.649832703027695e-05, 0.07035960997716854, 0.07453881083873386, 0.018079808020846345, -0.0012489546615515699, -0.002491035919873828, -4.110307107626933e-06, -0.00040763984980213367, 0.04347314441125988, 0.028064904788379367, 7.424251342076469e-07, -0.002464664890689465, 0.025406406637780994, 0.007890041340352606, 0.06378282944908116, 0.07110567363567229, 0.0784127263720031, 1.7390766626423138e-06, -0.001433790551060219, 0.00022087753900598367, 0.07254013599442419, -0.00038065769245545437, 0.048483190537792244, -0.00010912347465243661, 6.251441430724166e-06, 0.042473177377907664, 0.03175006199386798, 0.06108187135546527, -0.002488055736150857, 0.07793142728177971, 1.048157713433648e-18, 3.0481814907737657e-06, 0.005946516218467315, 6.254755780767991e-08, 0.021207394911218383, 0.07929928693128875, -0.002497435583084663, -0.0007252552261758124, 0.046479766087839575, 0.05922515725189695, 0.08105521614904057, 0.002429115361732433, 3.799273256474238e-06, 0.013150244251379149, -1.5266453654540216e-05, 1.54000892264513e-06, 4.649336493175233e-06, 0.04547709110451463, -0.0020854545539949515, -0.0021265579956648052, 0.016598882191637684, -0.0024251560420184845, 0.08246907333454662, -0.0024297559197984926, -5.951595955482316e-05, 0.08212442362785628, -4.128125873174736e-05, 0.002108071424421339, -0.0024544610304810055, -0.00018007205277773653, -0.0004040962927861809, -0.001159779264374637, 0.002763650442432735, 1.0974104396405544e-05, -0.0014809950371240943, 0.08132496494423744, -0.002399445992839946, -8.194238715866198e-05, 0.03654091959760706, 4.560786615966971e-07, -0.002279410655343552, -0.0015034720365777578, -0.0013763102602103565, -0.0024795978433219752, 0.06719768019427408, 2.619506572776292e-07, 1.3990993373858622e-06, 0.003850063349973732, 0.027168005364606732, 0.030815026614753223, 3.28542585637886e-06, 8.983995021377113e-06, 4.953012724983122e-06, 3.537596842711744e-06, 1.0325682164026036e-06, 7.977066439096651e-06, 9.885216922940113e-06, 0.08008193713562287, 0.05828210969100015, 0.08043342996708851, 1.2677976203724372e-06, 0.08242592546680576, 2.251002403810694e-07, -0.0012040513839653522, -0.000658096113070276, -0.000771500714345233, 4.96984486342935e-08, 0.07689487035035975, 5.850790244901255e-06, 1.088337650374436e-05, -0.0018139390414664727, 0.011874999820488966, 0.08156696057641506, 2.8206225823486905e-06, -0.0020846945161923478, -0.000833182058539254, 2.6044971758924117e-06, -0.0018607444369520907, -9.044609231282396e-05, 4.35549696550302e-06, 0.0006979930404067116, -0.0019070424543745927, 9.300314863763255e-06, 0.07183271711995307, 0.07389375151868346, -0.0025025561317611146, -5.299913249536603e-05, 4.0720078346828775e-06, 0.00950651160781722, 1.0381801829536081e-05, 0.02454247716865664, -0.0007602828542883173, 1.047964050270924e-05, -0.002498762495863228, 0.041475401287418334, -1.945166613773851e-06, 0.004240378072983618, 0.07576270733041814, -0.0019976340304188444, 0.060158648978224226, -0.0002588393089865985, -0.0016215605297766622, 1.0146552138739823e-05, 1.1000295935293669e-05, 0.015879850736619606, -0.0011161854690177769, 1.8519927447572555e-06, 0.005064203732491989, 1.922496480229604e-07, 0.03751857137598318, -0.002502190709845202, -6.509826143199113e-06, 0.03364479107221002, 0.0807579509706507, -0.0017192561495253307, -0.000909771406807081, -0.0015761008273510904, 0.06199411335353473, 7.792624870566256e-06, 1.0756068275015736e-05, -0.0001193402643357173, -0.0016238409971062475, -3.1186593826643534e-05, 0.08196686594268496, 9.278839615312733e-07, 0.02897199583990937, 1.0885236198501121e-05, -0.00019429881069767612, 3.2871902683031636e-06, 0.023690278657604633, 8.557647635737622e-06, -0.0017667401073523435, 7.630983599570356e-06, 0.06881290397321826, 0.06551918999587059, -0.0021548288421496787, 0.013810407330902556, -7.396684131510267e-05, -0.002363277236350318, 0.034603485095254245, -0.00031580995158641254, -0.000358139896049816, -0.0005072927054517898, -0.0024738119586286025, -0.0002769824642020327, 0.026281708138255495, -0.0004284684074119294, -0.0023131700220996028, -0.0020086403684454724, 7.749770595358078e-08, -0.0009376672646191548, 0.03269348085846506, 0.038501430413861934, -0.002243703505338492, 0.0015056537011587817, 2.9463235340704388e-08, 0.015175332356763542, 0.0046450441666391834, 0.06801353228963597, -0.0010312018065974904, -0.0022062176158428814, 3.031280692631285e-07, 0.010075793939417774, 9.199298196946883e-06, -1.2072207088245197e-05, -0.0005948385597234552, 0.06636600923202082, 0.04948258440617524, 1.05865566153314e-05, -1.875783517136941e-05, -0.00015376321007033492, 9.477681572350969e-08, 4.651889343061061e-06} of type must be a list in decimation stage 0" diff --git a/testing_archive/test_taps_not_nums.py b/testing_archive/test_taps_not_nums.py index 034c9fc..d76fd53 100644 --- a/testing_archive/test_taps_not_nums.py +++ b/testing_archive/test_taps_not_nums.py @@ -3,14 +3,15 @@ """ Experiment fault: Decimation stage filter taps not numbers -Expected exception: - Filter tap .* is not numeric in decimation stage .* """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype -from experiment_prototype.decimation_scheme.decimation_scheme import \ +from experiment_prototype.experiment_utils.decimation_scheme import \ DecimationScheme, DecimationStage, create_firwin_filter_by_attenuation +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from experiment_prototype.experiment_exception import ExperimentException + class TestExperiment(ExperimentPrototype): @@ -64,5 +65,10 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": decimation_scheme, } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ExperimentException, "Filter tap 1.525146324717017e-08 is not numeric in decimation stage 0" diff --git a/testing_archive/test_tau_dne.py b/testing_archive/test_tau_dne.py index 0275d2e..84cc484 100644 --- a/testing_archive/test_tau_dne.py +++ b/testing_archive/test_tau_dne.py @@ -3,12 +3,11 @@ """ Experiment fault: tau_spacing not specified -Expected exception: - Slice must specify tau_spacing in us that must be an integer """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme class TestExperiment(ExperimentPrototype): @@ -42,5 +41,10 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return TypeError, "__init__\(\) missing 1 required positional argument: 'tau_spacing'" diff --git a/testing_archive/test_tau_not_int.py b/testing_archive/test_tau_not_int.py index b6d47d6..005f429 100644 --- a/testing_archive/test_tau_not_int.py +++ b/testing_archive/test_tau_not_int.py @@ -3,12 +3,12 @@ """ Experiment fault: tau_spacing not an integer -Expected exception: - Slice must specify tau_spacing in us that must be an integer """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -42,5 +42,11 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "tau_spacing\n" \ + " value is not a valid integer \(type=type_error.integer\)" diff --git a/testing_archive/test_tau_not_multiple.py b/testing_archive/test_tau_not_multiple.py index b3fad06..1465067 100644 --- a/testing_archive/test_tau_not_multiple.py +++ b/testing_archive/test_tau_not_multiple.py @@ -3,13 +3,12 @@ """ Experiment fault: tau_spacing not multiple of output rx sampling period -Expected exception: - Slice .* correlation lags will be off because tau_spacing .* us is not a multiple of the output - rx sampling period \(1\/output_rx_rate .* Hz\). """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -43,5 +42,13 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "tau_spacing\n" \ + " Slice 0 correlation lags will be off because tau_spacing 2407 us is not a " \ + "multiple of the output rx sampling period \(1/output_rx_rate " \ + "3333.3333333333335 Hz\). \(type=value_error\)" diff --git a/testing_archive/test_tau_too_small.py b/testing_archive/test_tau_too_small.py index 05c4093..76d0184 100644 --- a/testing_archive/test_tau_too_small.py +++ b/testing_archive/test_tau_too_small.py @@ -2,13 +2,14 @@ """ Experiment fault: - tau_spacing too smal -Expected exception: - Slice .* multi-pulse increment too small + tau_spacing too small """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError + class TestExperiment(ExperimentPrototype): @@ -41,5 +42,12 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "tau_spacing\n" \ + " ensure this value is greater than or equal to 1.0 " \ + "\(type=value_error.number.not_ge; limit_value=1.0\)" diff --git a/testing_archive/test_too_many_dm_stages.py b/testing_archive/test_too_many_dm_stages.py index 899a5ed..44f5fbc 100644 --- a/testing_archive/test_too_many_dm_stages.py +++ b/testing_archive/test_too_many_dm_stages.py @@ -3,14 +3,14 @@ """ Experiment fault: Too many decimation stages -Expected exception: - Number of decimation stages .* is greater than max available .* """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype -from experiment_prototype.decimation_scheme.decimation_scheme import \ +from experiment_prototype.experiment_utils.decimation_scheme import \ DecimationScheme, DecimationStage, create_firwin_filter_by_attenuation +from experiment_prototype.experiment_exception import ExperimentException + class TestExperiment(ExperimentPrototype): @@ -64,7 +64,12 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": decimation_scheme, } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ExperimentException, "Number of decimation stages \(7\) is greater than max available 6" diff --git a/testing_archive/test_too_many_int_antennas.py b/testing_archive/test_too_many_int_antennas.py index 03e384a..b45ca8e 100644 --- a/testing_archive/test_too_many_int_antennas.py +++ b/testing_archive/test_too_many_int_antennas.py @@ -3,12 +3,12 @@ """ Experiment fault: rx_int_antennas specifies too many channels -Expected exception: - Slice .* has too many RX interferometer antenna channels .* greater than config .* """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -42,6 +42,13 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs - "rx_int_antennas": [0,1,2,3,4] ### One too many antennas, should fail + "rx_int_antennas": [0,1,2,3,4], ### One too many antennas, should fail + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "rx_int_antennas\n" \ + " ensure this value has at most 4 items " \ + "\(type=value_error.list.max_items; limit_value=4\)" diff --git a/testing_archive/test_too_many_rx_antennas.py b/testing_archive/test_too_many_rx_antennas.py index 070df74..bab317b 100644 --- a/testing_archive/test_too_many_rx_antennas.py +++ b/testing_archive/test_too_many_rx_antennas.py @@ -3,12 +3,12 @@ """ Experiment fault: rx_main_antennas specifies too many channels -Expected exception: - Slice .* has too many main RX antenna channels .* greater than config .* """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -42,6 +42,12 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs - "rx_main_antennas": [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] ### One too many antennas, should fail + "rx_main_antennas": [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16], ### One too many antennas, should fail + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "ensure this value has at most 16 items " \ + "\(type=value_error.list.max_items; limit_value=16\)" diff --git a/testing_archive/test_too_many_tx_antennas.py b/testing_archive/test_too_many_tx_antennas.py index cbc77f8..5e63c06 100644 --- a/testing_archive/test_too_many_tx_antennas.py +++ b/testing_archive/test_too_many_tx_antennas.py @@ -3,12 +3,12 @@ """ Experiment fault: tx_antennas specifies too many channels -Expected exception: - Slice .* has too many main TX antenna channels .* greater than config .* """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -42,6 +42,12 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs - "tx_antennas": [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] ### One too many antennas, should fail + "tx_antennas": [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16], ### One too many antennas, should fail + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "ensure this value has at most 16 items " \ + "\(type=value_error.list.max_items; limit_value=16\)" diff --git a/testing_archive/test_two_classes.py b/testing_archive/test_two_classes.py index c39e742..0d68cbd 100644 --- a/testing_archive/test_two_classes.py +++ b/testing_archive/test_two_classes.py @@ -3,12 +3,13 @@ """ Experiment fault: File contains two classes -Expected exception: - You have more than one experiment class in your experiment file - exiting """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from experiment_prototype.experiment_exception import ExperimentException + class TestExperiment2(ExperimentPrototype): ### First class @@ -41,9 +42,14 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + @classmethod + def error_message(cls): + return "pass" + class TestExperiment(ExperimentPrototype): ### Second class @@ -76,5 +82,10 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ExperimentException, "You have more than one experiment class in your experiment file - exiting" diff --git a/testing_archive/test_tx_antenna_dne.py b/testing_archive/test_tx_antenna_dne.py index bc9d921..05c59d7 100644 --- a/testing_archive/test_tx_antenna_dne.py +++ b/testing_archive/test_tx_antenna_dne.py @@ -3,12 +3,12 @@ """ Experiment fault: tx_antenna specifies antenna that doesn't exist -Expected exception: - Slice .* specifies TX main array antenna numbers over config max .* """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -42,6 +42,11 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs - "tx_antennas": [0,1,2,3,4,5,23] ### antenna 23 doesn't exist, should fail + "tx_antennas": [0,1,2,3,4,5,23], ### antenna 23 doesn't exist, should fail + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "ensure this value is less than 16 \(type=value_error.number.not_lt; limit_value=16\)" diff --git a/testing_archive/test_tx_antenna_dups.py b/testing_archive/test_tx_antenna_dups.py index 779347f..af20d8d 100644 --- a/testing_archive/test_tx_antenna_dups.py +++ b/testing_archive/test_tx_antenna_dups.py @@ -3,12 +3,12 @@ """ Experiment fault: tx_antennas has duplicate values -Expected exception: - Slice .* TX main antennas has duplicate antennas """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -42,6 +42,13 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs - "tx_antennas": [0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15] ### antenna 0 is duplicated, should fail + "tx_antennas": [0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15], ### antenna 0 is duplicated, should fail + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "tx_antennas\n" \ + " ensure this value has at most 16 items \(type=value_error.list.max_items; " \ + "limit_value=16\)" diff --git a/testing_archive/test_tx_antenna_invalid.py b/testing_archive/test_tx_antenna_invalid.py new file mode 100644 index 0000000..e133046 --- /dev/null +++ b/testing_archive/test_tx_antenna_invalid.py @@ -0,0 +1,45 @@ +#!/usr/bin/python + +""" +Experiment fault: + tx_antennas has invalid values (above and below the allowed range) +""" + +import borealis_experiments.superdarn_common_fields as scf +from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError + + +class TestExperiment(ExperimentPrototype): + + def __init__(self): + cpid = 1 + super().__init__(cpid) + + beams_to_use = scf.STD_16_FORWARD_BEAM_ORDER + num_ranges = scf.STD_NUM_RANGES + + slice_1 = { # slice_id = 0, there is only one slice. + "pulse_sequence": scf.SEQUENCE_7P, + "tau_spacing": scf.TAU_SPACING_7P, + "pulse_len": scf.PULSE_LEN_45KM, + "num_ranges": num_ranges, + "first_range": scf.STD_FIRST_RANGE, + "intt": 3500, # duration of an integration, in ms + "beam_angle": scf.STD_16_BEAM_ANGLE, + "rx_beam_order": beams_to_use, + "tx_beam_order": beams_to_use, + "freq": scf.COMMON_MODE_FREQ_1, #kHz + "tx_antennas": [-1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16], ### antenna -1 and 16 are out of range + "decimation_scheme": create_default_scheme(), + } + self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "tx_antennas -> 0\n" \ + " ensure this value is greater than or equal to 0 \(type=value_error.number.not_ge; " \ + "limit_value=0\)\n" \ + "tx_antennas -> 15\n" \ + " ensure this value is less than 16 \(type=value_error.number.not_lt; limit_value=16\)" diff --git a/testing_archive/test_tx_antenna_pattern_dim_mismatch.py b/testing_archive/test_tx_antenna_pattern_dim_mismatch.py index 2853b22..3018c8d 100644 --- a/testing_archive/test_tx_antenna_pattern_dim_mismatch.py +++ b/testing_archive/test_tx_antenna_pattern_dim_mismatch.py @@ -3,14 +3,15 @@ """ Experiment fault: tx_antenna_pattern dimension mismatch with number of main antennas -Expected exception: - Slice .* tx antenna pattern return 2nd dimension \(.*\) must be equal to number of main antennas \(.*\) """ import numpy as np import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError + ### pattern second dimension is not equal to num_main_antennas, this will fail in check_slice() ### of ExperimentPrototype @@ -46,8 +47,6 @@ def __init__(self, **kwargs): if 'freq' in kwargs.keys(): freq = kwargs['freq'] - self.printing('Frequency set to {}'.format(freq)) - self.add_slice({ # slice_id = 0, there is only one slice. "pulse_sequence": scf.SEQUENCE_7P, "tau_spacing": scf.TAU_SPACING_7P, @@ -63,4 +62,10 @@ def __init__(self, **kwargs): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), }) + + @classmethod + def error_message(cls): + return ValidationError, \ + "Slice 0 tx antenna pattern return 2nd dimension \(15\) must be equal to number of main antennas \(16\)" diff --git a/testing_archive/test_tx_antenna_pattern_magnitude.py b/testing_archive/test_tx_antenna_pattern_magnitude.py index 88131a5..8718baf 100644 --- a/testing_archive/test_tx_antenna_pattern_magnitude.py +++ b/testing_archive/test_tx_antenna_pattern_magnitude.py @@ -3,14 +3,15 @@ """ Experiment fault: tx_antenna_pattern magnitude too large -Expected exception: - Slice .* tx antenna pattern return must not have any values with a magnitude greater than 1 """ import numpy as np import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError + ### One of the pattern's elements' magnitudes is > 1.0, this will fail in check_slice() ### of ExperimentPrototype @@ -47,8 +48,6 @@ def __init__(self, **kwargs): if 'freq' in kwargs.keys(): freq = kwargs['freq'] - self.printing('Frequency set to {}'.format(freq)) - self.add_slice({ # slice_id = 0, there is only one slice. "pulse_sequence": scf.SEQUENCE_7P, "tau_spacing": scf.TAU_SPACING_7P, @@ -64,5 +63,10 @@ def __init__(self, **kwargs): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), }) + @classmethod + def error_message(cls): + return ValidationError, \ + "Slice 0 tx antenna pattern return must not have any values with a magnitude greater than 1" diff --git a/testing_archive/test_tx_antenna_pattern_not_2d.py b/testing_archive/test_tx_antenna_pattern_not_2d.py index da6db95..7b7fdf6 100644 --- a/testing_archive/test_tx_antenna_pattern_not_2d.py +++ b/testing_archive/test_tx_antenna_pattern_not_2d.py @@ -3,13 +3,14 @@ """ Experiment fault: tx_antenna_pattern not 2d -Expected exception: - Slice .* tx antenna pattern return shape .* must be 2-dimensional """ import numpy as np import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError + ### pattern returned is only one dimensional, but is required to be 2-dimensional ### this will fail in check_slice() of ExperimentPrototype @@ -45,8 +46,6 @@ def __init__(self, **kwargs): if 'freq' in kwargs.keys(): freq = kwargs['freq'] - self.printing('Frequency set to {}'.format(freq)) - self.add_slice({ # slice_id = 0, there is only one slice. "pulse_sequence": scf.SEQUENCE_7P, "tau_spacing": scf.TAU_SPACING_7P, @@ -62,4 +61,9 @@ def __init__(self, **kwargs): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), }) + + @classmethod + def error_message(cls): + return ValidationError, "Slice 0 tx antenna pattern return shape \(16,\) must be 2-dimensional" diff --git a/testing_archive/test_tx_antenna_pattern_not_callable.py b/testing_archive/test_tx_antenna_pattern_not_callable.py index 789fe3d..1518f4d 100644 --- a/testing_archive/test_tx_antenna_pattern_not_callable.py +++ b/testing_archive/test_tx_antenna_pattern_not_callable.py @@ -3,17 +3,17 @@ """ Experiment fault: tx_antenna_pattern not a function -Expected exception: - Slice .* tx antenna pattern must be a function """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError + ### tx_antenna_pattern is not a callable function. ### this will fail in check_slice() of ExperimentPrototype - class TxAntennaPatternTest(ExperimentPrototype): def __init__(self, **kwargs): @@ -40,8 +40,6 @@ def __init__(self, **kwargs): if 'freq' in kwargs.keys(): freq = kwargs['freq'] - self.printing('Frequency set to {}'.format(freq)) - self.add_slice({ # slice_id = 0, there is only one slice. "pulse_sequence": scf.SEQUENCE_7P, "tau_spacing": scf.TAU_SPACING_7P, @@ -57,4 +55,9 @@ def __init__(self, **kwargs): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), }) + + @classmethod + def error_message(cls): + return ValidationError, "pattern is not callable \(type=type_error.callable; value=pattern\)" diff --git a/testing_archive/test_tx_antenna_pattern_not_numpy.py b/testing_archive/test_tx_antenna_pattern_not_numpy.py index 3cf37cd..d01da1d 100644 --- a/testing_archive/test_tx_antenna_pattern_not_numpy.py +++ b/testing_archive/test_tx_antenna_pattern_not_numpy.py @@ -3,12 +3,13 @@ """ Experiment fault: tx_antenna_pattern returns non-numpy array -Expected exception: - Slice .* tx antenna pattern return is not a numpy array """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError + ### pattern returned by tx_antenna_pattern is not a numpy array, but a list ### this will fail in check_slice() of ExperimentPrototype @@ -44,8 +45,6 @@ def __init__(self, **kwargs): if 'freq' in kwargs.keys(): freq = kwargs['freq'] - self.printing('Frequency set to {}'.format(freq)) - self.add_slice({ # slice_id = 0, there is only one slice. "pulse_sequence": scf.SEQUENCE_7P, "tau_spacing": scf.TAU_SPACING_7P, @@ -61,4 +60,9 @@ def __init__(self, **kwargs): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), }) + + @classmethod + def error_message(cls): + return ValidationError, "Slice 0 tx antenna pattern return is not a numpy array" diff --git a/testing_archive/test_tx_beam_order_dne.py b/testing_archive/test_tx_beam_order_dne.py index d42be45..ea25104 100644 --- a/testing_archive/test_tx_beam_order_dne.py +++ b/testing_archive/test_tx_beam_order_dne.py @@ -3,14 +3,15 @@ """ Experiment fault: tx_beam_order not specified alongside tx_antenna_pattern -Expected exception: - tx_beam_order must be specified if tx_antenna_pattern specified. Slice .* """ import numpy as np import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError + def tx_antenna_pattern(tx_freq_khz, tx_antennas, antenna_spacing): """tx_antenna_pattern function for boresight transmission.""" @@ -51,5 +52,10 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "rxonly specified as False but tx_beam_order not given. Slice: 0" diff --git a/testing_archive/test_tx_beam_order_list_not_ints.py b/testing_archive/test_tx_beam_order_list_not_ints.py index 411e3cb..1909948 100644 --- a/testing_archive/test_tx_beam_order_list_not_ints.py +++ b/testing_archive/test_tx_beam_order_list_not_ints.py @@ -3,13 +3,12 @@ """ Experiment fault: tx_beam_order not integer values in list -Expected exception: - tx_beam_order must be a list of ints corresponding to the order of the angles in the beam_angle - list or an array of phases in the tx_antenna_pattern return. Slice: .* """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -43,5 +42,16 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "3 validation errors for ExperimentSlice\n" \ + "tx_beam_order -> 0\n" \ + " value is not a valid integer \(type=type_error.integer\)\n" \ + "tx_beam_order -> 1\n" \ + " value is not a valid integer \(type=type_error.integer\)\n" \ + "tx_beam_order -> 2\n" \ + " value is not a valid integer \(type=type_error.integer\)" diff --git a/testing_archive/test_tx_beam_order_listnum_too_high.py b/testing_archive/test_tx_beam_order_listnum_too_high.py index d2b8624..ea68130 100644 --- a/testing_archive/test_tx_beam_order_listnum_too_high.py +++ b/testing_archive/test_tx_beam_order_listnum_too_high.py @@ -3,12 +3,12 @@ """ Experiment fault: tx_beam_order specifies beam that doesn't exist -Expected exception: - Beam number .* in tx_beam_order could not index in beam_angle list of length .*. Slice: .* """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -42,5 +42,11 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, \ + "Beam number 22 in tx_beam_order could not index in beam_angle list of length 16. Slice: 0" diff --git a/testing_archive/test_tx_beam_order_mismatch_tx_antenna_pattern.py b/testing_archive/test_tx_beam_order_mismatch_tx_antenna_pattern.py new file mode 100644 index 0000000..d7fe1d3 --- /dev/null +++ b/testing_archive/test_tx_beam_order_mismatch_tx_antenna_pattern.py @@ -0,0 +1,60 @@ +#!/usr/bin/python + +""" +Experiment fault: + tx_beam_order has a value greater than the first dimension of tx_antenna_pattern return +""" + +import numpy as np + +import borealis_experiments.superdarn_common_fields as scf +from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError + + +### pattern second dimension is not equal to num_main_antennas, this will fail in check_slice() +### of ExperimentPrototype +def tx_antenna_pattern(tx_freq_khz, tx_antennas, antenna_spacing): + """Sets the amplitude and phase weighting for each tx antenna""" + pattern = np.array([1.0 for _ in range(len(tx_antennas))]).reshape((1, len(tx_antennas))) + return pattern + + +class TxAntennaPatternTest(ExperimentPrototype): + + def __init__(self): + """ + kwargs: + + freq: int + + """ + cpid = 12345 + super().__init__(cpid) + + beams_to_use = scf.STD_16_FORWARD_BEAM_ORDER + num_ranges = scf.STD_NUM_RANGES + + # default frequency set here + freq = scf.COMMON_MODE_FREQ_1 + + self.add_slice({ # slice_id = 0, there is only one slice. + "pulse_sequence": scf.SEQUENCE_7P, + "tau_spacing": scf.TAU_SPACING_7P, + "pulse_len": scf.PULSE_LEN_45KM, + "num_ranges": num_ranges, + "first_range": scf.STD_FIRST_RANGE, + "intt": scf.INTT_7P, # duration of an integration, in ms + "tx_antenna_pattern": tx_antenna_pattern, + "beam_angle": scf.STD_16_BEAM_ANGLE, + "rx_beam_order": [beams_to_use, beams_to_use], + "tx_beam_order": [0, 1], # tx_antenna_pattern returns array with only one row + "freq": freq, # kHz + "decimation_scheme": create_default_scheme(), + }) + + @classmethod + def error_message(cls): + return ValidationError, "tx_beam_order\n" \ + " Slice 0 scan tx beam number 1 DNE \(type=value_error\)" diff --git a/testing_archive/test_tx_beam_order_not_list.py b/testing_archive/test_tx_beam_order_not_list.py index 80cf3a7..39a8266 100644 --- a/testing_archive/test_tx_beam_order_not_list.py +++ b/testing_archive/test_tx_beam_order_not_list.py @@ -3,13 +3,12 @@ """ Experiment fault: tx_beam_order not a list -Expected exception: - tx_beam_order must be a list of ints corresponding to the order of the angles in the beam_angle - list or an array of phases in the tx_antenna_pattern return. Slice: .* """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -43,5 +42,11 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "tx_beam_order\n" \ + " value is not a valid list \(type=type_error.list\)" diff --git a/testing_archive/test_tx_beam_order_not_same_len_as_rx.py b/testing_archive/test_tx_beam_order_not_same_len_as_rx.py index 7da14f6..6c3c15c 100644 --- a/testing_archive/test_tx_beam_order_not_same_len_as_rx.py +++ b/testing_archive/test_tx_beam_order_not_same_len_as_rx.py @@ -3,12 +3,12 @@ """ Experiment fault: tx_beam_order different length from rx_beam_order -Expected exception: - tx_beam_order does not have same length as rx_beam_order. Slice: .* """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -42,5 +42,10 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } - self.add_slice(slice_1) \ No newline at end of file + self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, "tx_beam_order does not have same length as rx_beam_order. Slice: 0" diff --git a/testing_archive/test_txbw_not_divisible.py b/testing_archive/test_txbw_not_divisible.py index eac786f..aedffc9 100644 --- a/testing_archive/test_txbw_not_divisible.py +++ b/testing_archive/test_txbw_not_divisible.py @@ -3,12 +3,12 @@ """ Experiment fault: tx_bandwidth not divisor of usrp clock rate -Expected exception: - Experiment's transmit bandwidth .* is not possible as it must be an integer divisor of USRP master clock rate """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from experiment_prototype.experiment_exception import ExperimentException class TestExperiment(ExperimentPrototype): @@ -44,5 +44,12 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ExperimentException, \ + "Experiment's transmit bandwidth 3141590.0 is not possible as it must be an integer divisor of USRP " \ + "master clock rate 100000000.0" diff --git a/testing_archive/test_txrate_high.py b/testing_archive/test_txrate_high.py index e6dfa76..07f2806 100644 --- a/testing_archive/test_txrate_high.py +++ b/testing_archive/test_txrate_high.py @@ -3,12 +3,12 @@ """ Experiment fault: tx_bandwidth too high -Expected exception: - Experiment's transmit bandwidth is too large """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from experiment_prototype.experiment_exception import ExperimentException class TestExperiment(ExperimentPrototype): @@ -44,5 +44,11 @@ def __init__(self): "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ExperimentException, \ + "Experiment's transmit bandwidth is too large: 25000000.0 greater than max 5000000.0." diff --git a/testing_archive/test_unused_param.py b/testing_archive/test_unused_param.py index d579999..432c69b 100644 --- a/testing_archive/test_unused_param.py +++ b/testing_archive/test_unused_param.py @@ -3,12 +3,12 @@ """ Experiment fault: Slice has specified unused parameter -Expected exception: - Slice .* has a parameter that is not used: .* = .* """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from experiment_prototype.experiment_exception import ExperimentException class TestExperiment(ExperimentPrototype): @@ -43,5 +43,10 @@ def __init__(self): "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs "UNUSED": "it's a me-a, Mario", ### Unused param, should fail + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return TypeError, "__init__\(\) got an unexpected keyword argument 'UNUSED'" diff --git a/testing_archive/test_wait_for_first_scanbound_type.py b/testing_archive/test_wait_for_first_scanbound_type.py index 211c3e8..b26a995 100644 --- a/testing_archive/test_wait_for_first_scanbound_type.py +++ b/testing_archive/test_wait_for_first_scanbound_type.py @@ -3,12 +3,13 @@ """ Experiment fault: wait_for_first_scanbound not a boolean value -Expected exception: - Slice .* wait_for_first_scanbound must be True or False, got .* instead """ import borealis_experiments.superdarn_common_fields as scf from experiment_prototype.experiment_prototype import ExperimentPrototype +from experiment_prototype.experiment_utils.decimation_scheme import create_default_scheme +from experiment_prototype.experiment_exception import ExperimentException +from pydantic import ValidationError class TestExperiment(ExperimentPrototype): @@ -43,5 +44,13 @@ def __init__(self): "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs "wait_for_first_scanbound": 0, ### Not boolean, should fail + "decimation_scheme": create_default_scheme(), } self.add_slice(slice_1) + + @classmethod + def error_message(cls): + return ValidationError, \ + '1 validation error for ExperimentSlice\n' \ + 'wait_for_first_scanbound\n' \ + ' value is not a valid boolean \(type=value_error.strictbool\)' diff --git a/twofsound.py b/twofsound.py index 29a84a2..473bd02 100644 --- a/twofsound.py +++ b/twofsound.py @@ -50,7 +50,7 @@ def __init__(self, **kwargs): "rx_beam_order": beams_to_use, "tx_beam_order": beams_to_use, "scanbound" : scf.easy_scanbound(scf.INTT_7P, beams_to_use), - "freq" : tx_freq_1, #kHz + "freq" : tx_freq_1, # kHz "acf": True, "xcf": True, # cross-correlation processing "acfint": True, # interferometer acfs diff --git a/widebeam_2tx.py b/widebeam_2tx.py index 1455fdb..a190cc7 100644 --- a/widebeam_2tx.py +++ b/widebeam_2tx.py @@ -41,7 +41,7 @@ def __init__(self, **kwargs): if 'freq' in kwargs.keys(): freq = kwargs['freq'] - self.printing('Frequency set to {}'.format(freq)) + print('Frequency set to {}'.format(freq)) # TODO: Log self.add_slice({ # slice_id = 0, there is only one slice. "pulse_sequence": scf.SEQUENCE_7P, diff --git a/widebeam_3tx.py b/widebeam_3tx.py index 37537ed..7604742 100644 --- a/widebeam_3tx.py +++ b/widebeam_3tx.py @@ -41,7 +41,7 @@ def __init__(self, **kwargs): if 'freq' in kwargs.keys(): freq = kwargs['freq'] - self.printing('Frequency set to {}'.format(freq)) + print('Frequency set to {}'.format(freq)) # TODO: Log self.add_slice({ # slice_id = 0, there is only one slice. "pulse_sequence": scf.SEQUENCE_7P,