Skip to content

Commit f3dea09

Browse files
authored
Merge pull request #2 from php1ic/fwf_read
Utilise read_fwf() from pandas
2 parents 56d7eed + 96fc638 commit f3dea09

34 files changed

+49351
-924
lines changed

README.md

Lines changed: 105 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,12 @@ All data should, however, be accurate.
1414

1515
## Mass tables
1616

17-
The data files released by the papers linked below are used to create the mass tables read by this code
17+
The data files released by the papers linked below are used to create the mass tables read by this code.
18+
There was no AME data published in 1997, but the 1995 AME matches the 1997 NUBASE according to section 4, "The tables" on P31 of [these proceedings](https://www.google.co.uk/books/edition/Atomic_Physics_at_Accelerators_Mass_Spec/3AbsCAAAQBAJ?hl=en).
19+
As a result the 1997 NUBASE data is referred to as being from 1995 for simplicity when merging data.
20+
- [AME1983](https://doi.org/10.1016/0375-9474(85)90283-0)
21+
- [AME1993](https://doi.org/10.1016/0375-9474(93)90024-R)
22+
- [AME1995](https://doi.org/10.1016/0375-9474(95)00445-9) + [NUBASE1997](https://doi.org/10.1016/S0375-9474(97)00482-X)
1823
- [AME2003](https://doi.org/10.1016/j.nuclphysa.2003.11.002) + [NUBASE2003](https://doi.org/10.1016/j.nuclphysa.2003.11.001)
1924
- [AME2012](https://doi.org/10.1088/1674-1137/36/12/002) + [NUBASE2012](https://doi.org/10.1088/1674-1137/36/12/001)
2025
- [AME2016](https://doi.org/10.1088/1674-1137/41/3/030002) + [NUBASE2016](https://doi.org/10.1088/1674-1137/41/3/030001)
@@ -30,3 +35,102 @@ The package is available on the Python Package Index so can be installed via pip
3035
pip install nuclearmasses
3136
```
3237

38+
Or you can clone the latest version from github
39+
```bash
40+
git clone https://github.com/php1ic/nuclearmasses
41+
```
42+
43+
## Usage
44+
45+
Once installed or cloned, the data is available as a single dataframe indexed on the mass table year
46+
```python
47+
>>> from nuclearmasses.mass_table import MassTable
48+
>>> df = MassTable().full_data
49+
```
50+
You can then interrogate, or extract, what ever information you want.
51+
For example, how has the mass excess and it's accuracy changed overtime for 190Re according to the AME
52+
```python
53+
>>> df[(df['A'] == 190) & (df['Symbol'] == 'Re')][['AMEMassExcess', 'AMEMassExcessError']]
54+
AMEMassExcess AMEMassExcessError
55+
TableYear
56+
1983 -35536.605 200.029
57+
1993 -35557.789 145.549
58+
1995 -35568.032 212.151
59+
2003 -35566.326 149.248
60+
2012 -35634.992 70.542
61+
2016 -35635.830 70.852
62+
2020 -35583.015 4.870
63+
```
64+
Or how do the mass excess of gold vary across the isotropic chain according to NUBASE in the most recent table for both experimentally measured and theoretical values
65+
```python
66+
>>> df.query("TableYear == 2020 and Symbol == 'Au'")[['A', 'NUBASEMassExcess', 'NUBASEMassExcessError', 'Experimental']]
67+
A NUBASEMassExcess NUBASEMassExcessError Experimental
68+
TableYear
69+
2020 168 2530.0 400.0 False
70+
2020 169 -1790.0 300.0 False
71+
2020 170 -3700.0 200.0 False
72+
2020 171 -7562.0 21.0 True
73+
2020 172 -9320.0 60.0 True
74+
2020 173 -12832.0 23.0 True
75+
2020 174 -14060.0 100.0 False
76+
2020 175 -17400.0 40.0 True
77+
2020 176 -18520.0 30.0 True
78+
2020 177 -21546.0 10.0 True
79+
2020 178 -22303.0 10.0 True
80+
2020 179 -24989.0 12.0 True
81+
2020 180 -25626.0 5.0 True
82+
2020 181 -27871.0 20.0 True
83+
2020 182 -28304.0 19.0 True
84+
2020 183 -30191.0 9.0 True
85+
2020 184 -30319.0 22.0 True
86+
2020 185 -31858.1 2.6 True
87+
2020 186 -31715.0 21.0 True
88+
2020 187 -33029.0 22.0 True
89+
2020 188 -32371.3 2.7 True
90+
2020 189 -33582.0 20.0 True
91+
2020 190 -32834.0 3.0 True
92+
2020 191 -33798.0 5.0 True
93+
2020 192 -32772.0 16.0 True
94+
2020 193 -33405.0 9.0 True
95+
2020 194 -32211.9 2.1 True
96+
2020 195 -32567.1 1.1 True
97+
2020 196 -31138.7 3.0 True
98+
2020 197 -31139.8 0.5 True
99+
2020 198 -29580.8 0.5 True
100+
2020 199 -29093.8 0.5 True
101+
2020 200 -27240.0 27.0 True
102+
2020 201 -26401.0 3.0 True
103+
2020 202 -24353.0 23.0 True
104+
2020 203 -23143.0 3.0 True
105+
2020 204 -20390.0 200.0 False
106+
2020 205 -18570.0 200.0 False
107+
2020 206 -14190.0 300.0 False
108+
2020 207 -10640.0 300.0 False
109+
2020 208 -5910.0 300.0 False
110+
2020 209 -2230.0 400.0 False
111+
2020 210 2680.0 400.0 False
112+
```
113+
114+
## Contributing
115+
116+
If you have ideas for additional functionality or find bugs please create an [issue](https://github.com/php1ic/nuclearmasses/issues) or better yet a [pull request](https://github.com/php1ic/nuclearmasses/pulls).
117+
118+
## Known issues
119+
- The half life from the NUBASE data is stored as the individual elements, a column with the value in seconds would be useful
120+
```python
121+
>>> df[(df['A'] == 14) & (df['Symbol'] == 'C')][['HalfLifeValue', 'HalfLifeUnit', 'HalfLifeError']]
122+
HalfLifeValue HalfLifeUnit HalfLifeError
123+
TableYear
124+
1983 NaN <NA> NaN
125+
1993 NaN <NA> NaN
126+
1995 5.73 ky 0.04
127+
2003 5.70 ky 0.03
128+
2012 5.70 ky 0.03
129+
2016 5.70 ky 0.03
130+
2020 5.70 ky 0.03
131+
```
132+
- The decay mode field from the NUBASE data is stored 'as-is' from the file.
133+
It looks like it can be split on the ';' character for isotopes where there is more than one mode.
134+
A dictionary of {decay mode: fraction} may be the best way to store all of this information.
135+
- Information from anything other than the ground state of an isotope is ignored when parsing the NUABSE file.
136+
The selection of what is and what is not included appears random to me which is why I simply ignored for the moment.

nuclearmasses/ame_mass_file.py

Lines changed: 142 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,148 @@
1-
"""Storage for variable line positions."""
2-
from nuclearmasses.parse import Parse
1+
from nuclearmasses.element_converter import ElementConverter
32

43

5-
class AMEMassFile(Parse):
4+
class AMEMassFile(ElementConverter):
65
"""Easy access to where the variables are in the AME mass file."""
76

87
def __init__(self, year: int):
9-
"""Setup up the values."""
108
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
9+
match year:
10+
case 1983:
11+
self.HEADER = 35
12+
self.FOOTER = 0
13+
self.START_Z = 11
14+
self.END_Z = 14
15+
self.START_A = 16
16+
self.END_A = 19
17+
self.START_ME = 29
18+
self.END_ME = 39
19+
self.START_DME = 41
20+
self.END_DME = 48
21+
self.START_BE_PER_A = 49
22+
self.END_BE_PER_A = 59
23+
self.START_DBE_PER_A = 61
24+
self.END_DBE_PER_A = 68
25+
self.START_BETA_DECAY_ENERGY = 76
26+
self.END_BETA_DECAY_ENERGY = 85
27+
self.START_DBETA_DECAY_ENERGY = 87
28+
self.END_DBETA_DECAY_ENERGY = 94
29+
self.START_AM = 97
30+
self.END_AM = 99
31+
self.START_MICRO_U = 100
32+
self.END_MICRO_U = 110
33+
self.START_MICRO_DU = 113
34+
self.END_MICRO_DU = 120
35+
case 1993:
36+
self.HEADER = 40
37+
self.FOOTER = 0
38+
self.START_Z = 11
39+
self.END_Z = 14
40+
self.START_A = 16
41+
self.END_A = 19
42+
self.START_ME = 29
43+
self.END_ME = 39
44+
self.START_DME = 41
45+
self.END_DME = 48
46+
self.START_BE_PER_A = 49
47+
self.END_BE_PER_A = 59
48+
self.START_DBE_PER_A = 61
49+
self.END_DBE_PER_A = 68
50+
self.START_BETA_DECAY_ENERGY = 76
51+
self.END_BETA_DECAY_ENERGY = 85
52+
self.START_DBETA_DECAY_ENERGY = 87
53+
self.END_DBETA_DECAY_ENERGY = 94
54+
self.START_AM = 97
55+
self.END_AM = 99
56+
self.START_MICRO_U = 100
57+
self.END_MICRO_U = 110
58+
self.START_MICRO_DU = 112
59+
self.END_MICRO_DU = 120
60+
case 1995:
61+
self.HEADER = 39
62+
self.FOOTER = 0
63+
self.START_Z = 11
64+
self.END_Z = 14
65+
self.START_A = 16
66+
self.END_A = 19
67+
self.START_ME = 29
68+
self.END_ME = 39
69+
self.START_DME = 41
70+
self.END_DME = 48
71+
self.START_BE_PER_A = 49
72+
self.END_BE_PER_A = 59
73+
self.START_DBE_PER_A = 61
74+
self.END_DBE_PER_A = 68
75+
self.START_BETA_DECAY_ENERGY = 76
76+
self.END_BETA_DECAY_ENERGY = 85
77+
self.START_DBETA_DECAY_ENERGY = 87
78+
self.END_DBETA_DECAY_ENERGY = 94
79+
self.START_AM = 97
80+
self.END_AM = 99
81+
self.START_MICRO_U = 100
82+
self.END_MICRO_U = 110
83+
self.START_MICRO_DU = 112
84+
self.END_MICRO_DU = 120
85+
case 2020:
86+
self.HEADER = 36
87+
self.FOOTER = 0
88+
self.START_Z = 11
89+
self.END_Z = 14
90+
self.START_A = 16
91+
self.END_A = 19
92+
self.START_ME = 29
93+
self.END_ME = 42
94+
self.START_DME = 43
95+
self.END_DME = 53
96+
self.START_BE_PER_A = 56
97+
self.END_BE_PER_A = 66
98+
self.START_DBE_PER_A = 69
99+
self.END_DBE_PER_A = 77
100+
self.START_BETA_DECAY_ENERGY = 82
101+
self.END_BETA_DECAY_ENERGY = 93
102+
self.START_DBETA_DECAY_ENERGY = 95
103+
self.END_DBETA_DECAY_ENERGY = 104
104+
self.START_AM = 106
105+
self.END_AM = 109
106+
self.START_MICRO_U = 110
107+
self.END_MICRO_U = 120
108+
self.START_MICRO_DU = 124
109+
self.END_MICRO_DU = 135
110+
case _:
111+
self.HEADER = 39
112+
self.FOOTER = 0
113+
self.START_Z = 11
114+
self.END_Z = 14
115+
self.START_A = 16
116+
self.END_A = 19
117+
self.START_ME = 29
118+
self.END_ME = 41
119+
self.START_DME = 42
120+
self.END_DME = 53
121+
self.START_BE_PER_A = 54
122+
self.END_BE_PER_A = 64
123+
self.START_DBE_PER_A = 65
124+
self.END_DBE_PER_A = 72
125+
self.START_BETA_DECAY_ENERGY = 76
126+
self.END_BETA_DECAY_ENERGY = 86
127+
self.START_DBETA_DECAY_ENERGY = 87
128+
self.END_DBETA_DECAY_ENERGY = 95
129+
self.START_AM = 96
130+
self.END_AM = 99
131+
self.START_MICRO_U = 100
132+
self.END_MICRO_U = 112
133+
self.START_MICRO_DU = 113
134+
self.END_MICRO_DU = 120
135+
136+
self.column_limits = [
137+
(self.START_Z, self.END_Z),
138+
(self.START_A, self.END_A),
139+
(self.START_ME, self.END_ME),
140+
(self.START_DME, self.END_DME),
141+
(self.START_BE_PER_A, self.END_BE_PER_A),
142+
(self.START_DBE_PER_A, self.END_DBE_PER_A),
143+
(self.START_BETA_DECAY_ENERGY, self.END_BETA_DECAY_ENERGY),
144+
(self.START_DBETA_DECAY_ENERGY, self.END_DBETA_DECAY_ENERGY),
145+
(self.START_AM, self.END_AM),
146+
(self.START_MICRO_U, self.END_MICRO_U),
147+
(self.START_MICRO_DU, self.END_MICRO_DU),
148+
]

0 commit comments

Comments
 (0)