Repository: CORE-GATECH-GROUP/serpent-tools
Pull request #516 (2024-06-03 20:54:21)

ENH: Support passing depletion reader settings at construction
Not really a deprecation **yet** but this is my first step into #339. The depletion reader can be fully configured at construction like
```python
r = DepletionReader(
    "case_dep.m",
    materials=["f.*"],
    materialVariables=["ADENS", "INH_TOX"],
    metadataKeys=["NAMES", "DAYS"]],
    processTotal=False,
)
r.read()
```
All of the arguments are optional, defaulting to `None`. If not given, the values in the `rc` global settings object is used.

Starting small because I want to get buy in from @DanKotlyar and other users before applying this approach to all the readers.

Current plan roll out (to be re-posted into #339) is
1. next release : each reader can be fully configured at construction. `rc` unchanged
2. +1 major release : setting any value in the `rc` object raises a deprecation warning. transition tests away from using `rc` in favor of direct construction
3. +3 major releases : remove the `rc` object from the code base

This should give enough time for users to update their applications to move away from the `rc` object

Make sure you have read over the developer guide to ease
the review process. These include:

- [x] PR fits the [project scope](http://serpent-tools.readthedocs.io/en/latest/develop/contributing.html#project-scope)
- [x] Code to be committed is [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) and matches the [code style](http://serpent-tools.readthedocs.io/en/latest/develop/codestyle.html#code-style) of the project
- [x] New and/or changed features are [well documented](http://serpent-tools.readthedocs.io/en/latest/develop/documentation.html#documentation) and have adequate testing
- [x] For first-time contributors, you have included your attribution in [`docs/contributors.rst`](https://github.com/CORE-GATECH-GROUP/serpent-tools/blob/develop/docs/contributors.rst)

## TODO
- [x] Add something to the changelog (0.11.0?)
- [x] Add a `versionadded` tag in the docstrings for these parameters

drewejohnson: @DanKotlyar ready for your re-review and merge if approved

Patch:
diff --git a/docs/changelog.rst b/docs/changelog.rst
index ef0dd7f..644db99 100644
--- a/docs/changelog.rst
+++ b/docs/changelog.rst
@@ -6,6 +6,13 @@
 Changelog
 =========
 
+.. _v0.11.0:
+
+0.11.0
+======
+
+* Depletion reader settings can be provided at construction - :pull:`516`
+
 .. _v0.10.1:
 
 :release-tag:`0.10.1`
diff --git a/src/serpentTools/parsers/depletion.py b/src/serpentTools/parsers/depletion.py
index 18ade58..f30ff96 100644
--- a/src/serpentTools/parsers/depletion.py
+++ b/src/serpentTools/parsers/depletion.py
@@ -147,6 +147,37 @@ class DepletionReader(DepPlotMixin, MaterialReader):
     ----------
     filePath: str
         path to the depletion file
+    materials : list of string, optional
+        Names and patterns to use when determining if a material found
+        in the file should be processed or not. ``["fuel"]`` will
+        result in only the material exactly named ``fuel`` to be processed.
+        But ``["fuel.*"]`` is a pattern that will match and collect any
+        material that begins with ``fuel``. If not provided,
+        pulls from ``depletion.materials`` setting.
+
+        .. versionadded:: 0.11.0
+
+    materialVariables : list of string, optional
+        Names of variables to pull for each processed material. List can
+        contain zero or more entries like ``"ADENS"``, ``"MDENS"``, and
+        ``"INH_TOX"``. If not provided, pulls from
+        ``depletion.materialVariables`` setting.
+
+        .. versionadded:: 0.11.0
+
+    metadataKeys : list of string, optional
+        Metadata fields to pull from the file. List can contain
+        zero or more of the following strings: ``"ZAI"``, ``"NAMES"``,
+        ``"DAYS",`` and ``"BU"`` (case sensitive). If not provided,
+        pulls from ``depletion.metadataKeys`` setting
+
+        .. versionadded:: 0.11.0
+
+    processTotal : bool, optional
+        Flag to process the ``TOTAL`` data section or not. If not given,
+        pulls from the ``depletion.processTotal`` setting.
+
+        .. versionadded:: 0.11.0
 
     Attributes
     ----------
@@ -170,6 +201,7 @@ class DepletionReader(DepPlotMixin, MaterialReader):
         of this reader
 
     """
+
     docAttrs = """materials: dict
         Dictionary with material names as keys and the corresponding
         :py:class:`~serpentTools.objects.materials.DepletedMaterial` class
@@ -178,9 +210,24 @@ class DepletionReader(DepPlotMixin, MaterialReader):
         Dictionary with file-wide data names as keys and the
         corresponding data, e.g. ``'zai'``: [list of zai numbers]"""
 
-    def __init__(self, filePath):
-        MaterialReader.__init__(self, filePath, 'depletion')
-        patterns = self.settings['materials'] or ['.*']
+    def __init__(
+        self,
+        filePath,
+        materials=None,
+        materialVariables=None,
+        metadataKeys=None,
+        processTotal=None,
+    ):
+        MaterialReader.__init__(self, filePath, "depletion")
+        if metadataKeys is not None:
+            self.settings["metadataKeys"] = metadataKeys
+        if materials is not None:
+            self.settings["materials"] = materials
+        if processTotal is not None:
+            self.settings["processTotal"] = processTotal
+        if materialVariables is not None:
+            self.settings["materialVariables"] = materialVariables
+        patterns = self.settings["materials"] or [".*"]
         # match all materials if nothing given
         self._matPatterns = [re.compile(mat) for mat in patterns]
         DepPlotMixin.__init__(self)


Test patch:
diff --git a/tests/test_depletion.py b/tests/test_depletion.py
index 4e2c5d7..de56a25 100644
--- a/tests/test_depletion.py
+++ b/tests/test_depletion.py
@@ -1,11 +1,13 @@
 """Test the depletion file."""
+
 from unittest import TestCase
 from os import remove
+from io import BytesIO
 
 from numpy import array
 from numpy.testing import assert_equal
+import pytest
 
-from io import BytesIO
 from serpentTools.data import getFile
 from serpentTools.settings import rc
 from serpentTools.parsers.depletion import (
@@ -434,3 +436,41 @@ class DepMatlabExportNoConverter(DepMatlabExportHelper):
 
 
 del DepMatlabExportHelper
+
+
+def test_defaultSettings():
+    """Test behavior of settings if no additional arguments given"""
+    r = DepletionReader(DEP_FILE_PATH)
+    assert r.settings["metadataKeys"] == ["ZAI", "NAMES", "DAYS", "BU"]
+    assert r.settings["materials"] == []
+    assert r.settings["processTotal"]
+    assert r.settings["materialVariables"] == []
+
+
+def test_simpleOverloadSettings():
+    """Test overwritting some settings and the behavior"""
+    base = DepletionReader(DEP_FILE_PATH)
+    base.read()
+    alt = DepletionReader(
+        DEP_FILE_PATH,
+        materials=["f.*"],
+        materialVariables=["ADENS", "INH_TOX"],
+        metadataKeys=["ZAI"],
+        processTotal=False,
+    )
+    assert not alt.settings["processTotal"]
+    alt.read()
+    assert set(alt.metadata) == {
+        "zai",
+    }
+    assert alt.zais == base.zais
+    assert set(alt.materials) == {
+        "fuel",
+    }
+    fuel = alt["fuel"]
+    assert set(fuel.data) == {"adens", "inhTox"}
+    assert fuel["adens"] == pytest.approx(base["fuel"]["adens"])
+    assert fuel["inhTox"] == pytest.approx(base["fuel"]["inhTox"])
+    assert alt.days is None
+    assert alt.burnup is None
+    assert alt.names is None