Skip to content

Commit b0fb1ed

Browse files
committed
add multi-isotope configuration support in FitOptions and InpManager
1 parent 0203795 commit b0fb1ed

File tree

4 files changed

+144
-0
lines changed

4 files changed

+144
-0
lines changed

src/pleiades/sammy/fitting/options.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,41 @@ def from_fitting_config(cls) -> "FitOptions":
223223

224224
return options
225225

226+
@classmethod
227+
def from_multi_isotope_config(cls) -> "FitOptions":
228+
"""Create a FitOptions instance configured for multi-isotope JSON mode fitting.
229+
230+
Multi-isotope mode combines ENDF extraction and Bayesian fitting in a single step
231+
using JSON configuration files for multiple isotopes.
232+
233+
Key features for multi-isotope mode:
234+
- UID 15: INPUT IS ENDF/B FILE (for JSON mode processing)
235+
- UID 16: USE ENERGY RANGE FROM ENDF FILE (from ENDF data)
236+
- UID 34: USE TWENTY SIGNIFICANT digits (for data format)
237+
- UID 60: BROADENING IS WANTED (for instrumental broadening)
238+
- UID 102: SOLVE BAYES EQUATIONS (fitting enabled)
239+
- UID 133: CHI SQUARED IS WANTED (for fit quality)
240+
241+
Returns:
242+
FitOptions: Instance configured for multi-isotope JSON mode fitting
243+
"""
244+
# Create with default options
245+
options = cls()
246+
247+
# Configure for multi-isotope JSON mode
248+
options.endf = ENDFOptions(
249+
input_is_endf_file_2=True, # Enable JSON mode ENDF processing
250+
use_energy_range_from_endf_file_2=True, # Use ENDF energy range
251+
)
252+
options.experimental_data = ExperimentalDataInputOptions(
253+
use_twenty_significant_digits=True # Use twenty format
254+
)
255+
options.broadening = BroadeningOptions(broadening_is_wanted=True)
256+
options.bayes_solution = BayesSolutionOptions(solve_bayes_equations=True)
257+
options.lpt_output = LPTOutputOptions(chi_squared_is_wanted=True)
258+
259+
return options
260+
226261
@classmethod
227262
def from_custom_config(cls, **kwargs) -> "FitOptions":
228263
"""Create a FitOptions instance with custom settings.

src/pleiades/sammy/io/inp_manager.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,3 +198,23 @@ def create_fitting_inp(cls, output_path: Path, title: str = None) -> Path:
198198
options = FitOptions.from_fitting_config()
199199
manager = cls(options, title=title or "Bayesian fitting mode")
200200
return manager.write_inp_file(output_path)
201+
202+
@classmethod
203+
def create_multi_isotope_inp(cls, output_path: Path, title: str = None, material_properties: Dict = None) -> Path:
204+
"""
205+
Create input file for multi-isotope JSON mode fitting.
206+
207+
This method generates a complete INP file for multi-isotope fitting that includes
208+
both static alphanumeric commands and calculated parameter sections.
209+
210+
Args:
211+
output_path: Path to write the input file
212+
title: Optional title for the inp file
213+
material_properties: Optional dict with material properties for parameter calculations
214+
215+
Returns:
216+
Path: Path to the created file
217+
"""
218+
options = FitOptions.from_multi_isotope_config()
219+
manager = cls(options, title=title or "Multi-isotope JSON mode fitting", reaction_type="transmission")
220+
return manager.write_inp_file(output_path)

tests/unit/pleiades/sammy/fitting/test_fit_options.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,28 @@ def test_from_custom_config():
147147
assert "DO NOT SOLVE BAYES EQUATIONS" in commands
148148

149149

150+
def test_from_multi_isotope_config():
151+
"""Test the factory method that creates FitOptions for multi-isotope JSON mode fitting."""
152+
fit_options = FitOptions.from_multi_isotope_config()
153+
154+
# Verify multi-isotope mode settings
155+
assert fit_options.endf.input_is_endf_file_2 is True
156+
assert fit_options.endf.use_energy_range_from_endf_file_2 is True
157+
assert fit_options.experimental_data.use_twenty_significant_digits is True
158+
assert fit_options.broadening.broadening_is_wanted is True
159+
assert fit_options.bayes_solution.solve_bayes_equations is True
160+
assert fit_options.lpt_output.chi_squared_is_wanted is True
161+
162+
# Check generated commands for multi-isotope mode
163+
commands = fit_options.get_alphanumeric_commands()
164+
assert "INPUT IS ENDF/B FILE 2" in commands
165+
assert "USE ENERGY RANGE FROM ENDF/B FILE 2" in commands
166+
assert "USE TWENTY SIGNIFICANT DIGITS" in commands
167+
assert "BROADENING IS WANTED" in commands
168+
assert "SOLVE BAYES EQUATIONS" in commands
169+
assert "CHI SQUARED IS WANTED" in commands
170+
171+
150172
def test_mutually_exclusive_options():
151173
"""Test that mutually exclusive options are handled correctly."""
152174
# Create RMatrixOptions with mutually exclusive options

tests/unit/pleiades/sammy/io/test_inp_manager.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,3 +242,70 @@ def test_custom_inp_creation(temp_dir):
242242

243243
assert isinstance(content, str)
244244
assert len(content) > 0 # Ensure some content was written
245+
246+
247+
def test_create_multi_isotope_inp(temp_dir):
248+
"""Test creating input file for multi-isotope JSON mode using class method."""
249+
output_path = temp_dir / "multi_isotope.inp"
250+
251+
with patch.object(FitOptions, "from_multi_isotope_config") as mock_from_multi:
252+
mock_options = MagicMock(spec=FitOptions)
253+
mock_options.get_alphanumeric_commands.return_value = [
254+
"INPUT IS ENDF/B FILE 2",
255+
"USE ENERGY RANGE FROM ENDF/B FILE 2",
256+
"USE TWENTY SIGNIFICANT DIGITS",
257+
"BROADENING IS WANTED",
258+
"SOLVE BAYES EQUATIONS",
259+
"CHI SQUARED IS WANTED",
260+
]
261+
mock_from_multi.return_value = mock_options
262+
263+
result_path = InpManager.create_multi_isotope_inp(output_path, title="Multi-isotope test")
264+
265+
assert result_path == output_path
266+
assert output_path.exists()
267+
268+
with open(output_path, "r") as f:
269+
content = f.read()
270+
271+
assert "Multi-isotope test" in content
272+
assert "transmission" in content # Reaction type should be set
273+
assert "INPUT IS ENDF/B FILE 2" in content
274+
assert "USE TWENTY SIGNIFICANT DIGITS" in content
275+
assert "BROADENING IS WANTED" in content
276+
mock_from_multi.assert_called_once()
277+
278+
279+
def test_multi_isotope_config_integration(temp_dir):
280+
"""Test multi-isotope configuration integration without mocking."""
281+
output_path = temp_dir / "multi_isotope_real.inp"
282+
283+
# Test real implementation without mocking
284+
result_path = InpManager.create_multi_isotope_inp(output_path, title="Real multi-isotope integration test")
285+
286+
assert result_path == output_path
287+
assert output_path.exists()
288+
289+
with open(output_path, "r") as f:
290+
content = f.read()
291+
292+
# Check for key multi-isotope commands
293+
expected_commands = [
294+
"INPUT IS ENDF/B FILE",
295+
"USE ENERGY RANGE FROM ENDF",
296+
"USE TWENTY SIGNIFICANT DIGITS",
297+
"BROADENING IS WANTED",
298+
"SOLVE BAYES EQUATIONS",
299+
"CHI SQUARED IS WANTED",
300+
"transmission",
301+
]
302+
303+
found_commands = []
304+
for cmd in expected_commands:
305+
if cmd in content:
306+
found_commands.append(cmd)
307+
308+
# Should find most of the expected commands
309+
assert (
310+
len(found_commands) >= 6
311+
), f"Found only {len(found_commands)}/{len(expected_commands)} commands: {found_commands}"

0 commit comments

Comments
 (0)