def test_H_sigma(self): _energy_min = 0.004 _energy_max = 1 _energy_step = 0.01 o_reso = Resonance(energy_min=_energy_min, energy_max=_energy_max, energy_step=_energy_step, database=self.database) _layer_1 = 'H2' _thickness_1 = 0.025 # mm _layer_2 = 'H' _thickness_2 = 0.01 _layer_3 = 'CH4' _thickness_3 = 0.01 _layer_4 = 'ZrH' _thickness_4 = 0.01 o_reso.add_layer(formula=_layer_1, thickness=_thickness_1) o_reso.add_layer(formula=_layer_2, thickness=_thickness_2) o_reso.add_layer(formula=_layer_3, thickness=_thickness_3) o_reso.add_layer(formula=_layer_4, thickness=_thickness_4) layer1_sigma = o_reso.stack_sigma[_layer_1]['H']['1-H']['sigma_b_raw'][ 0] layer2_sigma = o_reso.stack_sigma[_layer_2]['H']['1-H']['sigma_b_raw'][ 0] layer3_sigma = o_reso.stack_sigma[_layer_3]['H']['1-H']['sigma_b_raw'][ 0] layer4_sigma = o_reso.stack_sigma[_layer_4]['H']['1-H']['sigma_b_raw'][ 0] self.assertNotEqual(layer1_sigma, layer2_sigma) self.assertNotEqual(layer1_sigma, layer3_sigma) self.assertNotEqual(layer1_sigma, layer4_sigma) self.assertNotEqual(layer2_sigma, layer3_sigma) self.assertNotEqual(layer2_sigma, layer4_sigma) self.assertNotEqual(layer3_sigma, layer4_sigma)
def test_element_metadata_via_add_layer_initialization(self): """assert __element_metadata is correctly populated using add layer initialization""" o_reso = Resonance(database=self.database) # layer 1 layer1 = 'CoAg' thickness1 = 0.025 o_reso.add_layer(formula=layer1, thickness=thickness1) # layer 2 layer2 = 'Ag' thickness2 = 0.1 o_reso.add_layer(formula=layer2, thickness=thickness2) stack = o_reso.stack # molar mass co_mass_expected = 58.9332 ag_mass_expected = 107.8682 self.assertEqual(co_mass_expected, stack['CoAg']['Co']['molar_mass']['value']) self.assertEqual(ag_mass_expected, stack['CoAg']['Ag']['molar_mass']['value']) self.assertEqual(ag_mass_expected, stack['Ag']['Ag']['molar_mass']['value']) # density co_density_expected = 8.9 ag_density_expected = 10.5 self.assertEqual(co_density_expected, stack['CoAg']['Co']['density']['value']) self.assertEqual(ag_density_expected, stack['Ag']['Ag']['density']['value'])
def test_abundance(self): """assert""" o_reso = Resonance(database=self.database) o_reso.add_layer(formula='C', thickness=1) self.assertAlmostEqual( o_reso.stack['C']['C']['isotopes']['isotopic_ratio'][0], 0.9893, delta=0.0001) self.assertAlmostEqual( o_reso.stack['C']['C']['isotopes']['isotopic_ratio'][1], 0.0107, delta=0.0001)
def setUp(self): _energy_min = 1 _energy_max = 50 _energy_step = 0.1 _layer_1 = 'Co' _thickness_1 = 0.025 # mm o_reso = Resonance(energy_min=_energy_min, energy_max=_energy_max, energy_step=_energy_step, database=self.database) o_reso.add_layer(formula=_layer_1, thickness=_thickness_1) self.o_reso = o_reso
def test_duplicated_layer_name(self): o_reso = Resonance(database=self.database) # layer 1 layer1 = 'CoAg' thickness1 = 0.025 o_reso.add_layer(formula=layer1, thickness=thickness1) # Duplicated layer name layer2 = 'CoAg' thickness2 = 0.01 self.assertRaises(ValueError, o_reso.add_layer, formula=layer2, thickness=thickness2)
def _fill_iso_to_items(name, stack=None, database='ENDF_VII'): if '*' not in name: raise ValueError( "'*' is needed to retrieve all isotopes of '{}' ".format(name)) else: ele_name = name.replace('*', '') if stack is None: o_reso = Resonance(database=database) o_reso.add_layer(formula=ele_name, thickness=1) stack = o_reso.stack iso_list = stack[ele_name][ele_name]['isotopes']['list'] _path_to_iso = [] for _each_iso in iso_list: _path_to_iso.append(_shape_items(_each_iso)) return _path_to_iso
def test_layer_density_locked_if_defined_during_initialization_add_layer( self): """assert the layer density is locked if defined at the beginning using add_layer""" o_reso = Resonance(database=self.database) # layer 1 layer1 = 'CoAg' thickness1 = 0.025 density = 8.9 o_reso.add_layer(formula=layer1, thickness=thickness1, density=density) # layer 2 layer2 = 'Ag' thickness2 = 0.1 o_reso.add_layer(formula=layer2, thickness=thickness2) density_lock_before = 8.9 density_lock_after = o_reso.stack['CoAg']['density']['value'] self.assertEqual(density_lock_after, density_lock_before) density_unlock_expected = 10.5 density_unlock_after = o_reso.stack['Ag']['density']['value'] self.assertEqual(density_unlock_after, density_unlock_expected)
def test_adding_layer(self): """assert adding_layer works""" o_reso = Resonance(database=self.database) # layer 1 layer1 = 'CoAg' thickness1 = 0.025 o_reso.add_layer(formula=layer1, thickness=thickness1) # layer 2 layer2 = 'Ag' thickness2 = 0.1 density2 = 0.5 o_reso.add_layer(formula=layer2, thickness=thickness2, density=density2) returned_stack = o_reso.stack expected_stack = { 'CoAg': { 'elements': ['Co', 'Ag'], 'stoichiometric_ratio': [1, 1], 'thickness': { 'value': 0.025, 'units': 'mm' }, 'density': { 'value': 9.7, 'units': 'g/cm3' }, 'Co': { 'isotopes': { 'file_names': ['Co-58.csv', 'Co-59.csv'], 'list': ['58-Co', '59-Co'], 'mass': { 'value': [57.9357576, 58.9332002], 'units': 'g/mol', }, 'isotopic_ratio': [0.0, 1.0], }, 'density': { 'value': 8.9, 'units': 'g/cm3' }, 'molar_mass': { 'value': 58.9332, 'units': 'g/mol' }, }, 'Ag': { 'isotopes': { 'file_names': ['Ag-107.csv', 'Ag-109.csv'], 'list': ['107-Ag', '109-Ag'], 'mass': { 'value': [106.905093, 108.904756], 'units': 'g/mol', }, 'isotopic_ratio': [0.51839, 0.48161000], }, 'density': { 'value': 10.5, 'units': 'g/cm3' }, 'molar_mass': { 'value': 107.8682, 'units': 'g/cm3' }, }, }, 'Ag': { 'elements': ['Ag'], 'stoichiometric_ratio': [1], 'thickness': { 'value': 0.1, 'units': 'mm' }, 'density': { 'value': 0.5, 'units': 'g/cm3' }, 'Ag': { 'isotopes': { 'file_names': ['Ag-107.csv', 'Ag-109.csv'], 'list': ['107-Ag', '109-Ag'], 'mass': { 'value': [106.905093, 108.904756], 'units': 'g/mol', }, 'isotopic_ratio': [0.51839, 0.48161000], }, 'density': { 'value': 10.5, 'units': 'g/cm3' }, 'molar_mass': { 'value': 107.8682, 'units': 'g/mol' }, }, }, } # CoAg # elements self.assertEqual(returned_stack['CoAg']['elements'], expected_stack['CoAg']['elements']) # atomic_atomic_ratio self.assertEqual(returned_stack['CoAg']['stoichiometric_ratio'], expected_stack['CoAg']['stoichiometric_ratio']) # thickness self.assertEqual(returned_stack['CoAg']['thickness']['value'], expected_stack['CoAg']['thickness']['value']) self.assertEqual(returned_stack['CoAg']['thickness']['units'], expected_stack['CoAg']['thickness']['units']) # isotopes Co # file names self.assertEqual( returned_stack['CoAg']['Co']['isotopes']['file_names'], expected_stack['CoAg']['Co']['isotopes']['file_names']) # list self.assertEqual(returned_stack['CoAg']['Co']['isotopes']['list'], expected_stack['CoAg']['Co']['isotopes']['list']) # mass self.assertEqual( returned_stack['CoAg']['Co']['isotopes']['mass']['value'], expected_stack['CoAg']['Co']['isotopes']['mass']['value']) self.assertEqual( returned_stack['CoAg']['Co']['isotopes']['mass']['units'], expected_stack['CoAg']['Co']['isotopes']['mass']['units']) # atomic_ratio Co self.assertAlmostEqual( returned_stack['CoAg']['Co']['isotopes']['isotopic_ratio'][0], expected_stack['CoAg']['Co']['isotopes']['isotopic_ratio'][0], delta=0.0001) self.assertAlmostEqual( returned_stack['CoAg']['Co']['isotopes']['isotopic_ratio'][1], expected_stack['CoAg']['Co']['isotopes']['isotopic_ratio'][1], delta=0.0001) # isotopic_ratio Ag self.assertAlmostEqual( returned_stack['CoAg']['Ag']['isotopes']['isotopic_ratio'][0], expected_stack['CoAg']['Ag']['isotopes']['isotopic_ratio'][0], delta=0.0001) self.assertAlmostEqual( returned_stack['CoAg']['Ag']['isotopes']['isotopic_ratio'][1], expected_stack['CoAg']['Ag']['isotopes']['isotopic_ratio'][1], delta=0.0001) # layer density self.assertEqual(returned_stack['Ag']['density']['value'], expected_stack['Ag']['density']['value']) self.assertAlmostEqual(returned_stack['CoAg']['density']['value'], expected_stack['CoAg']['density']['value'], delta=0.1) # element density self.assertEqual(returned_stack['CoAg']['Ag']['density']['value'], expected_stack['CoAg']['Ag']['density']['value']) self.assertEqual(returned_stack['CoAg']['Co']['density']['value'], expected_stack['CoAg']['Co']['density']['value']) # molar mass self.assertEqual(returned_stack['CoAg']['Ag']['molar_mass']['value'], expected_stack['CoAg']['Ag']['molar_mass']['value']) self.assertEqual(returned_stack['CoAg']['Co']['molar_mass']['value'], expected_stack['CoAg']['Co']['molar_mass']['value'])
class Simulation(object): # Input sample name or names as str, case sensitive def __init__(self, energy_min=1e-5, energy_max=1000, energy_step=0.01, database='ENDF_VIII'): """ initialize the a Simulation() using the Resonance() in ImagingReso :param energy_min: :type energy_min: :param energy_max: :type energy_max: :param energy_step: :type energy_step: :param database: :type database: """ self.energy_min = energy_min self.energy_max = energy_max self.energy_step = energy_step self.database = database self.o_reso = Resonance(energy_min=energy_min, energy_max=energy_max, energy_step=energy_step, database=database) self.neutron_pulse = None self.layer_list = [] self.layer = fit_util.Layer() self.x_tof_us = None self.y_att = None def add_layer(self, layer: str, thickness_mm: float, density_gcm3=np.NaN): """ :param layer: :type layer: :param thickness_mm: :type thickness_mm: :param density_gcm3: :type density_gcm3: :return: :rtype: """ self.o_reso.add_layer(formula=layer, thickness=thickness_mm, density=density_gcm3) self.layer_list.append(layer) self.layer.add_layer(layer=layer, thickness_mm=thickness_mm, density_gcm3=density_gcm3) def add_Layer(self, layer: Layer): """ Add layer using Layer class :param layer: """ for _each_layer in list(layer.info.keys()): self.add_layer(layer=_each_layer, thickness_mm=layer.info[_each_layer]['thickness']['value'], density_gcm3=layer.info[_each_layer]['density']['value']) def set_isotopic_ratio(self, layer, element, new_isotopic_ratio_list): """ Set isotopic ratios for picked element and update x y values to pass :param layer: :param element: :param new_isotopic_ratio_list: :return: x in eV y in attenuation """ if type(new_isotopic_ratio_list) is not list: raise ValueError("{} is not a list".format(new_isotopic_ratio_list)) # Check if layer exist if layer not in self.layer_list: raise ValueError('Layer {} does not exist.'.format(layer)) # Check if element exist _formula = re.findall(r'([A-Z][a-z]*)(\d*)', layer) _elements = [] for _element in _formula: _single_element = list(_element)[0] _elements.append(_single_element) if element not in _elements: raise ValueError('Element {} specified does not exist in {} layer.'.format(element, layer)) self.o_reso.set_isotopic_ratio(compound=layer, element=element, list_ratio=new_isotopic_ratio_list) # self.x_simu = np.array(self.o_reso.total_signal['energy_eV']).round(5) # self.y_simu = np.array(self.o_reso.total_signal['attenuation']) def get_x(self, x_type, offset_us=None, source_to_detector_m=None, t_unit='us', t_start_us=None, time_resolution_us=None, num_offset=0): """ Get x by specified type :param x_type: :type x_type: :param offset_us: :type offset_us: :param source_to_detector_m: :type source_to_detector_m: :return: x in specified type :rtype: np.array """ fit_util.check_if_in_list(x_type, fit_util.x_type_list) _x = np.array(self.o_reso.total_signal['energy_eV']).round(5) x = fit_util.convert_energy_to(x=_x, x_type=x_type, offset_us=offset_us, source_to_detector_m=source_to_detector_m, t_unit=t_unit, t_start_us=t_start_us, time_resolution_us=time_resolution_us, num_offset=num_offset) return x def get_y(self, y_type): """ Get x by specified type :param y_type: :type y_type: :return: y in specified type :rtype: np.array """ fit_util.check_if_in_list(y_type, fit_util.y_type_list) y = self.o_reso.total_signal[y_type] return y def _convolve_beam_shapes(self, source_to_detector_m, conv_proton, proton_params={}, model_index=1): _file_path = os.path.abspath(os.path.dirname(__file__)) _rel_path_to_neutron1 = 'data/_data_for_tutorial/neutron_pulse/source_section_1.dat' _rel_path_to_neutron2 = 'data/_data_for_tutorial/neutron_pulse/source_section_2.dat' path1 = os.path.join(_file_path, _rel_path_to_neutron1) path2 = os.path.join(_file_path, _rel_path_to_neutron2) self.neutron_pulse = NeutronPulse(path1, model_index=model_index) self.neutron_pulse.load_shape_each(path2) self.neutron_pulse.fit_shape(e_min=1, e_max=500, drop=False, norm=True, check_each=False, save_fig=False, overwrite_csv=False) self.neutron_pulse.fit_params(check_each=False, loglog_fit=True, overwrite_csv=False) self.neutron_pulse.make_shape(e_ev=self.get_x(x_type='energy'), t_interp=None, for_sum=True, norm=False, source_to_detector_m=source_to_detector_m, conv_proton=conv_proton, proton_params=proton_params, overwrite_csv=False) tof_beam_shape_df = self.neutron_pulse.shape_tof_df_interp.set_index('tof_us') tof_trans_df = tof_beam_shape_df * self.o_reso.total_signal['transmission'] tof_beam_shape_df['sum'] = tof_beam_shape_df.sum(axis=1) tof_trans_df['sum'] = tof_trans_df.sum(axis=1) # print(tof_beam_shape_df) # print(tof_trans_df) self.x_tof_us = np.array(tof_beam_shape_df.index) self.y_att = 1 - np.array(tof_trans_df['sum'] / tof_beam_shape_df['sum']) def peak_map(self, x_type, y_type, thres=0.15, min_dist=20, impr_reso=True, offset_us=None, source_to_detector_m=None, t_unit='us', t_start_us=None, time_resolution_us=None, num_offset=0, ): """ Get peak map for each element and/or isotope :param thres: :type thres: :param min_dist: :type min_dist: :param impr_reso: :type impr_reso: :return: :rtype: """ if len(self.layer_list) == 0: raise ValueError("No layer has been added.") _stack_signal = self.o_reso.stack_signal _layer_list = self.layer_list # _x_energy = _stack_signal[_layer_list[0]][_layer_list[0]]['energy_eV'] _x = self.get_x(x_type=x_type, offset_us=offset_us, source_to_detector_m=source_to_detector_m, t_unit=t_unit, t_start_us=t_start_us, time_resolution_us=time_resolution_us, num_offset=num_offset ) # _x = sorted(_x) peak_map = {} for _ele in _layer_list: # Isotope for _iso in self.o_reso.stack[_ele][_ele]['isotopes']['list']: peak_map[_iso] = {} _iso_y = _stack_signal[_ele][_ele][_iso]['attenuation'] _peak_df = fit_util.find_peak(x=_x, y=_iso_y, x_name='x', thres=thres, min_dist=min_dist, imprv_reso=impr_reso) if y_type == 'transmission': _peak_df['y'] = 1 - _peak_df['y'] peak_map[_iso]['ideal'] = _peak_df # Element peak_map[_ele] = {} _ele_y = _stack_signal[_ele][_ele]['attenuation'] _peak_df = fit_util.find_peak(x=_x, y=_ele_y, x_name='x', thres=thres, min_dist=min_dist, imprv_reso=impr_reso) if y_type == 'transmission': _peak_df['y'] = 1 - _peak_df['y'] peak_map[_ele]['ideal'] = _peak_df peak_map_dict = {'peak_map': peak_map, 'x_type': x_type, 'y_type': y_type} return peak_map_dict def plot(self, y_type='attenuation', x_type='energy', logx=False, logy=False, mixed=True, all_layers=False, all_elements=False, all_isotopes=False, items_to_plot=None, time_unit='us', offset_us=0., source_to_detector_m=16., t_start_us=1, time_resolution_us=0.16, ax_mpl=None, fmt='-', ms=2, lw=1.5, alpha=1): if len(self.layer_list) == 0: raise ValueError("No layer has been added.") if items_to_plot is not None: # shape format of items items = fit_util.Items(o_reso=self.o_reso, database=self.database) items_to_plot = items.shaped(items_list=items_to_plot) ax = self.o_reso.plot(y_axis=y_type, x_axis=x_type, mixed=mixed, all_layers=all_layers, all_elements=all_elements, all_isotopes=all_isotopes, items_to_plot=items_to_plot, source_to_detector_m=source_to_detector_m, offset_us=offset_us, time_resolution_us=time_resolution_us, time_unit=time_unit, t_start_us=t_start_us, ax_mpl=ax_mpl, logx=logx, logy=logy, # plotly=plotly fmt=fmt, ms=ms, lw=lw, alpha=alpha) return ax def export(self, output_type='clip', filename=None, x_type='energy', y_type='attenuation', all_layers=False, all_elements=False, all_isotopes=False, items_to_export=None, offset_us=0., source_to_detector_m=16., t_start_us=1, time_resolution_us=0.16, time_unit='us'): if items_to_export is not None: # Shape items items = fit_util.Items(o_reso=self.o_reso, database=self.database) items_to_export = items.shaped(items_list=items_to_export) _df = self.o_reso.export(output_type=output_type, filename=filename, x_axis=x_type, y_axis=y_type, all_layers=all_layers, all_elements=all_elements, all_isotopes=all_isotopes, items_to_export=items_to_export, offset_us=offset_us, source_to_detector_m=source_to_detector_m, t_start_us=t_start_us, time_resolution_us=time_resolution_us, time_unit=time_unit) return _df