11from settings import *
22import foils
3- from . calculations import n93_number , delay_time
3+ from calculations import n93_number , delay_time
44import numpy as np
55import pandas as pd
66import os
7+ import warnings
78
89
9- # def get_foil_data(foil: dict,
10- # filepath=os.path.join(os.path.dirname(os.path.abspath(__file__)), 'nuclide_data.xlsx'),
11- # xslib='EAF2010'):
12-
13- # # Read in nuclide data
14- # df = pd.read_excel(filepath, skiprows=1)
15-
16- # # Only get info for one nuclide
17- # mask = df['Nuclide'] == foil['nuclide']
18-
19- # # Calculate number of nuclide atoms in foil
20- # num_element = (foil['mass']
21- # / (df['Element_Atomic_Mass'][mask].item() * ureg.g / ureg.mol)
22- # * (6.022e23 * ureg.particle / ureg.mol)
23- # )
24-
25- # foil['number'] = num_element * df['Natural_Abundance'][mask].item()
26-
27- # # Get density and mass attenuation coefficient
28- # foil['density'] = df['Density'][mask].item() * ureg.g / ureg.cm**3
29- # foil['mass_attenuation_coefficient'] = df['Mass_Attenuation_Coefficient'][mask].item() * (ureg.cm**2/(ureg.g))
30-
31- # # Get cross section for available reactions
32- # for reaction in foil['reactions'].keys():
33- # heading = reaction + '_' + xslib + '_xs'
34- # if heading in df.keys():
35- # foil['reactions'][reaction]['cross_section'] = df[heading][mask].item() * ureg.barn
10+ def get_chain (irradiations , decay_constant ):
3611
37- # return foil
38-
39-
40-
41- def get_chain (irradiations , decay_constant = Nb92m_decay_constant ):
42- """
43- Returns the value of
12+ """ Returns the value of
4413 (1 - exp(-\lambda * \Delta t_1)) * (1 - exp(-\lambda * \Delta t_2)) * ... * (1 - exp(-\lambda * \Delta t_n))
4514 where \Delta t_i is the time between the end of the i-th period (rest or irradiation) and the start of the next one
4615
4716 Args:
4817 irradiations (list): list of dictionaries with keys "t_on" and "t_off" for irradiations
4918
5019 Returns:
51- float or pint.Quantity: the value of the chain
52- """
20+ float or pint.Quantity: the value of the chain """
21+
5322 result = 1
5423 periods = [{"start" : irradiations [0 ]["t_on" ], "end" : irradiations [0 ]["t_off" ]}]
5524 for irr in irradiations [1 :]:
@@ -61,6 +30,7 @@ def get_chain(irradiations, decay_constant=Nb92m_decay_constant):
6130 result = 1 - result * np .exp (- decay_constant * delta_t )
6231 return result
6332
33+
6434def get_efficiency (energies = None , coeff = None ,
6535 coeff_energy_bounds = None ,
6636 coeff_type = 'total' , geometric_eff = 1.0 ):
@@ -72,23 +42,26 @@ def get_efficiency(energies=None, coeff=None,
7242 if coeff is None :
7343 # These are the efficiencies reported for activation foil analysis
7444 # of the BABY 100 mL runs
75- geometric_efficiency = 0.5
45+ geometric_eff = 0.5
7646 intrinsic_efficiency = 0.344917296922981
7747 total_efficiency = geometric_eff * intrinsic_efficiency
48+ warnings .warn ('Using NaI efficiency from BABY 100 mL runs, which may not reflect detector efficiency accurately.' )
7849 else :
7950 # Check that efficiency is being interpolated between the bounds of the fit curve
80- if energies .min () < coeff_energy_bounds .min () or energies .max () > coeff_energy_bounds .max ():
81- raise Warning ('Efficiency is being extrapolated according to efficiency fit curve bounds.' )
82- if coeff_type .lower () is 'total' :
83- total_efficiency = np .polyval (coeff , energies )
84- elif coeff_type .lower () is 'intrinsic' :
85- intrinsic_efficiency = np .polyval (coeff , energies )
51+ ergs = energies .to (ureg .keV ).magnitude
52+ erg_bounds = coeff_energy_bounds .to (ureg .keV ).magnitude
53+ if np .min (ergs ) < np .min (erg_bounds ) or np .max (ergs ) > np .max (erg_bounds ):
54+ warnings .warn ('Efficiency is being extrapolated according to efficiency fit curve bounds.' )
55+ if coeff_type .lower ()== 'total' :
56+ total_efficiency = np .polyval (coeff , ergs )
57+ elif coeff_type .lower ()== 'intrinsic' :
58+ intrinsic_efficiency = np .polyval (coeff , ergs )
8659 total_efficiency = geometric_eff * intrinsic_efficiency
8760 total_efficiency *= ureg .count / ureg .particle
8861 return total_efficiency
8962
9063
91- def get_neutron_flux (experiment : dict , irradiations : list , foil : foils .Foil ):
64+ def get_neutron_flux (experiment : foils . Experiment , irradiations : list , foil : foils .Foil ):
9265 """calculates the neutron flux during the irradiation
9366 Based on Equation 1 from:
9467 Lee, Dongwon, et al. "Determination of the Deuterium-Tritium (D-T) Generator
@@ -108,15 +81,17 @@ def get_neutron_flux(experiment: dict, irradiations: list, foil: foils.Foil):
10881 # experiment["time_generator_off"], experiment["start_time_counting"]
10982 # )
11083 time_between_generator_off_and_start_of_counting = (
111- experiment [ " start_time_counting" ] - experiment [ " time_generator_off" ]
84+ experiment . start_time_counting - experiment . time_generator_off
11285 ).seconds * ureg .second
11386
114- if 'total_eff_coeff' in experiment .keys ():
115- total_efficiency = get_efficiency (experiment ['total_eff_coeff' ], foil .photon_energies ,
116- coeff_energy_bounds = experiment ['efficiency_bounds' ],
87+ if experiment .total_eff_coeff is not None :
88+ total_efficiency = get_efficiency (energies = foil .photon_energies ,
89+ coeff = experiment .total_eff_coeff ,
90+ coeff_energy_bounds = experiment .efficiency_bounds ,
11791 coeff_type = 'total' )
118- elif 'intrinsic_eff_coeff' in experiment .keys ():
119- total_efficiency = get_efficiency (experiment ['intrinsic_eff_coeff' ], foil .photon_energies ,
92+ elif experiment .intrinsic_eff_coeff is not None :
93+ total_efficiency = get_efficiency (energies = foil .photon_energies ,
94+ coeff = experiment .intrinsic_eff_coeff ,
12095 coeff_energy_bounds = experiment ['efficiency_bounds' ],
12196 coeff_type = 'intrinsic' )
12297 else :
@@ -128,10 +103,11 @@ def get_neutron_flux(experiment: dict, irradiations: list, foil: foils.Foil):
128103 f_spec = total_efficiency * foil .branching_ratio
129104
130105 print ('total efficiency' , total_efficiency )
131- number_of_decays_measured = experiment ["photon_counts" ] / f_spec
106+ number_of_decays_measured = experiment .photon_counts / f_spec
107+
132108 print ('number of decays measured' , number_of_decays_measured )
133- print ('number' , foil .atoms )
134- print ('cross section' , foil .cross_section )
109+ # print('number', foil.atoms)
110+ # print('cross section', foil.cross_section)
135111
136112
137113 flux = (
@@ -143,14 +119,11 @@ def get_neutron_flux(experiment: dict, irradiations: list, foil: foils.Foil):
143119 f_time = (get_chain (irradiations , foil .decay_constant )
144120 * np .exp ( - foil .decay_constant
145121 * time_between_generator_off_and_start_of_counting )
146- * (1 - np .exp ( - foil .decay_constant * experiment [ ' real_count_time' ] ))
147- * (experiment [ ' live_count_time' ] / experiment [ ' real_count_time' ] )
122+ * (1 - np .exp ( - foil .decay_constant * experiment . real_count_time ))
123+ * (experiment . live_count_time / experiment . real_count_time )
148124 / foil .decay_constant
149125 )
150126
151- print ('att coeff' , foil ['mass_attenuation_coefficient' ])
152- print ('density' , foil ['density' ])
153- print ('thickness' , foil ['thickness' ])
154127
155128 # Correction factor of gamma-ray self-attenuation in the foil
156129 f_self = ( (1 -
@@ -162,23 +135,23 @@ def get_neutron_flux(experiment: dict, irradiations: list, foil: foils.Foil):
162135 * foil .thickness )
163136 ).to ('dimensionless' )
164137
165- print ('flux: ' , flux .to_reduced_units ())
166- print ('f_time' , f_time )
167- print ('f_self' , f_self )
168-
169138 flux /= (f_time * f_self )
170-
171139
140+ # print('flux: ', flux.to_reduced_units())
141+ # print('f_time', f_time)
142+ # print('f_self', f_self)
172143
173144 # convert n/cm2/s to n/s
174- area_of_sphere = 4 * np .pi * experiment [ " distance_from_center_of_target_plane" ] ** 2
145+ area_of_sphere = 4 * np .pi * experiment . distance_from_center_of_target_plane ** 2
175146
176147 flux *= area_of_sphere
177148
149+ flux = flux .to (1 / ureg .s )
150+
178151 return flux
179152
180153
181- def get_neutron_flux_error (experiment : dict ):
154+ def get_neutron_flux_error (experiment : foils . Experiment , foil : foils . Foil ):
182155 """
183156 Returns the uncertainty of the neutron flux as a pint.Quantity
184157
@@ -189,7 +162,7 @@ def get_neutron_flux_error(experiment: dict):
189162 Returns:
190163 pint.Quantity: uncertainty of the neutron flux
191164 """
192- error_counts = experiment [ " photon_counts_uncertainty" ] / experiment [ " photon_counts" ]
165+ error_counts = experiment . photon_counts_uncertainty / experiment . photon_counts
193166 error_mass = 0.0001 * ureg .g / experiment ["foil_mass" ]
194167 error_geometric_eff = 0.025 / geometric_efficiency
195168 error_intrinsic_eff = 0.025 / nal_gamma_efficiency
0 commit comments