Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
183 changes: 183 additions & 0 deletions tools/test_testing_case_inp_params_to_dict.py
Original file line number Diff line number Diff line change
@@ -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)
68 changes: 68 additions & 0 deletions tools/testing_case_inp_params_to_dict.py
Original file line number Diff line number Diff line change
@@ -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