riplpy 0.6.2__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.
Files changed (110) hide show
  1. riplpy-0.6.2/LICENSE.txt +43 -0
  2. riplpy-0.6.2/MANIFEST.in +10 -0
  3. riplpy-0.6.2/PKG-INFO +522 -0
  4. riplpy-0.6.2/README.md +497 -0
  5. riplpy-0.6.2/pyproject.toml +48 -0
  6. riplpy-0.6.2/pytest.ini +8 -0
  7. riplpy-0.6.2/riplpy/__init__.py +1192 -0
  8. riplpy-0.6.2/riplpy/collections.py +474 -0
  9. riplpy-0.6.2/riplpy/config.py +397 -0
  10. riplpy-0.6.2/riplpy/db.py +1231 -0
  11. riplpy-0.6.2/riplpy/densities/__init__.py +94 -0
  12. riplpy-0.6.2/riplpy/densities/_comb_tab.py +82 -0
  13. riplpy-0.6.2/riplpy/densities/bsfg.py +178 -0
  14. riplpy-0.6.2/riplpy/densities/bsk14_comb.py +48 -0
  15. riplpy-0.6.2/riplpy/densities/bskg3_comb.py +46 -0
  16. riplpy-0.6.2/riplpy/densities/ct.py +140 -0
  17. riplpy-0.6.2/riplpy/densities/egsm.py +224 -0
  18. riplpy-0.6.2/riplpy/densities/egsm_norm.py +144 -0
  19. riplpy-0.6.2/riplpy/densities/examples/__init__.py +0 -0
  20. riplpy-0.6.2/riplpy/densities/examples/example1.py +55 -0
  21. riplpy-0.6.2/riplpy/densities/examples/example2.py +54 -0
  22. riplpy-0.6.2/riplpy/densities/examples/example3.py +61 -0
  23. riplpy-0.6.2/riplpy/densities/hfb.py +431 -0
  24. riplpy-0.6.2/riplpy/densities/nld.py +21 -0
  25. riplpy-0.6.2/riplpy/densities/qrpabe.py +46 -0
  26. riplpy-0.6.2/riplpy/densities/shell_corr.py +206 -0
  27. riplpy-0.6.2/riplpy/densities/thfb_comb.py +46 -0
  28. riplpy-0.6.2/riplpy/elements.py +513 -0
  29. riplpy-0.6.2/riplpy/exceptions.py +38 -0
  30. riplpy-0.6.2/riplpy/fission/__init__.py +126 -0
  31. riplpy-0.6.2/riplpy/fission/bskg3.py +214 -0
  32. riplpy-0.6.2/riplpy/fission/core.py +70 -0
  33. riplpy-0.6.2/riplpy/fission/d1m.py +149 -0
  34. riplpy-0.6.2/riplpy/fission/empire.py +181 -0
  35. riplpy-0.6.2/riplpy/fission/empirical.py +219 -0
  36. riplpy-0.6.2/riplpy/fission/empirical_new.py +50 -0
  37. riplpy-0.6.2/riplpy/fission/examples/__init__.py +0 -0
  38. riplpy-0.6.2/riplpy/fission/examples/example1.py +52 -0
  39. riplpy-0.6.2/riplpy/fission/hfb.py +242 -0
  40. riplpy-0.6.2/riplpy/fission/hfbpath.py +315 -0
  41. riplpy-0.6.2/riplpy/fission/nld_fis.py +347 -0
  42. riplpy-0.6.2/riplpy/fission/rmf.py +258 -0
  43. riplpy-0.6.2/riplpy/gamma/__init__.py +127 -0
  44. riplpy-0.6.2/riplpy/gamma/_layout.py +158 -0
  45. riplpy-0.6.2/riplpy/gamma/core.py +328 -0
  46. riplpy-0.6.2/riplpy/gamma/d1m.py +206 -0
  47. riplpy-0.6.2/riplpy/gamma/exp.py +410 -0
  48. riplpy-0.6.2/riplpy/gamma/gdr.py +158 -0
  49. riplpy-0.6.2/riplpy/gamma/gsf.py +292 -0
  50. riplpy-0.6.2/riplpy/gamma/psf.py +242 -0
  51. riplpy-0.6.2/riplpy/gamma/smlo_e1.py +234 -0
  52. riplpy-0.6.2/riplpy/gamma/smlo_m1.py +97 -0
  53. riplpy-0.6.2/riplpy/gamma/systematics.py +138 -0
  54. riplpy-0.6.2/riplpy/gamma/tlo.py +201 -0
  55. riplpy-0.6.2/riplpy/levels/__init__.py +39 -0
  56. riplpy-0.6.2/riplpy/levels/core.py +91 -0
  57. riplpy-0.6.2/riplpy/levels/ct.py +172 -0
  58. riplpy-0.6.2/riplpy/levels/discrete.py +381 -0
  59. riplpy-0.6.2/riplpy/masses/__init__.py +155 -0
  60. riplpy-0.6.2/riplpy/masses/ab.py +122 -0
  61. riplpy-0.6.2/riplpy/masses/ame20.py +153 -0
  62. riplpy-0.6.2/riplpy/masses/bskg3.py +189 -0
  63. riplpy-0.6.2/riplpy/masses/core.py +17 -0
  64. riplpy-0.6.2/riplpy/masses/d1m.py +172 -0
  65. riplpy-0.6.2/riplpy/masses/deformations.py +122 -0
  66. riplpy-0.6.2/riplpy/masses/density_bskg3.py +250 -0
  67. riplpy-0.6.2/riplpy/masses/density_d1m.py +253 -0
  68. riplpy-0.6.2/riplpy/masses/examples/__init__.py +0 -0
  69. riplpy-0.6.2/riplpy/masses/examples/example1.py +27 -0
  70. riplpy-0.6.2/riplpy/masses/examples/example2.py +30 -0
  71. riplpy-0.6.2/riplpy/masses/examples/example3.py +11 -0
  72. riplpy-0.6.2/riplpy/masses/examples/example4.py +26 -0
  73. riplpy-0.6.2/riplpy/masses/frdm12.py +152 -0
  74. riplpy-0.6.2/riplpy/masses/frdm95.py +157 -0
  75. riplpy-0.6.2/riplpy/masses/hfb14.py +164 -0
  76. riplpy-0.6.2/riplpy/masses/hfb27.py +177 -0
  77. riplpy-0.6.2/riplpy/masses/ws4.py +184 -0
  78. riplpy-0.6.2/riplpy/models.py +77 -0
  79. riplpy-0.6.2/riplpy/optical/__init__.py +192 -0
  80. riplpy-0.6.2/riplpy/optical/atomki.py +258 -0
  81. riplpy-0.6.2/riplpy/optical/config.py +228 -0
  82. riplpy-0.6.2/riplpy/optical/core.py +374 -0
  83. riplpy-0.6.2/riplpy/optical/coupled_channel.py +689 -0
  84. riplpy-0.6.2/riplpy/optical/deformations.py +319 -0
  85. riplpy-0.6.2/riplpy/optical/index.py +404 -0
  86. riplpy-0.6.2/riplpy/optical/omp.py +507 -0
  87. riplpy-0.6.2/riplpy/optical/reader.py +291 -0
  88. riplpy-0.6.2/riplpy/optical/references.py +274 -0
  89. riplpy-0.6.2/riplpy/optical/rop2013.py +273 -0
  90. riplpy-0.6.2/riplpy/optical/spherical.py +460 -0
  91. riplpy-0.6.2/riplpy/resonances/__init__.py +82 -0
  92. riplpy-0.6.2/riplpy/resonances/pwave.py +315 -0
  93. riplpy-0.6.2/riplpy/resonances/swave.py +40 -0
  94. riplpy-0.6.2/riplpy/test.py +54 -0
  95. riplpy-0.6.2/riplpy.egg-info/PKG-INFO +522 -0
  96. riplpy-0.6.2/riplpy.egg-info/SOURCES.txt +108 -0
  97. riplpy-0.6.2/riplpy.egg-info/dependency_links.txt +1 -0
  98. riplpy-0.6.2/riplpy.egg-info/requires.txt +11 -0
  99. riplpy-0.6.2/riplpy.egg-info/top_level.txt +1 -0
  100. riplpy-0.6.2/setup.cfg +4 -0
  101. riplpy-0.6.2/tests/test_api.py +927 -0
  102. riplpy-0.6.2/tests/test_core.py +176 -0
  103. riplpy-0.6.2/tests/test_densities.py +262 -0
  104. riplpy-0.6.2/tests/test_export.py +182 -0
  105. riplpy-0.6.2/tests/test_fission.py +140 -0
  106. riplpy-0.6.2/tests/test_gamma.py +250 -0
  107. riplpy-0.6.2/tests/test_levels.py +129 -0
  108. riplpy-0.6.2/tests/test_masses.py +255 -0
  109. riplpy-0.6.2/tests/test_optical.py +815 -0
  110. riplpy-0.6.2/tests/test_resonances.py +99 -0
@@ -0,0 +1,43 @@
1
+ Copyright (c) 2024. Triad National Security, LLC. All rights reserved.
2
+
3
+ This program was produced under U.S. Government contract
4
+ 89233218CNA000001 for Los Alamos National Laboratory (LANL), which is
5
+ operated by Triad National Security, LLC for the U.S. Department of
6
+ Energy/National Nuclear Security Administration.
7
+
8
+
9
+ All rights in the program are reserved by Triad National Security,
10
+ LLC, and the U.S. Department of Energy/National Nuclear Security
11
+ Administration. The Government is granted for itself and others acting
12
+ on its behalf a nonexclusive, paid-up, irrevocable worldwide license
13
+ in this material to reproduce, prepare derivative works, distribute
14
+ copies to the public, perform publicly and display publicly, and to
15
+ permit others to do so.
16
+
17
+
18
+ This program is open source under the BSD-3 License.
19
+
20
+ Redistribution and use in source and binary forms, with or without modification,
21
+ are permitted provided that the following conditions are met:
22
+
23
+ 1. Redistributions of source code must retain the above copyright notice, this
24
+ list of conditions and the following disclaimer.
25
+ 2. Redistributions in binary form must reproduce the above copyright notice, this
26
+ list of conditions and the following disclaimer in the documentation and/or other
27
+ materials provided with the distribution.
28
+ 3. Neither the name of the copyright holder nor the names of its contributors may
29
+ be used to endorse or promote products derived from this software without specific
30
+ prior written permission.
31
+
32
+
33
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
34
+ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
35
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
36
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
37
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
38
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
39
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
40
+ OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
41
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
42
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
43
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,10 @@
1
+ # Metadata is declared statically in pyproject.toml, so nothing here is read
2
+ # at build time; these rules only shape what lands in the sdist. README.md and
3
+ # LICENSE.txt are pulled in automatically by the `readme`/`license-files`
4
+ # fields, so only the test config needs naming explicitly.
5
+ include pytest.ini
6
+
7
+ # Never ship editor/OS cruft or bytecode.
8
+ global-exclude .DS_Store
9
+ global-exclude *.py[cod]
10
+ prune build
riplpy-0.6.2/PKG-INFO ADDED
@@ -0,0 +1,522 @@
1
+ Metadata-Version: 2.4
2
+ Name: riplpy
3
+ Version: 0.6.2
4
+ Summary: A Python package for the Reference Input Parameter Library (RIPL)
5
+ Author-email: Matthew Mumpower <matthew@mumpower.net>
6
+ License-Expression: BSD-3-Clause
7
+ Project-URL: Homepage, https://github.com/mrmumpow/riplpy
8
+ Project-URL: Source, https://github.com/mrmumpow/riplpy
9
+ Project-URL: Bug Tracker, https://github.com/mrmumpow/riplpy/issues
10
+ Project-URL: RIPL-4 Database, https://github.com/IAEA-NDS/RIPL-4
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Operating System :: OS Independent
13
+ Requires-Python: >=3.10
14
+ Description-Content-Type: text/markdown
15
+ License-File: LICENSE.txt
16
+ Requires-Dist: fortranformat>=1.2.2
17
+ Provides-Extra: dataframe
18
+ Requires-Dist: pandas; extra == "dataframe"
19
+ Provides-Extra: numpy
20
+ Requires-Dist: numpy; extra == "numpy"
21
+ Provides-Extra: all
22
+ Requires-Dist: numpy; extra == "all"
23
+ Requires-Dist: pandas; extra == "all"
24
+ Dynamic: license-file
25
+
26
+ # RIPLpy
27
+
28
+ Python interface for the Reference Input Parameter Library (RIPL).
29
+
30
+ ## Overview
31
+
32
+ RIPLpy provides access to the RIPL nuclear physics database, containing evaluated nuclear data for applications in nuclear reaction calculations, astrophysics simulations, and nuclear structure studies.
33
+
34
+ **Supported RIPL Sections:**
35
+ - **masses** - Atomic masses and mass models (AME2020, FRDM2012, HFB27, BSkG3, D1M, WS4)
36
+ - **densities** - Nuclear level density parameters (EGSM and microscopic combinatorial models)
37
+ - **fission** - Fission barrier heights and parameters
38
+ - **gamma** - Giant dipole resonance and gamma strength functions
39
+ - **levels** - Discrete nuclear level schemes
40
+ - **resonances** - Neutron resonance parameters (s-wave and p-wave)
41
+ - **optical** - Optical model potentials (~584 parameterizations)
42
+
43
+ > **RIPL-3 legacy support.** Some databases (mass models FRDM1995 / HFB14;
44
+ > level densities BSFG / CT / HFB; Mengoni-Nakajima shell corrections;
45
+ > theoretical GDR parameters) are RIPL-3 legacy products. They ship with the
46
+ > full RIPL distribution but are **not** part of the RIPL-4 GitHub release.
47
+ > RIPLpy retains their readers/writers and skips them with a warning when the
48
+ > data files are absent, so code works against both layouts.
49
+
50
+ ## Installation
51
+
52
+ To install RIPLpy please perform the following actions:
53
+ 1. Ensure your local environment is connected to the internet.
54
+ 2. Download the code from the Git repository.
55
+ 3. If necessary, unzip the compressed file and switch to the top level directory (which should include this read me file).
56
+ 4. Perform the appropriate pip installation based off how you want RIPL to behave in your given environment.
57
+
58
+
59
+
60
+ ```bash
61
+ # Development install (recommended)
62
+ pip install -e .
63
+ ```
64
+
65
+ The above command will install the package locally to your machine. Note that the install with the "-e" option allows the package to be updated in real time, so modifications to the source code will be live as soon as you make them. This is ideal for development / research environments and is the most common way to install and use RIPLpy.
66
+
67
+ ```bash
68
+ # Standard install
69
+ pip install .
70
+ ```
71
+
72
+ If you want the source to stay exactly as it was on the repository, use the above command instead. Note the lack of the "-e" option. This installation method is intended for production environments.
73
+
74
+ ### Optional features
75
+
76
+ `pandas` and `numpy` are only required for their respective DataFrame and
77
+ array exporters (`to_dataframe()` / `to_numpy()` and their `riplpy.*`
78
+ wrappers); everything else, including the CSV/JSON/list/ASCII exporters, works
79
+ without either. Install them via extras:
80
+
81
+ ```bash
82
+ pip install -e ".[dataframe]" # pandas, for to_dataframe()
83
+ pip install -e ".[numpy]" # numpy, for to_numpy()
84
+ pip install -e ".[dataframe,numpy]" # both
85
+ pip install -e ".[all]" # all optional dependencies
86
+ ```
87
+
88
+ (Drop the `-e` for a non-editable install.)
89
+
90
+ ## Quick Start
91
+
92
+ ```python
93
+ import riplpy
94
+
95
+ # Configure the RIPL database path
96
+ riplpy.set_path('/path/to/RIPL-4')
97
+
98
+ # Load all sections (may take time for large databases)
99
+ riplpy.load()
100
+
101
+ # Or load specific sections
102
+ import riplpy
103
+ import riplpy.masses as masses
104
+ masses.load(riplpy.get_path())
105
+ ```
106
+
107
+ ## Configuration
108
+
109
+ RIPLpy searches for the RIPL database in this order:
110
+ 1. Path set via `riplpy.set_path()`
111
+ 2. `RIPL_LOCATION` environment variable
112
+ 3. `~/.riplpyrc` configuration file
113
+
114
+ ```python
115
+ # Option 1: Set path programmatically
116
+ riplpy.set_path('/path/to/RIPL-4')
117
+
118
+ # Option 2: Environment variable
119
+ import os
120
+ os.environ['RIPL_LOCATION'] = '/path/to/RIPL-4'
121
+
122
+ # Check current path
123
+ print(riplpy.get_path())
124
+ ```
125
+
126
+ ## Core API
127
+
128
+ ### Working with Nuclei
129
+
130
+ ```python
131
+ from riplpy import Nuclide, Nucleus, Element
132
+
133
+ # Create nuclei using different specifications
134
+ pb208 = Nuclide(Z=82, A=208) # By Z and A
135
+ sn132 = Nuclide(Z=50, N=82) # By Z and N
136
+ fe56 = Nuclide(sym='Fe', A=56) # By symbol and A
137
+
138
+ # Access properties
139
+ print(pb208.Z) # 82
140
+ print(pb208.A) # 208
141
+ print(pb208.N) # 126
142
+ print(pb208.element_symbol) # 'Pb'
143
+ print(pb208.element_name) # 'Lead'
144
+
145
+ # Nucleus is an alias for Nuclide with N-based specification
146
+ nucleus = Nucleus(Z=50, N=82) # Sn-132
147
+ ```
148
+
149
+ ### Database Discovery
150
+
151
+ ```python
152
+ import riplpy
153
+
154
+ riplpy.load()
155
+
156
+ # List available sections
157
+ print(riplpy.list_sections())
158
+ # ['densities', 'fission', 'gamma', 'levels', 'masses', 'optical', 'resonances']
159
+
160
+ # List databases in a section
161
+ print(riplpy.list_databases('masses'))
162
+ # ['ame20', 'frdm12', 'frdm95', 'hfb14', 'hfb27', 'bskg3', 'd1m', ...]
163
+
164
+ # Check if a nucleus is in RIPL
165
+ n = Nuclide(Z=50, A=132)
166
+ print(riplpy.in_ripl(n))
167
+ # True
168
+
169
+ # Find which sections contain a nucleus
170
+ print(riplpy.in_sections(n))
171
+ # ['densities', 'gamma', 'levels', 'masses']
172
+
173
+ # Find specific databases containing a nucleus
174
+ print(riplpy.in_dbs(n))
175
+ # [('masses', 'ame20'), ('levels', 'discrete_levels'), ...]
176
+ ```
177
+
178
+ ### Convenience Functions
179
+
180
+ RIPLpy provides high-level functions for common operations:
181
+
182
+ ```python
183
+ import riplpy
184
+
185
+ riplpy.load()
186
+
187
+ # Mass data
188
+ mass_excess = riplpy.get_mass(82, 208) # Pb-208 mass excess [MeV]
189
+ mass_excess = riplpy.get_mass(82, 208, model='frdm12') # Using FRDM2012 model
190
+ entry = riplpy.get_mass_entry(82, 208) # Full mass entry
191
+
192
+ # Level density parameters
193
+ ld_params = riplpy.get_level_density(50, 120, model='egsm') # EGSM model for Sn-120
194
+
195
+ # Giant Dipole Resonance (RIPL-3 legacy theoretical GDR; full distribution only)
196
+ gdr = riplpy.get_gdr(82, 208) # GDR parameters for Pb-208
197
+
198
+ # Resonance spacing
199
+ res = riplpy.get_resonance(92, 238, wave='s') # S-wave resonances for U-238
200
+
201
+ # Fission barriers
202
+ barrier = riplpy.get_fission_barrier(92, 235, model='bskg3') # BSkG3 barrier for U-235
203
+
204
+ # Optical model potentials
205
+ omp = riplpy.get_omp(2405) # Get OMP by reference number
206
+ omps = riplpy.find_omp('n', 82, 208, E=14.0) # Find OMPs for n + Pb-208 at 14 MeV
207
+ irefs = riplpy.list_omps(projectile='n') # List all neutron OMPs
208
+ ```
209
+
210
+ ### Batch Operations
211
+
212
+ Process multiple nuclei efficiently:
213
+
214
+ ```python
215
+ import riplpy
216
+
217
+ riplpy.load()
218
+
219
+ # Get masses for multiple nuclei
220
+ nuclei = [(82, 208), (82, 206), (50, 132), (26, 56)]
221
+ masses = riplpy.get_masses(nuclei, model='ame20')
222
+
223
+ # Skip missing nuclei instead of raising errors
224
+ masses = riplpy.get_masses(nuclei, model='ame20', skip_missing=True)
225
+
226
+ # Batch level densities
227
+ ld_params = riplpy.get_level_densities(nuclei, model='egsm', skip_missing=True)
228
+
229
+ # Batch fission barriers
230
+ actinides = [(92, 235), (92, 238), (94, 239), (94, 241)]
231
+ barriers = riplpy.get_fission_barriers(actinides, model='bskg3', skip_missing=True)
232
+ ```
233
+
234
+ ### Direct Database Access
235
+
236
+ For more control, access databases directly:
237
+
238
+ ```python
239
+ import riplpy
240
+ import riplpy.masses as masses
241
+ from riplpy import Nuclide
242
+
243
+ masses.load(riplpy.get_path())
244
+
245
+ # Access specific database
246
+ ame = masses.db.ame20
247
+ frdm = masses.db.frdm2012
248
+
249
+ # Get entry for a nucleus
250
+ n = Nuclide(Z=82, A=208)
251
+ entry = ame.get(n)
252
+ print(entry.Mexp) # Experimental mass excess [MeV]
253
+ print(entry.Err) # Uncertainty [MeV]
254
+
255
+ # Filter databases
256
+ pb_isotopes = ame.filter(Z=82)
257
+ heavy_nuclei = ame.filter(lambda e: e.n.A > 200)
258
+
259
+ # Iterate over database
260
+ for nuclide, entry in ame.data.items():
261
+ if entry.Mexp is not None:
262
+ print(f"{nuclide.sym}-{nuclide.A}: {entry.Mexp:.3f} MeV")
263
+ ```
264
+
265
+ ### RIPL-4 Array Datasets
266
+
267
+ In addition to the scalar parameter tables, the RIPL-4 release ships large
268
+ per-nucleus / per-Z **array (spectral/tabular) datasets**. These are loaded on
269
+ demand (the global `riplpy.load()` skips them by default for speed) via
270
+ per-element / per-nucleus helpers, and every entry is a uniform
271
+ `PacketEntry` supporting both `entry['U']` and `entry.U` access plus
272
+ `.as_dict()` / `to_dataframe()` export:
273
+
274
+ ```python
275
+ import riplpy
276
+ from riplpy import Nuclide
277
+ riplpy.set_path('/path/to/RIPL-4')
278
+
279
+ # Gamma microscopic strength functions
280
+ import riplpy.gamma as gamma
281
+ d1m = gamma.d1m.load_element(Z=26) # D1M+QRPA E1, per Z
282
+ smlo = gamma.smlo_e1.load_nucleus(Nuclide(Z=82, A=208)) # SMLO E1 photoabsorption
283
+ tlo = gamma.tlo.load_element(Z=34) # TLO E1 tables
284
+ psf = gamma.psf.load_category('oslo') # experimental PSF database
285
+
286
+ # Fission paths and saddle-point level densities
287
+ import riplpy.fission as fission
288
+ paths = fission.hfbpath.load_d1m() # HFB-D1M fission paths
289
+ rmf = fission.rmf.load_axial() # RMF axial paths
290
+ nld = fission.nld_fis.load('Max1') # saddle-point NLD
291
+
292
+ # Combinatorial level densities
293
+ import riplpy.densities as densities
294
+ comb = densities.bsk14_comb.load_element(Z=26) # BSk14 combinatorial NLD
295
+
296
+ # Optical model potentials — select by incident particle (n, p, d, t, He3, alpha)
297
+ import riplpy.optical as optical
298
+ optical.load()
299
+ omps = optical.find_for_reaction('alpha', Z=26, A=56, E=20.0) # alpha-OMPs for Fe-56
300
+ atomki = optical.atomki.load_nucleus(26, 56) # ATOMKI / TALYS alphaomp9 alpha-OMP
301
+
302
+ # Every array DB exports uniformly for ML pipelines:
303
+ df = d1m.to_dataframe()
304
+ records = d1m.to_list()
305
+ ```
306
+
307
+ See `CATALOG.md` for the human-readable dataset/reader map and `SCHEMA.json`
308
+ for a machine-readable field/units catalog.
309
+
310
+ ### Writing & Exporting Data
311
+
312
+ Every loaded database supports the same export methods plus the native ASCII
313
+ writer, so the same recipes work for masses, level densities, fission
314
+ barriers, resonances, levels, and gamma-strength tables alike. Use these for
315
+ analysis pipelines, spreadsheet hand-off, ML ingestion, or to publish a
316
+ modified subset of RIPL back out to disk in the original format.
317
+
318
+ ```python
319
+ import riplpy
320
+ riplpy.load()
321
+
322
+ db = riplpy.get_database('masses.ame20') # any database works
323
+
324
+ # 1) Native RIPL ASCII (round-trip)
325
+ db.save('ame20_copy.dat')
326
+
327
+ # 2) Spreadsheet-friendly CSV (lists are stringified)
328
+ db.to_csv('ame20.csv')
329
+
330
+ # 3) JSON for general tooling
331
+ db.to_json('ame20.json', indent=2)
332
+
333
+ # 4) pandas DataFrame (Z, A, symbol always come first; array fields stay
334
+ # as native Python lists). Requires the [dataframe] extra.
335
+ df = db.to_dataframe()
336
+ df.to_parquet('ame20.parquet') # if you have pyarrow
337
+
338
+ # 5) numpy array (Z, A, symbol first). Requires the [numpy] extra.
339
+ arr = db.to_numpy() # structured (record) array
340
+ arr['Mexp'] # -> float64 column
341
+ X, cols = db.to_numpy(structured=False) # dense float64 feature matrix
342
+
343
+ # 6) Plain list of dicts (Nuclide -> {Z, A, symbol})
344
+ records = db.to_list() # nested structures preserved
345
+ flat = db.to_flat_list() # nested -> dotted keys
346
+
347
+ # Top-level convenience for ML/AI pipelines: one call, any section
348
+ df = riplpy.to_dataframe('fission.bskg3_barriers') # [dataframe] extra
349
+ arr = riplpy.to_numpy('resonances.swave') # [numpy] extra
350
+ rec = riplpy.to_records('resonances.swave') # no extra needed
351
+ ```
352
+
353
+ For ML/AI feature engineering, `to_dataframe` and `to_numpy` are the two
354
+ primary forms — a labelled table or a raw array:
355
+
356
+ ```python
357
+ import numpy as np
358
+ import riplpy
359
+ riplpy.load()
360
+
361
+ # (a) Scalar table -> DataFrame or feature matrix
362
+ db = riplpy.get_database('masses.ame20')
363
+ df = db.to_dataframe() # pandas: df['Mexp'], df['n.Z'], ...
364
+ X, cols = db.to_numpy(structured=False) # numpy: dense (n_nuclei, n_features)
365
+
366
+ # (b) Spectral table -> stacked (n_nuclei, n_energy) array for training
367
+ import riplpy.gamma as gamma
368
+ fe = gamma.d1m.load_element(Z=26) # per-Z D1M+QRPA E1 strengths
369
+ arr = fe.to_numpy() # arr['fE1'] is an object column of lists
370
+ spectra = np.stack(arr['fE1']) # (n_iron_isotopes, 300) float matrix
371
+ energy = np.asarray(arr['U'][0]) # shared 0.1-30 MeV grid
372
+ # `spectra` (and the matching DataFrame, fe.to_dataframe()) feed a model directly
373
+ ```
374
+
375
+ > The DataFrame exporters need `pip install ".[dataframe]"` and the numpy
376
+ > exporters need `pip install ".[numpy]"`; the CSV/JSON/list/ASCII exporters
377
+ > have no optional dependencies.
378
+
379
+ Filter, then write a derived subset back out as ASCII (round-trips through
380
+ the section's writer):
381
+
382
+ ```python
383
+ import riplpy
384
+ import riplpy.masses as masses
385
+ masses.load(riplpy.get_path())
386
+
387
+ heavy = masses.db.ame20.filter(lambda e: e.n.A > 200)
388
+ heavy.save('ame20_heavy_only.dat') # native ASCII, same format
389
+
390
+ import riplpy.fission as fission
391
+ fission.load(riplpy.get_path())
392
+ high = fission.db.bskg3_barriers.filter(
393
+ lambda e: e.inner['E[MeV]'] > 7.0
394
+ )
395
+ high.to_csv('bskg3_high_inner.csv')
396
+ ```
397
+
398
+ The gamma-strength `gsf` database can also write per-element or per-nucleus
399
+ files (useful when staging a customised RIPL tree on disk):
400
+
401
+ ```python
402
+ import riplpy.gamma as gamma
403
+ gamma.load(riplpy.get_path(), include_heavy=True)
404
+ gamma.db.gsf.save_all('out/gsf_by_Z') # one file per element (zNNN.dat)
405
+ gamma.db.gsf.save_entries_by_Z('out/gsf_by_nuc') # one file per nucleus
406
+ ```
407
+
408
+ And the per-element loaders that back the heavy spectral datasets are also
409
+ fully exportable — they expose the same uniform `to_dataframe()` /
410
+ `to_list()` interface as the scalar tables:
411
+
412
+ ```python
413
+ import riplpy.densities as densities
414
+ fe = densities.bsk14_comb.load_element(Z=26)
415
+ fe.to_dataframe().to_csv('bsk14_fe.csv', index=False)
416
+ fe.to_json('bsk14_fe.json')
417
+ ```
418
+
419
+ ## Section-Specific Usage
420
+
421
+ Each section has its own README with detailed examples:
422
+
423
+ - [Masses Section](riplpy/masses/README.md) - Evaluated masses and mass models
424
+ - [Densities Section](riplpy/densities/README.md) - Level density parameters
425
+ - [Fission Section](riplpy/fission/README.md) - Fission barrier data
426
+ - [Gamma Section](riplpy/gamma/README.md) - GDR and gamma strength functions
427
+ - [Levels Section](riplpy/levels/README.md) - Discrete nuclear levels
428
+ - [Resonances Section](riplpy/resonances/README.md) - Neutron resonance data
429
+ - [Optical Section](riplpy/optical/README.md) - Optical model potentials
430
+
431
+ ## Examples
432
+
433
+ ### Calculate Q-values
434
+
435
+ ```python
436
+ import riplpy
437
+
438
+ riplpy.load()
439
+
440
+ # Neutron mass excess in MeV
441
+ NEUTRON_MASS_EXCESS = 8.071
442
+
443
+ def capture_q_value(Z_target, A_target):
444
+ """Calculate Q-value for (n,gamma) capture reaction."""
445
+ m_target = riplpy.get_mass(Z_target, A_target)
446
+ m_product = riplpy.get_mass(Z_target, A_target + 1)
447
+ # Q = M_target + M_n - M_product (gamma has zero mass)
448
+ return m_target + NEUTRON_MASS_EXCESS - m_product
449
+
450
+ # Calculate Q-value for 208Pb(n,gamma)209Pb
451
+ q = capture_q_value(82, 208)
452
+ print(f"Q-value for Pb-208(n,g): {q:.3f} MeV")
453
+
454
+ # Calculate Q-value for a (p,n) reaction: 56Fe(p,n)56Co
455
+ def pn_q_value(Z, A):
456
+ """Calculate Q-value for (p,n) reaction."""
457
+ m_target = riplpy.get_mass(Z, A)
458
+ m_proton = riplpy.get_mass(1, 1)
459
+ m_residual = riplpy.get_mass(Z + 1, A)
460
+ m_neutron = NEUTRON_MASS_EXCESS
461
+ return (m_target + m_proton) - (m_residual + m_neutron)
462
+
463
+ q_pn = pn_q_value(26, 56)
464
+ print(f"Q-value for Fe-56(p,n)Co-56: {q_pn:.3f} MeV")
465
+ ```
466
+
467
+ ### Compare Mass Models
468
+
469
+ ```python
470
+ import riplpy
471
+
472
+ riplpy.load()
473
+
474
+ # Compare mass predictions for neutron-rich Sn isotopes
475
+ models = ['ame20', 'frdm12', 'hfb27']
476
+ isotopes = [(50, A) for A in range(120, 140)]
477
+
478
+ for Z, A in isotopes:
479
+ values = []
480
+ for model in models:
481
+ try:
482
+ m = riplpy.get_mass(Z, A, model=model)
483
+ values.append(f"{m:8.3f}")
484
+ except:
485
+ values.append(" N/A ")
486
+ print(f"Sn-{A}: " + " | ".join(values))
487
+ ```
488
+
489
+ ### Find Optical Potentials for a Reaction
490
+
491
+ ```python
492
+ import riplpy
493
+
494
+ riplpy.load()
495
+
496
+ # Find all neutron OMPs valid for U-238 at 1 MeV
497
+ potentials = riplpy.find_omp('n', Z=92, A=238, E=1.0)
498
+
499
+ print(f"Found {len(potentials)} potentials for n + U-238 at 1 MeV:")
500
+ for pot in potentials[:5]: # Show first 5
501
+ print(f" iref={pot.iref}: {pot.header.author[:40]}...")
502
+ print(f" Model: {pot.flags.model_name}, E: {pot.validity.E_min}-{pot.validity.E_max} MeV")
503
+ ```
504
+
505
+ ## Requirements
506
+
507
+ - Python 3.10+
508
+ - `fortranformat`
509
+ - `pandas` (optional, for `to_dataframe()`; install via the `dataframe` extra)
510
+ - `numpy` (optional, for `to_numpy()`; install via the `numpy` extra)
511
+
512
+ Install the required dependencies with `pip install .`, and the optional
513
+ DataFrame/array exporters with `pip install ".[dataframe,numpy]"` (or
514
+ `pip install ".[all]"`).
515
+
516
+ ## Author
517
+
518
+ Matthew Mumpower ([matthew@mumpower.net](mailto:matthew@mumpower.net))
519
+
520
+ ## License
521
+
522
+ Distributed under the BSD-3 License. See `LICENSE.txt` for details.