Repository: simpeg/simpeg
Pull request #1377 (2024-03-08 18:57:38)

Remove regmesh, mref and gradientType from regularizations
<!--
Thanks for contributing a pull request to SimPEG!
Remember to use a personal fork of SimPEG to propose changes.

Check out the stages of a pull request at
https://docs.simpeg.xyz/content/getting_started/contributing/pull-requests.html

Note that we are a team of volunteers and we appreciate your
patience during the review process.

Again, thanks for contributing!

Feel free to remove lines from this template that do not apply to you pull request.
-->

#### Summary
<!-- Add a summary of this Pull Request -->

Remove the `regmesh`, `mref` and `gradientType` properties from
regularizations. Make `Sparse` regularizations to raise errors after
getting `gradientType` as argument. Add tests checking errors are being
raised.

#### PR Checklist
* [ ] If this is a work in progress PR, set as a Draft PR
* [ ] Linted my code according to the [style guides](https://docs.simpeg.xyz/content/getting_started/contributing/code-style.html).
* [ ] Added [tests](https://docs.simpeg.xyz/content/getting_started/practices.html#testing) to verify changes to the code.
* [ ] Added necessary documentation to any new functions/classes following the
      expect [style](https://docs.simpeg.xyz/content/getting_started/practices.html#documentation).
* [ ] Marked as ready for review (if this is was a draft PR), and converted
      to a Pull Request
* [ ] Tagged ``@simpeg/simpeg-developers`` when ready for review.

#### Reference issue
<!--Example: write "Closes #NNNN" to automatically close that issue on merge.-->

Part of the solution to #1302

#### What does this implement/fix?
<!--Please explain your changes.-->

#### Additional information
<!--Any additional information you think is important.-->


<!--
Once all tests pass and the code has been reviewed and approved, it will be merged into main
-->


codecov[bot]: ## [Codecov](https://app.codecov.io/gh/simpeg/simpeg/pull/1377?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=simpeg) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 82.13%. Comparing base [(`7fe2c33`)](https://app.codecov.io/gh/simpeg/simpeg/commit/7fe2c33736e9632fd9c36296d0f89e32a53dfea5?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=simpeg) to head [(`bbbb791`)](https://app.codecov.io/gh/simpeg/simpeg/pull/1377?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=simpeg).


<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main    #1377      +/-   ##
==========================================
- Coverage   82.30%   82.13%   -0.18%     
==========================================
  Files         165      165              
  Lines       25240    25239       -1     
==========================================
- Hits        20774    20730      -44     
- Misses       4466     4509      +43     
```



</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/simpeg/simpeg/pull/1377?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=simpeg).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=simpeg).

santisoler: @jcapriot One of the last ones of these. I think is ready, would you take a second look?

Patch:
diff --git a/SimPEG/regularization/base.py b/SimPEG/regularization/base.py
index 5aaeaedfd..b82333025 100644
--- a/SimPEG/regularization/base.py
+++ b/SimPEG/regularization/base.py
@@ -262,8 +262,7 @@ class BaseRegularization(BaseObjectiveFunction):
         "mref",
         "reference_model",
         "0.19.0",
-        future_warn=True,
-        error=False,
+        error=True,
     )
 
     @property
@@ -285,8 +284,7 @@ class BaseRegularization(BaseObjectiveFunction):
         "regmesh",
         "regularization_mesh",
         "0.19.0",
-        future_warn=True,
-        error=False,
+        error=True,
     )
 
     @property
@@ -2111,8 +2109,7 @@ class WeightedLeastSquares(ComboObjectiveFunction):
         "mref",
         "reference_model",
         "0.19.0",
-        future_warn=True,
-        error=False,
+        error=True,
     )
 
     @property
diff --git a/SimPEG/regularization/sparse.py b/SimPEG/regularization/sparse.py
index 817c49e22..43d5916a0 100644
--- a/SimPEG/regularization/sparse.py
+++ b/SimPEG/regularization/sparse.py
@@ -577,10 +577,13 @@ class SparseSmoothness(BaseSparse, SmoothnessFirstOrder):
     """
 
     def __init__(self, mesh, orientation="x", gradient_type="total", **kwargs):
-        if "gradientType" in kwargs:
-            self.gradientType = kwargs.pop("gradientType")
-        else:
-            self.gradient_type = gradient_type
+        # Raise error if removed arguments were passed
+        if (key := "gradientType") in kwargs:
+            raise TypeError(
+                f"'{key}' argument has been removed. "
+                "Please use 'gradient_type' instead."
+            )
+        self.gradient_type = gradient_type
         super().__init__(mesh=mesh, orientation=orientation, **kwargs)
 
     def update_weights(self, m):
@@ -695,8 +698,7 @@ class SparseSmoothness(BaseSparse, SmoothnessFirstOrder):
         "gradientType",
         new_name="gradient_type",
         removal_version="0.19.0",
-        error=False,
-        future_warn=True,
+        error=True,
     )
 
 
@@ -930,6 +932,14 @@ class Sparse(WeightedLeastSquares):
                 f"'regularization_mesh' must be of type {RegularizationMesh} or {BaseMesh}. "
                 f"Value of type {type(mesh)} provided."
             )
+
+        # Raise error if removed arguments were passed
+        if (key := "gradientType") in kwargs:
+            raise TypeError(
+                f"'{key}' argument has been removed. "
+                "Please use 'gradient_type' instead."
+            )
+
         self._regularization_mesh = mesh
         if active_cells is not None:
             self._regularization_mesh.active_cells = active_cells
@@ -950,7 +960,6 @@ class Sparse(WeightedLeastSquares):
                     SparseSmoothness(mesh=self.regularization_mesh, orientation="z")
                 )
 
-        gradientType = kwargs.pop("gradientType", None)
         super().__init__(
             self.regularization_mesh,
             objfcts=objfcts,
@@ -959,13 +968,7 @@ class Sparse(WeightedLeastSquares):
         if norms is None:
             norms = [1] * (mesh.dim + 1)
         self.norms = norms
-
-        if gradientType is not None:
-            # Trigger deprecation warning
-            self.gradientType = gradientType
-        else:
-            self.gradient_type = gradient_type
-
+        self.gradient_type = gradient_type
         self.irls_scaled = irls_scaled
         self.irls_threshold = irls_threshold
 
@@ -995,7 +998,7 @@ class Sparse(WeightedLeastSquares):
         self._gradient_type = value
 
     gradientType = utils.code_utils.deprecate_property(
-        gradient_type, "gradientType", "0.19.0", error=False, future_warn=True
+        gradient_type, "gradientType", "0.19.0", error=True
     )
 
     @property
diff --git a/examples/01-maps/plot_sumMap.py b/examples/01-maps/plot_sumMap.py
index d86976ea0..fe99b0cc2 100644
--- a/examples/01-maps/plot_sumMap.py
+++ b/examples/01-maps/plot_sumMap.py
@@ -140,7 +140,7 @@ def run(plotIt=True):
     reg_m1 = regularization.Sparse(regMesh, mapping=wires.homo)
     reg_m1.set_weights(cell_weights=wires.homo * wr)
     reg_m1.norms = [0, 2]
-    reg_m1.mref = np.zeros(sumMap.shape[1])
+    reg_m1.reference_model = np.zeros(sumMap.shape[1])
 
     # Regularization for the voxel model
     reg_m2 = regularization.Sparse(
@@ -148,7 +148,7 @@ def run(plotIt=True):
     )
     reg_m2.set_weights(cell_weights=wires.hetero * wr)
     reg_m2.norms = [0, 0, 0, 0]
-    reg_m2.mref = np.zeros(sumMap.shape[1])
+    reg_m2.reference_model = np.zeros(sumMap.shape[1])
 
     reg = reg_m1 + reg_m2
 
diff --git a/examples/03-magnetics/plot_inv_mag_nonLinear_Amplitude.py b/examples/03-magnetics/plot_inv_mag_nonLinear_Amplitude.py
index bbcd745dc..a7bf71116 100644
--- a/examples/03-magnetics/plot_inv_mag_nonLinear_Amplitude.py
+++ b/examples/03-magnetics/plot_inv_mag_nonLinear_Amplitude.py
@@ -235,7 +235,7 @@ wr = wr / np.max(np.abs(wr))
 reg = regularization.Sparse(
     mesh, active_cells=surf, mapping=maps.IdentityMap(nP=nC), alpha_z=0
 )
-reg.mref = np.zeros(nC)
+reg.reference_model = np.zeros(nC)
 
 # Specify how the optimization will proceed, set susceptibility bounds to inf
 opt = optimization.ProjectedGNCG(
@@ -347,7 +347,7 @@ data_obj = data.Data(survey, dobs=bAmp, noise_floor=wd)
 # Create a sparse regularization
 reg = regularization.Sparse(mesh, active_cells=actv, mapping=idenMap)
 reg.norms = [1, 0, 0, 0]
-reg.mref = np.zeros(nC)
+reg.reference_model = np.zeros(nC)
 
 # Data misfit function
 dmis = data_misfit.L2DataMisfit(simulation=simulation, data=data_obj)
diff --git a/examples/20-published/plot_booky_1D_time_freq_inv.py b/examples/20-published/plot_booky_1D_time_freq_inv.py
index 180685ef3..e1469d3f3 100644
--- a/examples/20-published/plot_booky_1D_time_freq_inv.py
+++ b/examples/20-published/plot_booky_1D_time_freq_inv.py
@@ -261,7 +261,7 @@ def run(plotIt=True, saveFig=False, cleanup=True):
     inv = inversion.BaseInversion(invProb, directiveList=[target])
     reg.alpha_s = 1e-3
     reg.alpha_x = 1.0
-    reg.mref = m0.copy()
+    reg.reference_model = m0.copy()
     opt.LSshorten = 0.5
     opt.remember("xc")
     # run the inversion
@@ -379,7 +379,7 @@ def run(plotIt=True, saveFig=False, cleanup=True):
     reg.alpha_x = 1.0
     opt.LSshorten = 0.5
     opt.remember("xc")
-    reg.mref = mopt_re  # Use RESOLVE model as a reference model
+    reg.reference_model = mopt_re  # Use RESOLVE model as a reference model
 
     # run the inversion
     mopt_sky = inv.run(m0)
diff --git a/examples/20-published/plot_booky_1Dstitched_resolve_inv.py b/examples/20-published/plot_booky_1Dstitched_resolve_inv.py
index fc10a3317..dbdff9966 100644
--- a/examples/20-published/plot_booky_1Dstitched_resolve_inv.py
+++ b/examples/20-published/plot_booky_1Dstitched_resolve_inv.py
@@ -127,7 +127,7 @@ def resolve_1Dinversions(
     # regularization
     regMesh = discretize.TensorMesh([mesh.h[2][mapping.maps[-1].indActive]])
     reg = regularization.WeightedLeastSquares(regMesh)
-    reg.mref = mref
+    reg.reference_model = mref
 
     # optimization
     opt = optimization.InexactGaussNewton(maxIter=10)
diff --git a/examples/20-published/plot_laguna_del_maule_inversion.py b/examples/20-published/plot_laguna_del_maule_inversion.py
index 0edd61c3c..d124efa9d 100644
--- a/examples/20-published/plot_laguna_del_maule_inversion.py
+++ b/examples/20-published/plot_laguna_del_maule_inversion.py
@@ -96,9 +96,9 @@ def run(plotIt=True, cleanAfterRun=True):
 
     # %% Create inversion objects
     reg = regularization.Sparse(
-        mesh, active_cells=active, mapping=staticCells, gradientType="total"
+        mesh, active_cells=active, mapping=staticCells, gradient_type="total"
     )
-    reg.mref = driver.mref[dynamic]
+    reg.reference_model = driver.mref[dynamic]
 
     reg.norms = [0.0, 1.0, 1.0, 1.0]
     # reg.norms = driver.lpnorms
diff --git a/examples/_archived/plot_inv_dcip_dipoledipole_2_5Dinversion_irls.py b/examples/_archived/plot_inv_dcip_dipoledipole_2_5Dinversion_irls.py
index b6c67f0fb..8c3238670 100644
--- a/examples/_archived/plot_inv_dcip_dipoledipole_2_5Dinversion_irls.py
+++ b/examples/_archived/plot_inv_dcip_dipoledipole_2_5Dinversion_irls.py
@@ -155,9 +155,8 @@ def run(plotIt=True, survey_type="dipole-dipole", p=0.0, qx=2.0, qz=2.0):
 
     # Related to inversion
     reg = regularization.Sparse(
-        mesh, active_cells=actind, mapping=regmap, gradientType="components"
+        mesh, active_cells=actind, mapping=regmap, gradient_type="components"
     )
-    #     gradientType = 'components'
     reg.norms = [p, qx, qz, 0.0]
     IRLS = directives.Update_IRLS(
         max_irls_iterations=20, minGNiter=1, beta_search=False, fix_Jmatrix=True
diff --git a/tutorials/05-dcr/plot_inv_2_dcr2d_irls.py b/tutorials/05-dcr/plot_inv_2_dcr2d_irls.py
index 50ad50e10..d72de43fb 100644
--- a/tutorials/05-dcr/plot_inv_2_dcr2d_irls.py
+++ b/tutorials/05-dcr/plot_inv_2_dcr2d_irls.py
@@ -305,7 +305,7 @@ reg = regularization.Sparse(
     active_cells=ind_active,
     reference_model=starting_conductivity_model,
     mapping=regmap,
-    gradientType="total",
+    gradient_type="total",
     alpha_s=0.01,
     alpha_x=1,
     alpha_y=1,
diff --git a/tutorials/07-fdem/plot_inv_1_em1dfm.py b/tutorials/07-fdem/plot_inv_1_em1dfm.py
index 8c58fc7ad..2d566f06a 100644
--- a/tutorials/07-fdem/plot_inv_1_em1dfm.py
+++ b/tutorials/07-fdem/plot_inv_1_em1dfm.py
@@ -238,7 +238,7 @@ reg_map = maps.IdentityMap(nP=mesh.nC)
 reg = regularization.Sparse(mesh, mapping=reg_map, alpha_s=0.025, alpha_x=1.0)
 
 # reference model
-reg.mref = starting_model
+reg.reference_model = starting_model
 
 # Define sparse and blocky norms p, q
 reg.norms = [0, 0]
diff --git a/tutorials/08-tdem/plot_inv_1_em1dtm.py b/tutorials/08-tdem/plot_inv_1_em1dtm.py
index ae188747c..535f64674 100644
--- a/tutorials/08-tdem/plot_inv_1_em1dtm.py
+++ b/tutorials/08-tdem/plot_inv_1_em1dtm.py
@@ -227,7 +227,7 @@ reg_map = maps.IdentityMap(nP=mesh.nC)
 reg = regularization.Sparse(mesh, mapping=reg_map, alpha_s=0.01, alpha_x=1.0)
 
 # set reference model
-reg.mref = starting_model
+reg.reference_model = starting_model
 
 # Define sparse and blocky norms p, q
 reg.norms = [1, 0]


Test patch:
diff --git a/tests/base/test_regularization.py b/tests/base/test_regularization.py
index c50a4a83a..4150aba4f 100644
--- a/tests/base/test_regularization.py
+++ b/tests/base/test_regularization.py
@@ -9,6 +9,8 @@ from SimPEG import maps, objective_function, regularization, utils
 from SimPEG.regularization import (
     BaseRegularization,
     WeightedLeastSquares,
+    Sparse,
+    SparseSmoothness,
     Smallness,
     SmoothnessFirstOrder,
     SmoothnessSecondOrder,
@@ -91,7 +93,7 @@ class RegularizationTests(unittest.TestCase):
                     else:
                         m = np.random.rand(mesh.nC)
                     mref = np.ones_like(m) * np.mean(m)
-                    reg.mref = mref
+                    reg.reference_model = mref
 
                     # test derivs
                     passed = reg.test(m, eps=TOL)
@@ -764,6 +766,9 @@ class TestRemovedObjects:
     access removed properties.
 
     * ``indActive`` (replaced by ``active_cells``)
+    * ``gradientType`` (replaced by ``gradient_type``)
+    * ``mref`` (replaced by ``reference_model``)
+    * ``regmesh`` (replaced by ``regularization_mesh``)
     * ``cell_weights`` (replaced by ``weights``)
 
     """
@@ -782,6 +787,33 @@ class TestRemovedObjects:
             h = [h_i / h_i.sum() for h_i in (hx, hy, hz)]
         return discretize.TensorMesh(h)
 
+    @pytest.mark.parametrize(
+        "regularization_class", (BaseRegularization, WeightedLeastSquares)
+    )
+    def test_mref_property(self, mesh, regularization_class):
+        """Test mref property."""
+        msg = "mref has been removed, please use reference_model."
+        reg = regularization_class(mesh)
+        with pytest.raises(NotImplementedError, match=msg):
+            reg.mref
+
+    def test_regmesh_property(self, mesh):
+        """Test regmesh property."""
+        msg = "regmesh has been removed, please use regularization_mesh."
+        reg = BaseRegularization(mesh)
+        with pytest.raises(NotImplementedError, match=msg):
+            reg.regmesh
+
+    @pytest.mark.parametrize("regularization_class", (Sparse, SparseSmoothness))
+    def test_gradient_type(self, mesh, regularization_class):
+        """Test gradientType argument."""
+        msg = (
+            "'gradientType' argument has been removed. "
+            "Please use 'gradient_type' instead."
+        )
+        with pytest.raises(TypeError, match=msg):
+            regularization_class(mesh, gradientType="total")
+
     @pytest.mark.parametrize(
         "regularization_class",
         (BaseRegularization, WeightedLeastSquares),
diff --git a/tests/dask/test_mag_MVI_Octree.py b/tests/dask/test_mag_MVI_Octree.py
index 3c7305f55..37b878374 100644
--- a/tests/dask/test_mag_MVI_Octree.py
+++ b/tests/dask/test_mag_MVI_Octree.py
@@ -118,16 +118,16 @@ class MVIProblemTest(unittest.TestCase):
         # Create three regularization for the different components
         # of magnetization
         reg_p = regularization.Sparse(mesh, active_cells=actv, mapping=wires.p)
-        reg_p.mref = np.zeros(3 * nC)
+        reg_p.reference_model = np.zeros(3 * nC)
 
         reg_s = regularization.Sparse(mesh, active_cells=actv, mapping=wires.s)
-        reg_s.mref = np.zeros(3 * nC)
+        reg_s.reference_model = np.zeros(3 * nC)
 
         reg_t = regularization.Sparse(mesh, active_cells=actv, mapping=wires.t)
-        reg_t.mref = np.zeros(3 * nC)
+        reg_t.reference_model = np.zeros(3 * nC)
 
         reg = reg_p + reg_s + reg_t
-        reg.mref = np.zeros(3 * nC)
+        reg.reference_model = np.zeros(3 * nC)
 
         # Data misfit function
         dmis = data_misfit.L2DataMisfit(simulation=sim, data=data)
@@ -173,7 +173,7 @@ class MVIProblemTest(unittest.TestCase):
         # Regularize the amplitude of the vectors
         reg_a = regularization.Sparse(mesh, active_cells=actv, mapping=wires.amp)
         reg_a.norms = [0.0, 0.0, 0.0, 0.0]  # Sparse on the model and its gradients
-        reg_a.mref = np.zeros(3 * nC)
+        reg_a.reference_model = np.zeros(3 * nC)
 
         # Regularize the vertical angle of the vectors
         reg_t = regularization.Sparse(mesh, active_cells=actv, mapping=wires.theta)
@@ -188,7 +188,7 @@ class MVIProblemTest(unittest.TestCase):
         reg_p.norms = [2.0, 0.0, 0.0, 0.0]  # Only norm on gradients used
 
         reg = reg_a + reg_t + reg_p
-        reg.mref = np.zeros(3 * nC)
+        reg.reference_model = np.zeros(3 * nC)
 
         Lbound = np.kron(np.asarray([0, -np.inf, -np.inf]), np.ones(nC))
         Ubound = np.kron(np.asarray([10, np.inf, np.inf]), np.ones(nC))
diff --git a/tests/dask/test_mag_nonLinear_Amplitude.py b/tests/dask/test_mag_nonLinear_Amplitude.py
index 1f9109d40..758db82d0 100644
--- a/tests/dask/test_mag_nonLinear_Amplitude.py
+++ b/tests/dask/test_mag_nonLinear_Amplitude.py
@@ -144,7 +144,7 @@ class AmpProblemTest(unittest.TestCase):
         reg = regularization.Sparse(
             mesh, active_cells=surf, mapping=maps.IdentityMap(nP=nC), alpha_z=0
         )
-        reg.mref = np.zeros(nC)
+        reg.reference_model = np.zeros(nC)
 
         # Specify how the optimization will proceed, set susceptibility bounds to inf
         opt = optimization.ProjectedGNCG(
@@ -237,7 +237,7 @@ class AmpProblemTest(unittest.TestCase):
         # Create a sparse regularization
         reg = regularization.Sparse(mesh, active_cells=actv, mapping=idenMap)
         reg.norms = [1, 0, 0, 0]
-        reg.mref = np.zeros(nC)
+        reg.reference_model = np.zeros(nC)
 
         # Data misfit function
         dmis = data_misfit.L2DataMisfit(simulation=simulation, data=data_obj)
diff --git a/tests/pf/test_mag_inversion_linear.py b/tests/pf/test_mag_inversion_linear.py
index 2da13bf2f..bf7e10dba 100644
--- a/tests/pf/test_mag_inversion_linear.py
+++ b/tests/pf/test_mag_inversion_linear.py
@@ -103,7 +103,7 @@ class MagInvLinProblemTest(unittest.TestCase):
         # Create a regularization
         reg = regularization.Sparse(self.mesh, active_cells=actv, mapping=idenMap)
         reg.norms = [0, 0, 0, 0]
-        reg.gradientType = "components"
+        reg.gradient_type = "components"
 
         # Data misfit function
         dmis = data_misfit.L2DataMisfit(simulation=sim, data=data)
diff --git a/tests/pf/test_mag_inversion_linear_Octree.py b/tests/pf/test_mag_inversion_linear_Octree.py
index 64ce31e0b..8167bf1e1 100644
--- a/tests/pf/test_mag_inversion_linear_Octree.py
+++ b/tests/pf/test_mag_inversion_linear_Octree.py
@@ -117,7 +117,7 @@ class MagInvLinProblemTest(unittest.TestCase):
         # Create a regularization
         reg = regularization.Sparse(self.mesh, active_cells=actv, mapping=idenMap)
         reg.norms = [0, 0, 0, 0]
-        reg.mref = np.zeros(nC)
+        reg.reference_model = np.zeros(nC)
 
         # Data misfit function
         dmis = data_misfit.L2DataMisfit(simulation=sim, data=data)
diff --git a/tests/pf/test_mag_nonLinear_Amplitude.py b/tests/pf/test_mag_nonLinear_Amplitude.py
index 015aa8bfe..85f27266d 100644
--- a/tests/pf/test_mag_nonLinear_Amplitude.py
+++ b/tests/pf/test_mag_nonLinear_Amplitude.py
@@ -143,7 +143,7 @@ class AmpProblemTest(unittest.TestCase):
         reg = regularization.Sparse(
             mesh, active_cells=surf, mapping=maps.IdentityMap(nP=nC), alpha_z=0
         )
-        reg.mref = np.zeros(nC)
+        reg.reference_model = np.zeros(nC)
 
         # Specify how the optimization will proceed, set susceptibility bounds to inf
         opt = optimization.ProjectedGNCG(
@@ -236,7 +236,7 @@ class AmpProblemTest(unittest.TestCase):
         # Create a sparse regularization
         reg = regularization.Sparse(mesh, active_cells=actv, mapping=idenMap)
         reg.norms = [1, 0, 0, 0]
-        reg.mref = np.zeros(nC)
+        reg.reference_model = np.zeros(nC)
 
         # Data misfit function
         dmis = data_misfit.L2DataMisfit(simulation=simulation, data=data_obj)