예제 #1
0
 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)
예제 #2
0
    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'])
예제 #3
0
 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)
예제 #4
0
    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
예제 #5
0
    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)
예제 #6
0
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
예제 #7
0
    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)
예제 #8
0
    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'])
예제 #9
0
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