diff --git a/tools/test_testing_case_inp_params_to_dict.py b/tools/test_testing_case_inp_params_to_dict.py new file mode 100644 index 0000000..299dc35 --- /dev/null +++ b/tools/test_testing_case_inp_params_to_dict.py @@ -0,0 +1,183 @@ +import numpy as np +import pytest +import testing_case_inp_params_to_dict as tcipd + +@pytest.mark.parametrize("fluences, duty_cycles, nums_pulses, exp_pulse_lengths, exp_abs_dwell_times", [ + (np.array([5, 10]), + np.array([1, 0.2]), + np.array([2, 5]), + np.array([[5/2, 5/5], + [10/2, 10/5]]), + np.array([ + [[0, 0], [0, 0]], + [[(0.8/0.2)*5/2, (0.8/0.2)*5/5], [(0.8/0.2)*10/2, (0.8/0.2)*10/5]] + ]) + ) + ]) + +def test_calc_testing_simple_ph_time_params(fluences, duty_cycles, nums_pulses, exp_pulse_lengths, exp_abs_dwell_times): + obs_pulse_lengths, obs_abs_dwell_times = tcipd.calc_testing_simple_ph_time_params(fluences, duty_cycles, nums_pulses) + assert np.array_equal(obs_pulse_lengths, exp_pulse_lengths) + assert np.array_equal(obs_abs_dwell_times, exp_abs_dwell_times) + +@pytest.mark.parametrize("flux_filepaths, pulse_lengths, nums_pulses, abs_dwell_times, time_unit, exp_testing_pe_array", [ + (np.array(['../iter', '../frascati']), + np.array([[5, 6], [1, 2]]), + np.array([2, 4]), + np.array([[[0.3, 0.2], [0.1, 1]], [[0.5, 0.1], [0.4, 0.9]]]), + 'y', + np.array([ + [[ + [{'type': 'pulse_entry', + 'pulse_length': 5, + 'pulse_length_unit': 'y', + 'flux_filepath': '../iter', + 'flux_norm': 1.0, + 'pulse_history': [2, 0.3, 'y'], + 'delay_dur': 0.0, + 'delay_dur_unit': 'y'}, + + {'type': 'pulse_entry', + 'pulse_length': 6, + 'pulse_length_unit': 'y', + 'flux_filepath': '../iter', + 'flux_norm': 1.0, + 'pulse_history': [4, 0.2, 'y'], + 'delay_dur': 0.0, + 'delay_dur_unit': 'y'}], + + [{'type': 'pulse_entry', + 'pulse_length': 1, + 'pulse_length_unit': 'y', + 'flux_filepath': '../iter', + 'flux_norm': 1.0, + 'pulse_history': [2, 0.1, 'y'], + 'delay_dur': 0.0, + 'delay_dur_unit': 'y'}, + + {'type': 'pulse_entry', + 'pulse_length': 2, + 'pulse_length_unit': 'y', + 'flux_filepath': '../iter', + 'flux_norm': 1.0, + 'pulse_history': [4, 1, 'y'], + 'delay_dur': 0.0, + 'delay_dur_unit': 'y'}]], + + [[{'type': 'pulse_entry', + 'pulse_length': 5, + 'pulse_length_unit': 'y', + 'flux_filepath': '../iter', + 'flux_norm': 1.0, + 'pulse_history': [2, 0.5, 'y'], + 'delay_dur': 0.0, + 'delay_dur_unit': 'y'}, + + {'type': 'pulse_entry', + 'pulse_length': 6, + 'pulse_length_unit': 'y', + 'flux_filepath': '../iter', + 'flux_norm': 1.0, + 'pulse_history': [4, 0.1, 'y'], + 'delay_dur': 0.0, + 'delay_dur_unit': 'y'}], + + [{'type': 'pulse_entry', + 'pulse_length': 1, + 'pulse_length_unit': 'y', + 'flux_filepath': '../iter', + 'flux_norm': 1.0, + 'pulse_history': [2, 0.4, 'y'], + 'delay_dur': 0.0, + 'delay_dur_unit': 'y'}, + + {'type': 'pulse_entry', + 'pulse_length': 2, + 'pulse_length_unit': 'y', + 'flux_filepath': '../iter', + 'flux_norm': 1.0, + 'pulse_history': [4, 0.9, 'y'], + 'delay_dur': 0.0, + 'delay_dur_unit': 'y'}]]], + + + + [[[{'type': 'pulse_entry', + 'pulse_length': 5, + 'pulse_length_unit': 'y', + 'flux_filepath': '../frascati', + 'flux_norm': 1.0, + 'pulse_history': [2, 0.3, 'y'], + 'delay_dur': 0.0, + 'delay_dur_unit': 'y'}, + + {'type': 'pulse_entry', + 'pulse_length': 6, + 'pulse_length_unit': 'y', + 'flux_filepath': '../frascati', + 'flux_norm': 1.0, + 'pulse_history': [4, 0.2, 'y'], + 'delay_dur': 0.0, + 'delay_dur_unit': 'y'}], + + [{'type': 'pulse_entry', + 'pulse_length': 1, + 'pulse_length_unit': 'y', + 'flux_filepath': '../frascati', + 'flux_norm': 1.0, + 'pulse_history': [2, 0.1, 'y'], + 'delay_dur': 0.0, + 'delay_dur_unit': 'y'}, + + {'type': 'pulse_entry', + 'pulse_length': 2, + 'pulse_length_unit': 'y', + 'flux_filepath': '../frascati', + 'flux_norm': 1.0, + 'pulse_history': [4, 1, 'y'], + 'delay_dur': 0.0, + 'delay_dur_unit': 'y'}]], + + [[{'type': 'pulse_entry', + 'pulse_length': 5, + 'pulse_length_unit': 'y', + 'flux_filepath': '../frascati', + 'flux_norm': 1.0, + 'pulse_history': [2, 0.5, 'y'], + 'delay_dur': 0.0, + 'delay_dur_unit': 'y'}, + + {'type': 'pulse_entry', + 'pulse_length': 6, + 'pulse_length_unit': 'y', + 'flux_filepath': '../frascati', + 'flux_norm': 1.0, + 'pulse_history': [4, 0.1, 'y'], + 'delay_dur': 0.0, + 'delay_dur_unit': 'y'}], + + [{'type': 'pulse_entry', + 'pulse_length': 1, + 'pulse_length_unit': 'y', + 'flux_filepath': '../frascati', + 'flux_norm': 1.0, + 'pulse_history': [2, 0.4, 'y'], + 'delay_dur': 0.0, + 'delay_dur_unit': 'y'}, + + {'type': 'pulse_entry', + 'pulse_length': 2, + 'pulse_length_unit': 'y', + 'flux_filepath': '../frascati', + 'flux_norm': 1.0, + 'pulse_history': [4, 0.9, 'y'], + 'delay_dur': 0.0, + 'delay_dur_unit': 'y'}]]] + + ]) + ) + ]) + +def test_populate_simple_child_dict(flux_filepaths, pulse_lengths, nums_pulses, abs_dwell_times, time_unit, exp_testing_pe_array): + obs_testing_pe_array = tcipd.populate_simple_child_dict(flux_filepaths, pulse_lengths, nums_pulses, abs_dwell_times, time_unit) + assert np.array_equal(exp_testing_pe_array, obs_testing_pe_array) \ No newline at end of file diff --git a/tools/testing_case_inp_params_to_dict.py b/tools/testing_case_inp_params_to_dict.py new file mode 100644 index 0000000..430333c --- /dev/null +++ b/tools/testing_case_inp_params_to_dict.py @@ -0,0 +1,68 @@ +import numpy as np +from itertools import product + +''' +The following dictionary (child_dict) is the representative data structure used to +store and access pulse history-related information for ALARA simulations. This script +populates this dictionary using user-specified information about the pulse history. + +Because this script is intended to store information for the testing cases, +flux variation is introduced through duty cycles, and the flux normalization +factor is taken to be 1. + + {'type': 'pulse_entry', + 'pulse_length': (float), + 'pulse_length_unit': (str), + 'flux_filepath' : (str), + 'flux_norm' : (float), + 'pulse_history': (iterable of (int, float, str)), + 'delay_dur' : (float), + 'delay_dur_unit': (str) + } +''' +def calc_testing_simple_ph_time_params(fluences, duty_cycles, nums_pulses): + ''' + Calculates the pulse lengths and pulse dwell times given a set of fluences/on-times, + duty cycles, and pulse numbers. These parameters are calculated for a single-level + pulse history. + input: + :param: fluences: iterable of times (float) where the system experiences nonzero flux + :param: duty_cycles: iterable of duty cycles (float), defined as pulse length / (pulse length + dwell time) + For each value, 0 < duty cycle <= 1 + :param: nums_pulses: iterable of the number (int) of pulses the on-time is divided into + + output: + pulse_lengths: 2D numpy array of shape (len(fluences), len(nums_pulses)) + abs_dwell_times: 3D numpy array of shape (len(duty_cycles), len(fluences), len(nums_pulses)) + ''' + pulse_lengths = np.outer(fluences, 1/nums_pulses) + rel_dwell_times = (1 - duty_cycles) / duty_cycles + abs_dwell_times = np.multiply.outer(rel_dwell_times, pulse_lengths) + return pulse_lengths, abs_dwell_times + +def populate_simple_child_dict(flux_filepaths, pulse_lengths, nums_pulses, abs_dwell_times, time_unit): + ''' + Populates the child dictionary structure using the pulse lengths and dwell times calculated in + calc_testing_simple_ph_time_params(). + input: + flux_filepaths: iterable of paths (str) to files containing flux data + time_unit: unit (str) of fluence time + + output: + testing_pe_array: 4D numpy array of shape (len(flux_filepaths), len(duty_cycles), len(fluences), len(nums_pulses)) + ''' + testing_pe_array = np.empty((len(flux_filepaths),) + abs_dwell_times.shape, dtype=object) + for (flux_idx, flux_filepath), ((duty_cycle_idx, fluence_idx, num_pulse_idx), abs_dwell_time) in product( + enumerate(flux_filepaths), np.ndenumerate(abs_dwell_times) + ): + testing_pe_array[flux_idx, duty_cycle_idx, fluence_idx, num_pulse_idx] = { + 'type': 'pulse_entry', + 'pulse_length': pulse_lengths[fluence_idx, num_pulse_idx], + 'pulse_length_unit': time_unit, + 'flux_filepath' : flux_filepath, + 'flux_norm': 1.0, + 'pulse_history': [nums_pulses[num_pulse_idx], abs_dwell_time, time_unit], + 'delay_dur' : 0.0, + 'delay_dur_unit': time_unit + } + return testing_pe_array \ No newline at end of file