Skip to content

Commit 347a17d

Browse files
committed
Updated explicit with foil classes
1 parent 8b0cb16 commit 347a17d

File tree

2 files changed

+91
-57
lines changed

2 files changed

+91
-57
lines changed

libra_toolbox/neutron_detection/activation_foils/explicit.py

Lines changed: 86 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,44 @@
11
from settings import *
2-
# from .calculations import n93_number, delay_time
2+
import foils
3+
from .calculations import n93_number, delay_time
34
import numpy as np
45
import pandas as pd
56
import os
67

78

8-
def get_foil_data(foil: dict,
9-
filepath=os.path.join(os.path.dirname(os.path.abspath(__file__)), 'nuclide_data.xlsx'),
10-
xslib='EAF2010'):
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'):
1112

12-
# Read in nuclide data
13-
df = pd.read_excel(filepath, skiprows=1)
13+
# # Read in nuclide data
14+
# df = pd.read_excel(filepath, skiprows=1)
1415

15-
# Only get info for one nuclide
16-
mask = df['Nuclide'] == foil['nuclide']
17-
18-
# Calculate number of nuclide atoms in foil
19-
num_element = (foil['mass']
20-
/ (df['Element_Atomic_Mass'][mask].item() * ureg.g / ureg.mol)
21-
* (6.022e23 * ureg.particle / ureg.mol)
22-
)
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+
# )
2324

24-
foil['number'] = num_element * df['Natural_Abundance'][mask].item()
25+
# foil['number'] = num_element * df['Natural_Abundance'][mask].item()
2526

26-
# Get density and mass attenuation coefficient
27-
foil['density'] = df['Density'][mask].item() * ureg.g / ureg.cm**3
28-
foil['mass_attenuation_coefficient'] = df['Mass_Attenuation_Coefficient'][mask].item() * (ureg.cm**2/(ureg.g))
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))
2930

30-
# Get cross section for available reactions
31-
for reaction in foil['reactions'].keys():
32-
heading = reaction + '_' + xslib + '_xs'
33-
if heading in df.keys():
34-
foil['reactions'][reaction]['cross_section'] = df[heading][mask].item() * ureg.barn
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
3536

36-
return foil
37+
# return foil
3738

3839

3940

40-
def get_chain(irradiations, decay_constant):
41+
def get_chain(irradiations, decay_constant=Nb92m_decay_constant):
4142
"""
4243
Returns the value of
4344
(1 - exp(-\lambda * \Delta t_1)) * (1 - exp(-\lambda * \Delta t_2)) * ... * (1 - exp(-\lambda * \Delta t_n))
@@ -60,9 +61,34 @@ def get_chain(irradiations, decay_constant):
6061
result = 1 - result * np.exp(-decay_constant * delta_t)
6162
return result
6263

63-
64-
def get_neutron_flux(experiment: dict, irradiations: list, foil: dict,
65-
reaction: str):
64+
def get_efficiency(energies=None, coeff=None,
65+
coeff_energy_bounds=None,
66+
coeff_type='total', geometric_eff=1.0):
67+
"""Calculates the total efficiency of a gamma detector
68+
based on provided coefficients. These coefficients could
69+
be for calculating the total efficiency (coeff_type='total')
70+
or for calculating the intrinsic efficiency (coeff_type='intrinsic')"""
71+
72+
if coeff is None:
73+
# These are the efficiencies reported for activation foil analysis
74+
# of the BABY 100 mL runs
75+
geometric_efficiency = 0.5
76+
intrinsic_efficiency = 0.344917296922981
77+
total_efficiency = geometric_eff * intrinsic_efficiency
78+
else:
79+
# 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)
86+
total_efficiency = geometric_eff * intrinsic_efficiency
87+
total_efficiency *= ureg.count / ureg.particle
88+
return total_efficiency
89+
90+
91+
def get_neutron_flux(experiment: dict, irradiations: list, foil: foils.Foil):
6692
"""calculates the neutron flux during the irradiation
6793
Based on Equation 1 from:
6894
Lee, Dongwon, et al. "Determination of the Deuterium-Tritium (D-T) Generator
@@ -77,9 +103,6 @@ def get_neutron_flux(experiment: dict, irradiations: list, foil: dict,
77103
pint.Quantity: neutron flux
78104
"""
79105

80-
print('inside get_neutron_flux()')
81-
decay_constant = foil['reactions'][reaction]['decay_constant']
82-
foil = get_foil_data(foil)
83106

84107
# time_between_generator_off_and_start_of_counting = delay_time(
85108
# experiment["time_generator_off"], experiment["start_time_counting"]
@@ -88,44 +111,55 @@ def get_neutron_flux(experiment: dict, irradiations: list, foil: dict,
88111
experiment["start_time_counting"] - experiment["time_generator_off"]
89112
).seconds * ureg.second
90113

91-
overall_efficiency = (
92-
(experiment[reaction]['efficiency'] * foil['reactions'][reaction]['branching_ratio'])
93-
* ureg.count
94-
/ ureg.particle
95-
)
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'],
117+
coeff_type='total')
118+
elif 'intrinsic_eff_coeff' in experiment.keys():
119+
total_efficiency = get_efficiency(experiment['intrinsic_eff_coeff'], foil.photon_energies,
120+
coeff_energy_bounds=experiment['efficiency_bounds'],
121+
coeff_type='intrinsic')
122+
else:
123+
total_efficiency = get_efficiency()
124+
125+
#Spectroscopic Factor to account for the branching ratio and the
126+
# total detection efficiency
127+
128+
f_spec = total_efficiency * foil.branching_ratio
96129

97-
print('efficiency', overall_efficiency)
98-
number_of_decays_measured = experiment[reaction]["photon_counts"] / overall_efficiency
130+
print('total efficiency', total_efficiency)
131+
number_of_decays_measured = experiment["photon_counts"] / f_spec
99132
print('number of decays measured', number_of_decays_measured)
100-
print('number', foil['number'])
101-
print('cross section', foil['reactions'][reaction]['cross_section'])
133+
print('number', foil.atoms)
134+
print('cross section', foil.cross_section)
102135

103136

104137
flux = (
105138
number_of_decays_measured
106-
/ foil['number']
107-
/ foil['reactions'][reaction]['cross_section']
139+
/ foil.atoms
140+
/ foil.cross_section
108141
)
109142

110-
f_time = (get_chain(irradiations, foil['reactions'][reaction]['decay_constant'])
111-
* np.exp( -decay_constant
143+
f_time = (get_chain(irradiations, foil.decay_constant)
144+
* np.exp( -foil.decay_constant
112145
* time_between_generator_off_and_start_of_counting)
113-
* (1 - np.exp( -decay_constant * experiment['real_count_time']))
146+
* (1 - np.exp( -foil.decay_constant * experiment['real_count_time']))
114147
* (experiment['live_count_time'] / experiment['real_count_time'])
115-
/ decay_constant
148+
/ foil.decay_constant
116149
)
117150

118151
print('att coeff', foil['mass_attenuation_coefficient'])
119152
print('density', foil['density'])
120153
print('thickness', foil['thickness'])
121154

155+
# Correction factor of gamma-ray self-attenuation in the foil
122156
f_self = ( (1 -
123-
np.exp(-foil['mass_attenuation_coefficient']
124-
* foil['density']
125-
* foil['thickness']))
126-
/ (foil['mass_attenuation_coefficient']
127-
* foil['density']
128-
* foil['thickness'])
157+
np.exp(-foil.mass_attenuation_coefficient
158+
* foil.density
159+
* foil.thickness))
160+
/ (foil.mass_attenuation_coefficient
161+
* foil.density
162+
* foil.thickness)
129163
).to('dimensionless')
130164

131165
print('flux: ', flux.to_reduced_units())

libra_toolbox/neutron_detection/activation_foils/foils.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ def __init__(self, mass: float, thickness: float, name=''):
7070
self.get_atoms()
7171

7272
# Should update mass attenuation coefficient to be photon energy-dependent
73-
self.mass_attenuation_coefficient = np.array([0.05866]) * ureg.g / ureg.cm**2 # at 1 MeV
73+
self.mass_attenuation_coefficient = np.array([0.06120]) * ureg.cm**2 / ureg.g # at 1 MeV
7474

7575
class Zirconium(Foil):
7676
def __init__(self, mass: float, thickness: float, name=''):
@@ -96,8 +96,8 @@ def __init__(self, mass: float, thickness: float, name=''):
9696
self.abundance = np.array([0.5145,
9797
0.5145])
9898
self.get_atoms()
99-
100-
# Should update mass attenuation coefficient to be photon energy-dependent
101-
self.mass_attenuation_coefficient = np.array([0.0581,
102-
0.0581]) * ureg.g / ureg.cm**2 # at 1 MeV
99+
100+
#From NIST Xray Mass Attenuation Coefficients Table 3
101+
self.mass_attenuation_coefficient = np.array([0.08590,
102+
0.06156]) * ureg.cm**2 / ureg.g # at 1 MeV
103103

0 commit comments

Comments
 (0)