Repository: simpeg/simpeg

Issue:
ENH: Add method to expose weights keys in regularizations
### Proposed new feature or change:

Would be nice to add a public method to regularization classes that exposes the keys of the `_weights` dictionary, so every array in it can be accessed without the need to know all the keys.

This new method should live in `BaseRegularization` and could look like this:

```python
@property
def weights_keys(self) -> list[str]:
    """Return keys of cell weights."""
    return list(self._weights.keys())
```

---

This idea came up after the SimPEG Meeting of 2024-01-03.

Comments:

Patch:
diff --git a/SimPEG/regularization/base.py b/SimPEG/regularization/base.py
index 1c89fb4ec..8e91c704d 100644
--- a/SimPEG/regularization/base.py
+++ b/SimPEG/regularization/base.py
@@ -383,6 +383,13 @@ class BaseRegularization(BaseObjectiveFunction):
             self._weights[key] = values
         self._W = None
 
+    @property
+    def weights_keys(self) -> list[str]:
+        """
+        Return the keys for the existing cell weights
+        """
+        return list(self._weights.keys())
+
     def remove_weights(self, key):
         """Removes the weights for the key provided.
 


Test patch:
diff --git a/tests/base/test_regularization.py b/tests/base/test_regularization.py
index ceb910baf..8e9f769b9 100644
--- a/tests/base/test_regularization.py
+++ b/tests/base/test_regularization.py
@@ -6,7 +6,13 @@ import inspect
 
 import discretize
 from SimPEG import maps, objective_function, regularization, utils
-from SimPEG.regularization import BaseRegularization, WeightedLeastSquares
+from SimPEG.regularization import (
+    BaseRegularization,
+    WeightedLeastSquares,
+    Smallness,
+    SmoothnessFirstOrder,
+    SmoothnessSecondOrder,
+)
 from SimPEG.objective_function import ComboObjectiveFunction
 
 
@@ -657,6 +663,67 @@ class TestParent:
             regularization.parent = invalid_parent
 
 
+class TestWeightsKeys:
+    """
+    Test weights_keys property of regularizations
+    """
+
+    @pytest.fixture
+    def mesh(self):
+        """Sample mesh."""
+        return discretize.TensorMesh([8, 7, 6])
+
+    def test_empty_weights(self, mesh):
+        """
+        Test weights_keys when no weight is defined
+        """
+        reg = BaseRegularization(mesh)
+        assert reg.weights_keys == []
+
+    def test_user_defined_weights_as_dict(self, mesh):
+        """
+        Test weights_keys after user defined weights as dictionary
+        """
+        weights = dict(dummy_weight=np.ones(mesh.n_cells))
+        reg = BaseRegularization(mesh, weights=weights)
+        assert reg.weights_keys == ["dummy_weight"]
+
+    def test_user_defined_weights_as_array(self, mesh):
+        """
+        Test weights_keys after user defined weights as dictionary
+        """
+        weights = np.ones(mesh.n_cells)
+        reg = BaseRegularization(mesh, weights=weights)
+        assert reg.weights_keys == ["user_weights"]
+
+    @pytest.mark.parametrize(
+        "regularization_class", (Smallness, SmoothnessFirstOrder, SmoothnessSecondOrder)
+    )
+    def test_volume_weights(self, mesh, regularization_class):
+        """
+        Test weights_keys has "volume" by default on some regularizations
+        """
+        reg = regularization_class(mesh)
+        assert reg.weights_keys == ["volume"]
+
+    @pytest.mark.parametrize(
+        "regularization_class",
+        (BaseRegularization, Smallness, SmoothnessFirstOrder, SmoothnessSecondOrder),
+    )
+    def test_multiple_weights(self, mesh, regularization_class):
+        """
+        Test weights_keys has "volume" by default on some regularizations
+        """
+        weights = dict(
+            dummy_weight=np.ones(mesh.n_cells), other_weights=np.ones(mesh.n_cells)
+        )
+        reg = regularization_class(mesh, weights=weights)
+        if regularization_class == BaseRegularization:
+            assert reg.weights_keys == ["dummy_weight", "other_weights"]
+        else:
+            assert reg.weights_keys == ["dummy_weight", "other_weights", "volume"]
+
+
 class TestDeprecatedArguments:
     """
     Test errors after simultaneously passing new and deprecated arguments.