Repository: permamodel/permamodel

Issue:
Update use of int for numpy>=1.24
In NumPy 1.24, `numpy.int` is replaced with `int`. This causes the Ku model to fail:
```
File ~/anaconda3/envs/pymt/lib/python3.10/site-packages/permamodel/components/Ku_method.py:788, in Ku_method.Extract_Soil_Texture2(self)
    784 lat = np.transpose(np.reshape(np.repeat(self.lat,n_lon), (n_lat,n_lon)));
    786 x_coords, y_coords = ~aff * (lon, lat)
--> 788 x_coords = np.round(x_coords).astype(np.int)
    789 y_coords = np.round(y_coords).astype(np.int)
    791 if np.size(x_coords) >= 1 and np.size(y_coords) >= 1:

File ~/anaconda3/envs/pymt/lib/python3.10/site-packages/numpy/__init__.py:284, in __getattr__(attr)
    281     from .testing import Tester
    282     return Tester
--> 284 raise AttributeError("module {!r} has no attribute "
    285                      "{!r}".format(__name__, attr))

AttributeError: module 'numpy' has no attribute 'int'
``` 

Discussion:

Patch:
diff --git a/permamodel/components/Ku_method.py b/permamodel/components/Ku_method.py
index feeb38a..5e5f174 100644
--- a/permamodel/components/Ku_method.py
+++ b/permamodel/components/Ku_method.py
@@ -844,8 +844,8 @@ class Ku_method(perma_base.PermafrostComponent):
 
         x_coords, y_coords = ~aff * (lon, lat)
 
-        x_coords = np.round(x_coords).astype(np.int)
-        y_coords = np.round(y_coords).astype(np.int)
+        x_coords = np.round(x_coords).astype(int)
+        y_coords = np.round(y_coords).astype(int)
 
         if np.size(x_coords) >= 1 and np.size(y_coords) >= 1:
             clay_perc0 = self.Clay_percent[y_coords, x_coords]
diff --git a/permamodel/components/frost_number_Geo.py b/permamodel/components/frost_number_Geo.py
index a7e2497..18f191c 100644
--- a/permamodel/components/frost_number_Geo.py
+++ b/permamodel/components/frost_number_Geo.py
@@ -447,80 +447,10 @@ class FrostnumberGeoMethod(perma_base.PermafrostComponent):
         for n in range(ngridlines):
             config_arg = eval(config["%s_grid_data_%d" % (gridname, n)])
             slicelist.append(np.array(config_arg))
-        # In NumPy 1.10 later, we can use np.stack()
-        # But for v1.09 -- which pip seems to install -- we need np.dstack()
-        # datacube = np.stack(slicelist)
-        datacube = self.np_stack(slicelist)
+        datacube = np.stack(slicelist)
 
         return datelist, datacube
 
-    def np_stack(self, arrays, axis=0):
-        """
-        In order to provide this function from numpy v1.10, this is copied
-        from:
-           https://github.com/numpy/numpy/blob/
-           f4cc58c80df5202a743bddd514a3485d5e4ec5a4/numpy/core/shape_base.py
-        Join a sequence of arrays along a new axis.
-        The `axis` parameter specifies the index of the new axis in the dimensions
-        of the result. For example, if ``axis=0`` it will be the first dimension
-        and if ``axis=-1`` it will be the last dimension.
-        .. versionadded:: 1.10.0
-        Parameters
-        ----------
-        arrays : sequence of array_like
-            Each array must have the same shape.
-        axis : int, optional
-            The axis in the result array along which the input arrays are stacked.
-        Returns
-        -------
-        stacked : ndarray
-            The stacked array has one more dimension than the input arrays.
-        See Also
-        --------
-        concatenate : Join a sequence of arrays along an existing axis.
-        split : Split array into a list of multiple sub-arrays of equal size.
-        Examples
-        Note: Replace '>>>' with '>>' so it doesn't doctest
-        --------
-        >> arrays = [np.random.randn(3, 4) for _ in range(10)]
-        >> np.stack(arrays, axis=0).shape
-        (10, 3, 4)
-        >> np.stack(arrays, axis=1).shape
-        (3, 10, 4)
-        >> np.stack(arrays, axis=2).shape
-        (3, 4, 10)
-        >> a = np.array([1, 2, 3])
-        >> b = np.array([2, 3, 4])
-        >> np.stack((a, b))
-        array([[1, 2, 3],
-               [2, 3, 4]])
-        >> np.stack((a, b), axis=-1)
-        array([[1, 2],
-               [2, 3],
-               [3, 4]])
-        """
-        arrays = [np.asanyarray(arr) for arr in arrays]
-        if not arrays:
-            raise ValueError("need at least one array to stack")
-
-        shapes = set(arr.shape for arr in arrays)
-        if len(shapes) != 1:
-            raise ValueError("all input arrays must have the same shape")
-
-        result_ndim = arrays[0].ndim + 1
-        if not -result_ndim <= axis < result_ndim:
-            msg = "axis {0} out of bounds [-{1}, {1})".format(axis, result_ndim)
-            raise IndexError(msg)
-        if axis < 0:
-            axis += result_ndim
-
-        sl = (slice(None),) * axis + (np.newaxis,)
-        expanded_arrays = [arr[sl] for arr in arrays]
-
-        # Changed name from that of copied code
-        # return _nx.concatenate(expanded_arrays, axis=axis)
-        return np.concatenate(expanded_arrays, axis=axis)
-
     def get_datacube_slice(self, thisdate, datacube, cubedates):
         # Data are invalid until the first date in the datacube
         if thisdate < cubedates[0]:


Test patch:
diff --git a/permamodel/tests/test_Ku_method.py b/permamodel/tests/test_Ku_method.py
new file mode 100644
index 0000000..9f8c429
--- /dev/null
+++ b/permamodel/tests/test_Ku_method.py
@@ -0,0 +1,41 @@
+"""Test Ku model"""
+import os
+
+import pytest
+
+from permamodel import examples_directory
+from permamodel.components.Ku_method import Ku_method
+
+CFG_FILENAME = "Ku_method.cfg"
+CFG_FILE = os.path.join(examples_directory, CFG_FILENAME)
+
+
+def test_instantiate_Ku():
+    m = Ku_method()
+    assert type(m) is Ku_method
+
+
+def test_not_initialized_Ku():
+    with pytest.raises(AttributeError):
+        m = Ku_method()
+        m.time
+
+
+def test_initialize_Ku():
+    m = Ku_method()
+    m.initialize(CFG_FILE)
+    assert m.time == 0.0
+
+
+# See #78
+# def test_update_Ku():
+#     m = Ku_method()
+#     m.initialize(CFG_FILE)
+#     m.update()
+#     assert m.time == 1.0
+
+
+def test_finalize_Ku():
+    m = Ku_method()
+    m.initialize(CFG_FILE)
+    m.finalize()