|
26 | 26 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
27 | 27 | """ |
28 | 28 |
|
| 29 | +import itertools |
29 | 30 | import re |
30 | | -from typing import List, Tuple |
| 31 | +from pathlib import Path |
| 32 | +from typing import List, Tuple, Dict |
31 | 33 |
|
32 | 34 |
|
33 | 35 | ATOMIC_SYMBOL = { |
@@ -188,3 +190,42 @@ def isotopes(element: str) -> List[Tuple[str, float]]: |
188 | 190 | if re.match(r'{}\d+'.format(element), kv[0]): |
189 | 191 | result.append(kv) |
190 | 192 | return result |
| 193 | + |
| 194 | + |
| 195 | +# Used in atomic_mass function as a cache |
| 196 | +_ATOMIC_MASS: Dict[str, float] = {} |
| 197 | + |
| 198 | + |
| 199 | +def atomic_mass(nuclide): |
| 200 | + """Return atomic mass of isotope in atomic mass units. |
| 201 | +
|
| 202 | + Atomic mass data comes from the `Atomic Mass Evaluation 2020 |
| 203 | + <https://doi.org/10.1088/1674-1137/abddaf>`_. |
| 204 | +
|
| 205 | + Parameters |
| 206 | + ---------- |
| 207 | + nuclide : str |
| 208 | + Name of nuclide, e.g., 'Pu239' |
| 209 | +
|
| 210 | + Returns |
| 211 | + ------- |
| 212 | + float |
| 213 | + Atomic mass of nuclide in [amu] |
| 214 | +
|
| 215 | + """ |
| 216 | + if not _ATOMIC_MASS: |
| 217 | + # Load data from AME2020 file |
| 218 | + mass_file = Path(__file__).with_name('mass_1.mas20.txt') |
| 219 | + with mass_file.open('r') as ame: |
| 220 | + # Read lines in file starting at line 37 |
| 221 | + for line in itertools.islice(ame, 36, None): |
| 222 | + name = f'{line[20:22].strip()}{int(line[16:19])}' |
| 223 | + mass = float(line[106:109]) + 1e-6*float( |
| 224 | + line[110:116] + '.' + line[117:123]) |
| 225 | + _ATOMIC_MASS[name.lower()] = mass |
| 226 | + |
| 227 | + # Get rid of metastable information |
| 228 | + if '_' in nuclide: |
| 229 | + nuclide = nuclide[:nuclide.find('_')] |
| 230 | + |
| 231 | + return _ATOMIC_MASS[nuclide.lower()] |
0 commit comments