nuclearmasses 0.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nuclearmasses-0.0.1/.github/workflows/tests.yml +24 -0
- nuclearmasses-0.0.1/.gitignore +21 -0
- nuclearmasses-0.0.1/LICENSE +21 -0
- nuclearmasses-0.0.1/PKG-INFO +35 -0
- nuclearmasses-0.0.1/README.md +4 -0
- nuclearmasses-0.0.1/nuclearmasses/__init__.py +0 -0
- nuclearmasses-0.0.1/nuclearmasses/ame_mass_file.py +56 -0
- nuclearmasses-0.0.1/nuclearmasses/ame_mass_parse.py +55 -0
- nuclearmasses-0.0.1/nuclearmasses/ame_reaction_1_file.py +72 -0
- nuclearmasses-0.0.1/nuclearmasses/ame_reaction_1_parse.py +61 -0
- nuclearmasses-0.0.1/nuclearmasses/ame_reaction_2_file.py +72 -0
- nuclearmasses-0.0.1/nuclearmasses/ame_reaction_2_parse.py +64 -0
- nuclearmasses-0.0.1/nuclearmasses/data/2003/mass.mas03 +3218 -0
- nuclearmasses-0.0.1/nuclearmasses/data/2003/nubtab03.asc +4468 -0
- nuclearmasses-0.0.1/nuclearmasses/data/2003/rct1.mas03 +3218 -0
- nuclearmasses-0.0.1/nuclearmasses/data/2003/rct2.mas03 +3218 -0
- nuclearmasses-0.0.1/nuclearmasses/data/2012/mass.mas12 +3392 -0
- nuclearmasses-0.0.1/nuclearmasses/data/2012/nubtab12.asc +5511 -0
- nuclearmasses-0.0.1/nuclearmasses/data/2012/rct1.mas12 +3392 -0
- nuclearmasses-0.0.1/nuclearmasses/data/2012/rct2.mas12 +3392 -0
- nuclearmasses-0.0.1/nuclearmasses/data/2016/mass16.txt +3475 -0
- nuclearmasses-0.0.1/nuclearmasses/data/2016/nubase2016.txt +5625 -0
- nuclearmasses-0.0.1/nuclearmasses/data/2016/rct1-16.txt +3475 -0
- nuclearmasses-0.0.1/nuclearmasses/data/2016/rct2-16.txt +3475 -0
- nuclearmasses-0.0.1/nuclearmasses/data/2020/mass.mas20 +3594 -0
- nuclearmasses-0.0.1/nuclearmasses/data/2020/nubase_1.mas20 +5869 -0
- nuclearmasses-0.0.1/nuclearmasses/data/2020/rct1.mas20 +3593 -0
- nuclearmasses-0.0.1/nuclearmasses/data/2020/rct2.mas20 +3660 -0
- nuclearmasses-0.0.1/nuclearmasses/mass_table.py +126 -0
- nuclearmasses-0.0.1/nuclearmasses/nubase_file.py +85 -0
- nuclearmasses-0.0.1/nuclearmasses/nubase_parse.py +137 -0
- nuclearmasses-0.0.1/nuclearmasses/parse.py +46 -0
- nuclearmasses-0.0.1/nuclearmasses.egg-info/PKG-INFO +35 -0
- nuclearmasses-0.0.1/nuclearmasses.egg-info/SOURCES.txt +44 -0
- nuclearmasses-0.0.1/nuclearmasses.egg-info/dependency_links.txt +1 -0
- nuclearmasses-0.0.1/nuclearmasses.egg-info/requires.txt +5 -0
- nuclearmasses-0.0.1/nuclearmasses.egg-info/top_level.txt +1 -0
- nuclearmasses-0.0.1/pyproject.toml +64 -0
- nuclearmasses-0.0.1/setup.cfg +4 -0
- nuclearmasses-0.0.1/tests/__init__.py +0 -0
- nuclearmasses-0.0.1/tests/test_ame_mass_parse.py +69 -0
- nuclearmasses-0.0.1/tests/test_ame_reaction_1_parse.py +85 -0
- nuclearmasses-0.0.1/tests/test_ame_reaction_2_parse.py +85 -0
- nuclearmasses-0.0.1/tests/test_mass_table.py +56 -0
- nuclearmasses-0.0.1/tests/test_nubase_parse.py +105 -0
- nuclearmasses-0.0.1/tests/test_parse.py +34 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: Unit Tests
|
|
2
|
+
|
|
3
|
+
on: [push, pull_request]
|
|
4
|
+
|
|
5
|
+
jobs:
|
|
6
|
+
build:
|
|
7
|
+
runs-on: ubuntu-latest
|
|
8
|
+
strategy:
|
|
9
|
+
matrix:
|
|
10
|
+
python-version: ['3.10', '3.11', '3.12', '3.13']
|
|
11
|
+
|
|
12
|
+
steps:
|
|
13
|
+
- name: Checkout repository
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
16
|
+
uses: actions/setup-python@v5
|
|
17
|
+
with:
|
|
18
|
+
python-version: ${{ matrix.python-version }}
|
|
19
|
+
- name: Install dependencies
|
|
20
|
+
run: |
|
|
21
|
+
python -m pip install --upgrade pip
|
|
22
|
+
pip install -e .
|
|
23
|
+
- name: Test with pytest
|
|
24
|
+
run: pytest -v
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Files and directories created by python
|
|
2
|
+
**/__pycache__/
|
|
3
|
+
**/.pytest_cache
|
|
4
|
+
|
|
5
|
+
# A catch all for virtual env directories
|
|
6
|
+
.venv*/
|
|
7
|
+
venv*/
|
|
8
|
+
|
|
9
|
+
# PyCharm settings directory
|
|
10
|
+
.idea/
|
|
11
|
+
|
|
12
|
+
# Jupyter related files and directories
|
|
13
|
+
*.ipynb
|
|
14
|
+
.ipynb_checkpoints/
|
|
15
|
+
|
|
16
|
+
# Test coverage related files and directories
|
|
17
|
+
.coverage
|
|
18
|
+
coverage_html_report
|
|
19
|
+
|
|
20
|
+
# Package build files and folders
|
|
21
|
+
*.egg-info/
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: nuclearmasses
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: A python package to parse and store the various files published by AME and NUBASE
|
|
5
|
+
Author: Ian Cullen, Soham Pal
|
|
6
|
+
Project-URL: GitHub, https://github.com/php1ic/nuclearmasses
|
|
7
|
+
Keywords: nuclear,physics,decay,AME,NUBASE
|
|
8
|
+
Classifier: Development Status :: 4 - Beta
|
|
9
|
+
Classifier: Intended Audience :: Education
|
|
10
|
+
Classifier: Intended Audience :: Science/Research
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Programming Language :: Python
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Operating System :: OS Independent
|
|
20
|
+
Classifier: Topic :: Education
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering
|
|
22
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
23
|
+
Requires-Python: >=3.10
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Requires-Dist: pandas
|
|
27
|
+
Requires-Dist: pytest
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: coverage; extra == "dev"
|
|
30
|
+
Dynamic: license-file
|
|
31
|
+
|
|
32
|
+
# Nuclear Masses
|
|
33
|
+
|
|
34
|
+
Python package to parse the various files published by the AME and NUBASE.
|
|
35
|
+
|
|
File without changes
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""Storage for variable line positions."""
|
|
2
|
+
from nuclearmasses.parse import Parse
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class AMEMassFile(Parse):
|
|
6
|
+
"""Easy access to where the variables are in the AME mass file."""
|
|
7
|
+
|
|
8
|
+
def __init__(self, year: int):
|
|
9
|
+
"""Setup up the values."""
|
|
10
|
+
super().__init__()
|
|
11
|
+
if year < 2020:
|
|
12
|
+
self.HEADER = 39
|
|
13
|
+
self.FOOTER = None
|
|
14
|
+
self.START_A = 16
|
|
15
|
+
self.END_A = 19
|
|
16
|
+
self.START_Z = 11
|
|
17
|
+
self.END_Z = 14
|
|
18
|
+
self.START_ME = 29
|
|
19
|
+
self.END_ME = 41
|
|
20
|
+
self.START_DME = 42
|
|
21
|
+
self.END_DME = 53
|
|
22
|
+
self.START_BE_PER_A = 54
|
|
23
|
+
self.END_BE_PER_A = 64
|
|
24
|
+
self.START_DBE_PER_A = 65
|
|
25
|
+
self.END_DBE_PER_A = 72
|
|
26
|
+
self.START_BETA_DECAY_ENERGY = 76
|
|
27
|
+
self.END_BETA_DECAY_ENERGY = 86
|
|
28
|
+
self.START_DBETA_DECAY_ENERGY = 87
|
|
29
|
+
self.END_DBETA_DECAY_ENERGY = 95
|
|
30
|
+
self.START_MICRO_U = 100
|
|
31
|
+
self.END_MICRO_U = 112
|
|
32
|
+
self.START_MICRO_DU = 113
|
|
33
|
+
self.END_MICRO_DU = 125
|
|
34
|
+
else:
|
|
35
|
+
self.HEADER = 36
|
|
36
|
+
self.FOOTER = None
|
|
37
|
+
self.START_A = 16
|
|
38
|
+
self.END_A = 19
|
|
39
|
+
self.START_Z = 11
|
|
40
|
+
self.END_Z = 14
|
|
41
|
+
self.START_ME = 29
|
|
42
|
+
self.END_ME = 42
|
|
43
|
+
self.START_DME = 43
|
|
44
|
+
self.END_DME = 53
|
|
45
|
+
self.START_BE_PER_A = 56
|
|
46
|
+
self.END_BE_PER_A = 66
|
|
47
|
+
self.START_DBE_PER_A = 69
|
|
48
|
+
self.END_DBE_PER_A = 77
|
|
49
|
+
self.START_BETA_DECAY_ENERGY = 82
|
|
50
|
+
self.END_BETA_DECAY_ENERGY = 93
|
|
51
|
+
self.START_DBETA_DECAY_ENERGY = 95
|
|
52
|
+
self.END_DBETA_DECAY_ENERGY = 104
|
|
53
|
+
self.START_MICRO_U = 110
|
|
54
|
+
self.END_MICRO_U = 120
|
|
55
|
+
self.START_MICRO_DU = 124
|
|
56
|
+
self.END_MICRO_DU = 135
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"""Extract the data from the AME mass file."""
|
|
2
|
+
import logging
|
|
3
|
+
import pathlib
|
|
4
|
+
|
|
5
|
+
import pandas as pd
|
|
6
|
+
|
|
7
|
+
from nuclearmasses.ame_mass_file import AMEMassFile
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class AMEMassParser(AMEMassFile):
|
|
11
|
+
"""Parse the AME mass file.
|
|
12
|
+
|
|
13
|
+
The format is known but I don't think python can easily parse it.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
def __init__(self, filename: pathlib.Path, year: int):
|
|
17
|
+
"""Set the file to read and table year."""
|
|
18
|
+
self.filename = filename
|
|
19
|
+
self.year = year
|
|
20
|
+
super().__init__(self.year)
|
|
21
|
+
logging.info(f"Reading {self.filename} from {self.year}")
|
|
22
|
+
|
|
23
|
+
def _read_line(self, line: str) -> dict:
|
|
24
|
+
"""Read a line from the file."""
|
|
25
|
+
if line.find("#") != -1:
|
|
26
|
+
line = line.replace("#", " ")
|
|
27
|
+
|
|
28
|
+
data = {
|
|
29
|
+
"TableYear": self.year,
|
|
30
|
+
"A": self._read_as_int(line, self.START_A, self.END_A),
|
|
31
|
+
"Z": self._read_as_int(line, self.START_Z, self.END_Z),
|
|
32
|
+
"AMEMassExcess": self._read_as_float(line, self.START_ME, self.END_ME),
|
|
33
|
+
"AMEMassExcessError": self._read_as_float(line, self.START_DME, self.END_DME),
|
|
34
|
+
"BindingEnergyPerA": self._read_as_float(line, self.START_BE_PER_A, self.END_BE_PER_A),
|
|
35
|
+
"BindingEnergyPerAError": self._read_as_float(line, self.START_DBE_PER_A, self.END_DBE_PER_A),
|
|
36
|
+
"BetaDecayEnergy": self._read_as_float(line, self.START_BETA_DECAY_ENERGY, self.END_BETA_DECAY_ENERGY),
|
|
37
|
+
"BetaDecayEnergyError": self._read_as_float(line, self.START_DBETA_DECAY_ENERGY, self.END_DBETA_DECAY_ENERGY),
|
|
38
|
+
"AtomicMass": self._read_as_float(line, self.START_MICRO_U, self.END_MICRO_U),
|
|
39
|
+
"AtomicMassError": self._read_as_float(line, self.START_MICRO_DU, self.END_MICRO_DU),
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
data["N"] = data["A"] - data["Z"]
|
|
43
|
+
data["Symbol"] = self.z_to_symbol[data["Z"]]
|
|
44
|
+
|
|
45
|
+
return data
|
|
46
|
+
|
|
47
|
+
def read_file(self) -> pd.DataFrame:
|
|
48
|
+
"""Read the file."""
|
|
49
|
+
with open(self.filename, "r") as f:
|
|
50
|
+
lines = [line.rstrip() for line in f]
|
|
51
|
+
|
|
52
|
+
# Remove the header lines
|
|
53
|
+
lines = lines[self.HEADER: self.FOOTER]
|
|
54
|
+
|
|
55
|
+
return pd.DataFrame([self._read_line(line) for line in lines])
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"""Storage for the variable line positions."""
|
|
2
|
+
from nuclearmasses.parse import Parse
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class AMEReactionFileOne(Parse):
|
|
6
|
+
"""Easy access to where the variables are in the first AME reaction file."""
|
|
7
|
+
|
|
8
|
+
def __init__(self, year: int):
|
|
9
|
+
"""Setup the values that locate the variable."""
|
|
10
|
+
super().__init__()
|
|
11
|
+
if year < 2020:
|
|
12
|
+
self.HEADER = 39
|
|
13
|
+
self.FOOTER = None
|
|
14
|
+
self.START_R1_A = 1
|
|
15
|
+
self.END_R1_A = 4
|
|
16
|
+
self.START_R1_Z = 8
|
|
17
|
+
self.END_R1_Z = 11
|
|
18
|
+
self.START_S2N = 14
|
|
19
|
+
self.END_S2N = 22
|
|
20
|
+
self.START_DS2N = 23
|
|
21
|
+
self.END_DS2N = 30
|
|
22
|
+
self.START_S2P = 32
|
|
23
|
+
self.END_S2P = 40
|
|
24
|
+
self.START_DS2P = 41
|
|
25
|
+
self.END_DS2P = 48
|
|
26
|
+
self.START_QA = 50
|
|
27
|
+
self.END_QA = 58
|
|
28
|
+
self.START_DQA = 59
|
|
29
|
+
self.END_DQA = 66
|
|
30
|
+
self.START_Q2B = 67
|
|
31
|
+
self.END_Q2B = 76
|
|
32
|
+
self.START_DQ2B = 77
|
|
33
|
+
self.END_DQ2B = 84
|
|
34
|
+
self.START_QEP = 85
|
|
35
|
+
self.END_QEP = 94
|
|
36
|
+
self.START_DQEP = 95
|
|
37
|
+
self.END_DQEP = 102
|
|
38
|
+
self.START_QBN = 103
|
|
39
|
+
self.END_QBN = 112
|
|
40
|
+
self.START_DQBN = 113
|
|
41
|
+
self.END_DQBN = 125
|
|
42
|
+
else:
|
|
43
|
+
self.HEADER = 35
|
|
44
|
+
self.FOOTER = None
|
|
45
|
+
self.START_R1_A = 1
|
|
46
|
+
self.END_R1_A = 4
|
|
47
|
+
self.START_R1_Z = 8
|
|
48
|
+
self.END_R1_Z = 11
|
|
49
|
+
self.START_S2N = 14
|
|
50
|
+
self.END_S2N = 24
|
|
51
|
+
self.START_DS2N = 25
|
|
52
|
+
self.END_DS2N = 34
|
|
53
|
+
self.START_S2P = 36
|
|
54
|
+
self.END_S2P = 46
|
|
55
|
+
self.START_DS2P = 47
|
|
56
|
+
self.END_DS2P = 56
|
|
57
|
+
self.START_QA = 58
|
|
58
|
+
self.END_QA = 68
|
|
59
|
+
self.START_DQA = 69
|
|
60
|
+
self.END_DQA = 78
|
|
61
|
+
self.START_Q2B = 79
|
|
62
|
+
self.END_Q2B = 90
|
|
63
|
+
self.START_DQ2B = 91
|
|
64
|
+
self.END_DQ2B = 100
|
|
65
|
+
self.START_QEP = 101
|
|
66
|
+
self.END_QEP = 112
|
|
67
|
+
self.START_DQEP = 113
|
|
68
|
+
self.END_DQEP = 122
|
|
69
|
+
self.START_QBN = 123
|
|
70
|
+
self.END_QBN = 134
|
|
71
|
+
self.START_DQBN = 135
|
|
72
|
+
self.END_DQBN = 144
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""Extract the data from the first reaction file."""
|
|
2
|
+
import logging
|
|
3
|
+
import pathlib
|
|
4
|
+
|
|
5
|
+
import pandas as pd
|
|
6
|
+
|
|
7
|
+
from nuclearmasses.ame_reaction_1_file import AMEReactionFileOne
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class AMEReactionParserOne(AMEReactionFileOne):
|
|
11
|
+
"""Parse the first AME reaction file.
|
|
12
|
+
|
|
13
|
+
The format is known but I don't think python can easily parse it.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
def __init__(self, filename: pathlib.Path, year: int):
|
|
17
|
+
"""Set the file to read and table year."""
|
|
18
|
+
self.filename = filename
|
|
19
|
+
self.year = year
|
|
20
|
+
super().__init__(self.year)
|
|
21
|
+
logging.info(f"Reading {self.filename} from {self.year}")
|
|
22
|
+
|
|
23
|
+
def _read_line(self, line: str) -> dict:
|
|
24
|
+
"""Read a line from the file."""
|
|
25
|
+
# Don't use a '#' as an experimental marker in this file
|
|
26
|
+
# but still need to remove it
|
|
27
|
+
if line.find("#") != -1:
|
|
28
|
+
line = line.replace("#", " ")
|
|
29
|
+
|
|
30
|
+
data = {
|
|
31
|
+
"TableYear": self.year,
|
|
32
|
+
"A": self._read_as_int(line, self.START_R1_A, self.END_R1_A),
|
|
33
|
+
"Z": self._read_as_int(line, self.START_R1_Z, self.END_R1_Z),
|
|
34
|
+
"TwoNeutronSeparationEnergy": self._read_as_float(line, self.START_S2N, self.END_S2N),
|
|
35
|
+
"TwoNeutronSeparationEnergyError": self._read_as_float(line, self.START_DS2N, self.END_DS2N),
|
|
36
|
+
"TwoProtonSeparationEnergy": self._read_as_float(line, self.START_S2P, self.END_S2P),
|
|
37
|
+
"TwoProtonSeparationEnergyError": self._read_as_float(line, self.START_DS2P, self.END_DS2P),
|
|
38
|
+
"QAlpha": self._read_as_float(line, self.START_QA, self.END_QA),
|
|
39
|
+
"QAlphaError": self._read_as_float(line, self.START_DQA, self.END_DQA),
|
|
40
|
+
"QTwoBeta": self._read_as_float(line, self.START_Q2B, self.END_Q2B),
|
|
41
|
+
"QTwoBetaError": self._read_as_float(line, self.START_DQ2B, self.END_DQ2B),
|
|
42
|
+
"QEpsilon": self._read_as_float(line, self.START_QEP, self.END_QEP),
|
|
43
|
+
"QEpsilonError": self._read_as_float(line, self.START_DQEP, self.END_DQEP),
|
|
44
|
+
"QBetaNeutron": self._read_as_float(line, self.START_QBN, self.END_QBN),
|
|
45
|
+
"QBetaNeutronError": self._read_as_float(line, self.START_DQBN, self.END_DQBN),
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
data["N"] = data["A"] - data["Z"]
|
|
49
|
+
data["Symbol"] = self.z_to_symbol[data["Z"]]
|
|
50
|
+
|
|
51
|
+
return data
|
|
52
|
+
|
|
53
|
+
def read_file(self) -> pd.DataFrame:
|
|
54
|
+
"""Read the file."""
|
|
55
|
+
with open(self.filename, "r") as f:
|
|
56
|
+
lines = [line.rstrip() for line in f]
|
|
57
|
+
|
|
58
|
+
# Remove the header lines
|
|
59
|
+
lines = lines[self.HEADER: self.FOOTER]
|
|
60
|
+
|
|
61
|
+
return pd.DataFrame([self._read_line(line) for line in lines])
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"""Storage for the variable line positions."""
|
|
2
|
+
from nuclearmasses.parse import Parse
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class AMEReactionFileTwo(Parse):
|
|
6
|
+
"""Easy access to where the variables are in the second AME reaction file."""
|
|
7
|
+
|
|
8
|
+
def __init__(self, year: int):
|
|
9
|
+
"""Setup the values that locate the variables."""
|
|
10
|
+
super().__init__()
|
|
11
|
+
if year < 2020:
|
|
12
|
+
self.HEADER = 39
|
|
13
|
+
self.FOOTER = None
|
|
14
|
+
self.START_R2_A = 1
|
|
15
|
+
self.END_R2_A = 4
|
|
16
|
+
self.START_R2_Z = 8
|
|
17
|
+
self.END_R2_Z = 11
|
|
18
|
+
self.START_SN = 14
|
|
19
|
+
self.END_SN = 22
|
|
20
|
+
self.START_DSN = 23
|
|
21
|
+
self.END_DSN = 30
|
|
22
|
+
self.START_SP = 32
|
|
23
|
+
self.END_SP = 40
|
|
24
|
+
self.START_DSP = 41
|
|
25
|
+
self.END_DSP = 48
|
|
26
|
+
self.START_Q4B = 49
|
|
27
|
+
self.END_Q4B = 58
|
|
28
|
+
self.START_DQ4B = 59
|
|
29
|
+
self.END_DQ4B = 66
|
|
30
|
+
self.START_QDA = 67
|
|
31
|
+
self.END_QDA = 76
|
|
32
|
+
self.START_DQDA = 77
|
|
33
|
+
self.END_DQDA = 84
|
|
34
|
+
self.START_QPA = 85
|
|
35
|
+
self.END_QPA = 94
|
|
36
|
+
self.START_DQPA = 95
|
|
37
|
+
self.END_DQPA = 102
|
|
38
|
+
self.START_QNA = 103
|
|
39
|
+
self.END_QNA = 112
|
|
40
|
+
self.START_DQNA = 113
|
|
41
|
+
self.END_DQNA = 125
|
|
42
|
+
else:
|
|
43
|
+
self.HEADER = 37
|
|
44
|
+
self.FOOTER = 3645
|
|
45
|
+
self.START_R2_A = 1
|
|
46
|
+
self.END_R2_A = 4
|
|
47
|
+
self.START_R2_Z = 8
|
|
48
|
+
self.END_R2_Z = 11
|
|
49
|
+
self.START_SN = 14
|
|
50
|
+
self.END_SN = 24
|
|
51
|
+
self.START_DSN = 25
|
|
52
|
+
self.END_DSN = 34
|
|
53
|
+
self.START_SP = 36
|
|
54
|
+
self.END_SP = 46
|
|
55
|
+
self.START_DSP = 47
|
|
56
|
+
self.END_DSP = 56
|
|
57
|
+
self.START_Q4B = 57
|
|
58
|
+
self.END_Q4B = 68
|
|
59
|
+
self.START_DQ4B = 69
|
|
60
|
+
self.END_DQ4B = 78
|
|
61
|
+
self.START_QDA = 79
|
|
62
|
+
self.END_QDA = 90
|
|
63
|
+
self.START_DQDA = 91
|
|
64
|
+
self.END_DQDA = 100
|
|
65
|
+
self.START_QPA = 101
|
|
66
|
+
self.END_QPA = 112
|
|
67
|
+
self.START_DQPA = 113
|
|
68
|
+
self.END_DQPA = 122
|
|
69
|
+
self.START_QNA = 123
|
|
70
|
+
self.END_QNA = 134
|
|
71
|
+
self.START_DQNA = 135
|
|
72
|
+
self.END_DQNA = 144
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"""Extract the date from the second reaction file."""
|
|
2
|
+
import logging
|
|
3
|
+
import pathlib
|
|
4
|
+
|
|
5
|
+
import pandas as pd
|
|
6
|
+
|
|
7
|
+
from nuclearmasses.ame_reaction_2_file import AMEReactionFileTwo
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class AMEReactionParserTwo(AMEReactionFileTwo):
|
|
11
|
+
"""Parse the second AME reaction file.
|
|
12
|
+
|
|
13
|
+
The format is known but I don't think python can easily parse it.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
def __init__(self, filename: pathlib.Path, year: int):
|
|
17
|
+
"""Set the file to read and table year."""
|
|
18
|
+
self.filename = filename
|
|
19
|
+
self.year = year
|
|
20
|
+
super().__init__(self.year)
|
|
21
|
+
logging.info(f"Reading {self.filename} from {self.year}")
|
|
22
|
+
|
|
23
|
+
def _read_line(self, line: str) -> dict:
|
|
24
|
+
"""Read a line from the file."""
|
|
25
|
+
# Don't use a '#' as an experimental marker in this file
|
|
26
|
+
# but still need to remove it
|
|
27
|
+
if line.find("#") != -1:
|
|
28
|
+
line = line.replace("#", " ")
|
|
29
|
+
|
|
30
|
+
data = {
|
|
31
|
+
"TableYear": self.year,
|
|
32
|
+
"A": self._read_as_int(line, self.START_R2_A, self.END_R2_A),
|
|
33
|
+
"Z": self._read_as_int(line, self.START_R2_Z, self.END_R2_Z),
|
|
34
|
+
"OneNeutronSeparationEnergy": self._read_as_float(line, self.START_SN, self.END_SN),
|
|
35
|
+
"OneNeutronSeparationEnergyError": self._read_as_float(line, self.START_DSN, self.END_DSN),
|
|
36
|
+
"OneProtonSeparationEnergy": self._read_as_float(line, self.START_SP, self.END_SP),
|
|
37
|
+
"OneProtonSeparationEnergyError": self._read_as_float(line, self.START_DSP, self.END_DSP),
|
|
38
|
+
"QFourBeta": self._read_as_float(line, self.START_Q4B, self.END_Q4B),
|
|
39
|
+
"QFourBetaError": self._read_as_float(line, self.START_DQ4B, self.END_DQ4B),
|
|
40
|
+
"QDeuteronAlpha": self._read_as_float(line, self.START_QDA, self.END_QDA),
|
|
41
|
+
"QDeuteronAlphaError": self._read_as_float(line, self.START_DQDA, self.END_DQDA),
|
|
42
|
+
"QProtonAlpha": self._read_as_float(line, self.START_QPA, self.END_QPA),
|
|
43
|
+
"QProtonAlphaError": self._read_as_float(line, self.START_DQPA, self.END_DQPA),
|
|
44
|
+
"QNeutronAlpha": self._read_as_float(line, self.START_QNA, self.END_QNA),
|
|
45
|
+
"QNeutronAlphaError": self._read_as_float(line, self.START_DQNA, self.END_DQNA),
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
data["N"] = data["A"] - data["Z"]
|
|
49
|
+
data["Symbol"] = self.z_to_symbol[data["Z"]]
|
|
50
|
+
|
|
51
|
+
return data
|
|
52
|
+
|
|
53
|
+
def read_file(self) -> pd.DataFrame:
|
|
54
|
+
"""Read the file."""
|
|
55
|
+
with open(self.filename, "r") as f:
|
|
56
|
+
lines = [line.rstrip() for line in f]
|
|
57
|
+
|
|
58
|
+
# Remove the header lines and the footer for the 2020 table
|
|
59
|
+
lines = lines[self.HEADER: self.FOOTER]
|
|
60
|
+
|
|
61
|
+
# The 2020 rct2 file has additional lines feeds not present in any other file
|
|
62
|
+
the_lines = [line for line in lines if line[:1] != "1"]
|
|
63
|
+
|
|
64
|
+
return pd.DataFrame([self._read_line(line) for line in the_lines])
|