diff --git a/doc/source/changelog.rst b/doc/source/changelog.rst index a57c5b06..7d229a5c 100644 --- a/doc/source/changelog.rst +++ b/doc/source/changelog.rst @@ -8,6 +8,7 @@ MontePy Changelog ---------------------- **Bug fixes** +* Fixed bug with parsing tally segments (#377) **Documentation** diff --git a/montepy/data_inputs/data_parser.py b/montepy/data_inputs/data_parser.py index ab893003..5e8b9b1b 100644 --- a/montepy/data_inputs/data_parser.py +++ b/montepy/data_inputs/data_parser.py @@ -7,6 +7,7 @@ material, mode, tally, + tally_segment, tally_multiplier, thermal_scattering, universe_input, @@ -23,6 +24,7 @@ mode.Mode, tally.Tally, tally_multiplier.TallyMultiplier, + tally_segment.TallySegment, thermal_scattering.ThermalScatteringLaw, transform.Transform, volume.Volume, diff --git a/montepy/data_inputs/tally_segment.py b/montepy/data_inputs/tally_segment.py new file mode 100644 index 00000000..9a78cea2 --- /dev/null +++ b/montepy/data_inputs/tally_segment.py @@ -0,0 +1,22 @@ +# Copyright 2024, Battelle Energy Alliance, LLC All Rights Reserved. +import montepy +from montepy.data_inputs.data_input import DataInputAbstract +from montepy.input_parser.tally_seg_parser import TallySegmentParser + + +class TallySegment(DataInputAbstract): + """ """ + + _parser = TallySegmentParser() + + @staticmethod + def _class_prefix(): + return "fs" + + @staticmethod + def _has_number(): + return True + + @staticmethod + def _has_classifier(): + return 0 diff --git a/montepy/input_parser/tally_seg_parser.py b/montepy/input_parser/tally_seg_parser.py new file mode 100644 index 00000000..25ae0856 --- /dev/null +++ b/montepy/input_parser/tally_seg_parser.py @@ -0,0 +1,61 @@ +# Copyright 2024, Battelle Energy Alliance, LLC All Rights Reserved. +from montepy.input_parser.data_parser import DataParser +from montepy.input_parser import syntax_node + + +class TallySegmentParser(DataParser): + """ """ + + debugfile = None + + @_("introduction tally_specification") + def tally(self, p): + ret = {} + for key, node in p.introduction.nodes.items(): + ret[key] = node + ret["tally"] = p.tally_specification + return syntax_node.SyntaxNode("data", ret) + + @_( + "tally_numbers", + "tally_numbers end_phrase", + "tally_numbers end_phrase end_phrase", + ) + def tally_specification(self, p): + if hasattr(p, "end_phrase"): + text = p.end_phrase + else: + text = syntax_node.ValueNode(None, str) + + return syntax_node.SyntaxNode( + "tally list", {"tally": p.tally_numbers, "end": text} + ) + + @_("PARTICLE", "PARTICLE padding", "TEXT", "TEXT padding") + def end_phrase(self, p): + """ + A non-zero number with or without padding. + + :returns: a float ValueNode + :rtype: ValueNode + """ + return self._flush_phrase(p, str) + + @_( + "tally_numbers tally_numbers", + "number_sequence", + "tally_numbers padding", + ) + def tally_numbers(self, p): + if hasattr(p, "tally_numbers"): + ret = p.tally_numbers + ret.nodes["right"] += p.padding + return ret + if hasattr(p, "tally_numbers1"): + return syntax_node.SyntaxNode("tally tree", {"left": p[0], "right": p[1]}) + else: + left = syntax_node.PaddingNode(None) + right = syntax_node.PaddingNode(None) + return syntax_node.SyntaxNode( + "tally set", {"left": left, "tally": p[0], "right": right} + ) diff --git a/tests/test_tally.py b/tests/test_tally.py index 9e38df73..9b840321 100644 --- a/tests/test_tally.py +++ b/tests/test_tally.py @@ -6,6 +6,7 @@ from unittest import TestCase +import pytest class TestTallyParser(TestCase): @@ -38,3 +39,18 @@ def test_parsing_tally_multiplier(self): print(test) input = Input([test], BlockType.DATA) data = parse_data(input) + + +@pytest.mark.parametrize( + "line", + [ + "fs14 -123", + "fs12 -456 t", + "fs11 -1 -2", + "fs16 +1 +2 c", + "fs17 -1 -2 t c", + ], +) +def test_tally_segment_init(line): + input = Input([line], BlockType.DATA) + data = parse_data(input)