From 6374e476478a559b163dcd7c41a7efc3e96a016a Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Tue, 23 Nov 2021 14:43:24 -0500 Subject: [PATCH 01/10] Add LabelVariable Useful for, e.g., https://pages.nist.gov/pfhub/benchmarks/benchmark8.ipynb --- fipy/variables/labelVariable.py | 74 +++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 fipy/variables/labelVariable.py diff --git a/fipy/variables/labelVariable.py b/fipy/variables/labelVariable.py new file mode 100644 index 0000000000..2fa3132585 --- /dev/null +++ b/fipy/variables/labelVariable.py @@ -0,0 +1,74 @@ +from __future__ import unicode_literals +__docformat__ = 'restructuredtext' + +from fipy.variables.cellVariable import CellVariable + +__all__ = ["LabelVariable"] +from future.utils import text_to_native_str +__all__ = [text_to_native_str(n) for n in __all__] + +from scipy import ndimage + +class LabelVariable(CellVariable): + """Label features in `var` using scipy.ndimage.label + + Parameters + ---------- + var : ~fipy.variables.cellVariable.CellVariable + Field to be labeled. Any non-zero values in input are counted as + features and zero values are considered the background. + + .. important: + Only sensible if `var` is defined on a `...Grid...` Mesh. + structure : array_like, optional + A structuring element that defines feature connections. + `structure` must be centrosymmetric + (see ```scipy.ndimage.label`` Notes + `_). + If no structuring element is provided, + one is automatically generated with a squared connectivity equal to + one. That is, for a 2-D `input` array, the default structuring element + is:: + [[0,1,0], + [1,1,1], + [0,1,0]] + dtype : date-type, optional + The desired data-type for the labels. Note that the type must be able + to store the largest label, or this Variable will raise an Exception. + Default: int. + """ + def __init__(self, var, structure=None, dtype=int): + # We want our value to hold dtype, + # but if we pass an array, the CellVariable + # will probably be wonky + value = fp.numerix.array(0.).astype(dtype).item() + fp.CellVariable.__init__(self, + mesh=var.mesh, + value=value, + elementshape=var.shape[:-1]) + self.var = self._requires(var) + self.structure = structure + self.dtype = dtype + self._num_features = None + + def _calcValue(self): + """Label features of `var` + + Side-effect: sets self._num_features + """ + arr = self.var.globalValue.astype(self.dtype) + shape = (self.var.mesh.args['nx'], self.var.mesh.args['ny']) + arr = arr.reshape(shape) + self._num_features = ndimage.label(input=arr, + structure=self.structure, + output=arr) + return arr.flat + + @property + def num_features(self): + """How many objects were found + """ + if self.stale or not self._isCached() or self._num_features is None: + self._getValue() + + return self._num_features From 5b86e0be0542b659e0a0d170cd876bd4c52ae83d Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Fri, 3 Dec 2021 21:07:29 -0500 Subject: [PATCH 02/10] Fix initialization so that it actually works Imports were messed up and never tested --- fipy/variables/labelVariable.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/fipy/variables/labelVariable.py b/fipy/variables/labelVariable.py index 2fa3132585..2970a43e10 100644 --- a/fipy/variables/labelVariable.py +++ b/fipy/variables/labelVariable.py @@ -2,13 +2,12 @@ __docformat__ = 'restructuredtext' from fipy.variables.cellVariable import CellVariable +from fipy.tools import numerix __all__ = ["LabelVariable"] from future.utils import text_to_native_str __all__ = [text_to_native_str(n) for n in __all__] -from scipy import ndimage - class LabelVariable(CellVariable): """Label features in `var` using scipy.ndimage.label @@ -37,15 +36,16 @@ class LabelVariable(CellVariable): to store the largest label, or this Variable will raise an Exception. Default: int. """ - def __init__(self, var, structure=None, dtype=int): + def __init__(self, var, name="", structure=None, dtype=int): # We want our value to hold dtype, # but if we pass an array, the CellVariable # will probably be wonky - value = fp.numerix.array(0.).astype(dtype).item() - fp.CellVariable.__init__(self, - mesh=var.mesh, - value=value, - elementshape=var.shape[:-1]) + value = numerix.array(0.).astype(dtype).item() + CellVariable.__init__(self, + mesh=var.mesh, + name=name, + value=value, + elementshape=var.shape[:-1]) self.var = self._requires(var) self.structure = structure self.dtype = dtype From b677b42226ed059e3a003cd1a634573b012d127e Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Fri, 3 Dec 2021 21:10:17 -0500 Subject: [PATCH 03/10] Label Variable of any type and any dimension --- fipy/variables/labelVariable.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/fipy/variables/labelVariable.py b/fipy/variables/labelVariable.py index 2970a43e10..83cdcb1128 100644 --- a/fipy/variables/labelVariable.py +++ b/fipy/variables/labelVariable.py @@ -56,13 +56,16 @@ def _calcValue(self): Side-effect: sets self._num_features """ - arr = self.var.globalValue.astype(self.dtype) - shape = (self.var.mesh.args['nx'], self.var.mesh.args['ny']) - arr = arr.reshape(shape) - self._num_features = ndimage.label(input=arr, + from scipy import ndimage + + feat = self.var.globalValue + feat = feat.reshape(self.var.mesh.shape[::-1]) + + arr = numerix.empty(self.var.mesh.shape[::-1], dtype=self.dtype) + self._num_features = ndimage.label(input=feat, structure=self.structure, output=arr) - return arr.flat + return arr.flatten() @property def num_features(self): From 126dfe2b63b076d06d7123b5d3599b56acd75525 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Fri, 3 Dec 2021 21:13:10 -0500 Subject: [PATCH 04/10] Add doctests to LabelVariable --- fipy/variables/labelVariable.py | 167 ++++++++++++++++++++++++++++++++ fipy/variables/test.py | 3 +- 2 files changed, 169 insertions(+), 1 deletion(-) diff --git a/fipy/variables/labelVariable.py b/fipy/variables/labelVariable.py index 83cdcb1128..368d1e512a 100644 --- a/fipy/variables/labelVariable.py +++ b/fipy/variables/labelVariable.py @@ -11,6 +11,166 @@ class LabelVariable(CellVariable): """Label features in `var` using scipy.ndimage.label + >>> import fipy as fp + + Create a 1D domain with two distinct non-zero regions. + + >>> mesh = fp.Grid1D(nx=5) + + >>> features = fp.CellVariable(mesh=mesh, name="features") + >>> features.setValue(1., where=(mesh.x > 1) & (mesh.x < 3)) + >>> features.setValue(0.5, where=(mesh.x > 4) & (mesh.x < 5)) + >>> print(features.value) + [ 0. 1. 1. 0. 0.5] + + Label the non-zero regions. + + >>> labels = fp.LabelVariable(features, name="labels") + >>> print(labels.num_features) + 2 + >>> print(labels) + [0 1 1 0 2] + + To have no connectivity between cells, we can assign a structure with + no neighbors. + + >>> labels = fp.LabelVariable(features, structure=[0,1,0], + ... name="labels") + >>> print(labels.num_features) + 3 + >>> print(labels) + [0 1 2 0 3] + + Similarly, create a 2D domain with two distinct non-zero regions. + + >>> mesh = fp.Grid2D(nx=5, ny=5) + + >>> features = fp.CellVariable(mesh=mesh, name="features") + >>> features.setValue(1., where=((mesh.x > 1) & (mesh.x < 3) + ... & (mesh.y > 1) & (mesh.y < 3))) + >>> features.setValue(0.5, where=((mesh.x > 3) & (mesh.x < 4) + ... & (mesh.y > 3) & (mesh.y < 4))) + + Note that FiPy arranges its gridded cells in a right-handed Cartesian + fashion, with x increasing to the right, y increasing up, and z + increasing toward you. Conversely, NumPy arrays and ndimages are + arranged in stacks of increasing z, each consisting of rows of + increasing y, each element of which increases in x. As a result, we + reverse FiPy's (x,y) shape to NumPy's (y, x): + + >>> print(features.value.reshape(mesh.shape[::-1])) + [[ 0. 0. 0. 0. 0. ] + [ 0. 1. 1. 0. 0. ] + [ 0. 1. 1. 0. 0. ] + [ 0. 0. 0. 0.5 0. ] + [ 0. 0. 0. 0. 0. ]] + + >>> labels = fp.LabelVariable(features, name="labels") + >>> print(labels.num_features) + 2 + >>> print(labels.value.reshape(mesh.shape[::-1])) + [[0 0 0 0 0] + [0 1 1 0 0] + [0 1 1 0 0] + [0 0 0 2 0] + [0 0 0 0 0]] + + By default, the two domains are seen as unconnected because there is no + overlap of cells along either the x or y axis. The following structure + creates connectivity along one diagonal, but not the other. Note that + the structure array follows NumPy (y, x) ordering, rather than FiPy (x, + y) ordering. + + >>> labels = fp.LabelVariable(features, structure=[[1,1,0], + ... [1,1,1], + ... [0,1,1]], + ... name="labels") + >>> print(labels.num_features) + 1 + >>> print(labels.value.reshape(mesh.shape[::-1])) + [[0 0 0 0 0] + [0 1 1 0 0] + [0 1 1 0 0] + [0 0 0 1 0] + [0 0 0 0 0]] + + Similarly, create a 3D domain with three distinct non-zero regions. + + >>> mesh = fp.Grid3D(nx=3, ny=3, nz=3) + + >>> features = fp.CellVariable(mesh=mesh, name="features") + >>> features.setValue(1., where=((mesh.x > 0) & (mesh.x < 2) + ... & (mesh.y > 0) & (mesh.y < 2) + ... & (mesh.z > 0) & (mesh.z < 2))) + >>> features.setValue(0.7, where=((mesh.x > 2) & (mesh.x < 3) + ... & (mesh.y > 2) & (mesh.y < 3) + ... & (mesh.z > 0) & (mesh.z < 1))) + >>> features.setValue(0.5, where=((mesh.x > 2) & (mesh.x < 3) + ... & (mesh.y > 2) & (mesh.y < 3) + ... & (mesh.z > 2) & (mesh.z < 3))) + + We reverse FiPy's (x,y, z) shape to NumPy's (z, y, x) + + >>> print(features.value.reshape(mesh.shape[::-1])) + [[[ 1. 1. 0. ] + [ 1. 1. 0. ] + [ 0. 0. 0.7]] + + [[ 1. 1. 0. ] + [ 1. 1. 0. ] + [ 0. 0. 0. ]] + + [[ 0. 0. 0. ] + [ 0. 0. 0. ] + [ 0. 0. 0.5]]] + + >>> labels = fp.LabelVariable(features, name="labels") + >>> print(labels.num_features) + 3 + >>> print(labels.value.reshape(mesh.shape[::-1])) + [[[1 1 0] + [1 1 0] + [0 0 2]] + + [[1 1 0] + [1 1 0] + [0 0 0]] + + [[0 0 0] + [0 0 0] + [0 0 3]]] + + By default, the three domains are seen as unconnected because there is + no overlap of cells along any of the x, y, or z axes. The following + structure creates connectivity along one major diagonal, but not the + other two. Note that the structure array follows NumPy (z, y, x) + ordering, rather than FiPy (x, y, z) ordering. + + >>> labels = fp.LabelVariable(features, structure=[[[1,0,0], + ... [0,1,0], + ... [0,0,0]], + ... [[0,1,0], + ... [1,1,1], + ... [0,1,0]], + ... [[0,0,0], + ... [0,1,0], + ... [0,0,1]]], + ... name="labels") + >>> print(labels.num_features) + 2 + >>> print(labels.value.reshape(mesh.shape[::-1])) + [[[1 1 0] + [1 1 0] + [0 0 2]] + + [[1 1 0] + [1 1 0] + [0 0 0]] + + [[0 0 0] + [0 0 0] + [0 0 1]]] + Parameters ---------- var : ~fipy.variables.cellVariable.CellVariable @@ -75,3 +235,10 @@ def num_features(self): self._getValue() return self._num_features + +def _test(): + import fipy.tests.doctestPlus + return fipy.tests.doctestPlus.testmod() + +if __name__ == "__main__": + _test() diff --git a/fipy/variables/test.py b/fipy/variables/test.py index 8c500f16fa..390503d2f4 100755 --- a/fipy/variables/test.py +++ b/fipy/variables/test.py @@ -31,7 +31,8 @@ def _suite(): 'fipy.variables.surfactantConvectionVariable', 'fipy.variables.surfactantVariable', 'fipy.variables.levelSetDiffusionVariable', - 'fipy.variables.distanceVariable' + 'fipy.variables.distanceVariable', + 'fipy.variables.labelVariable' )) if __name__ == '__main__': From dd5822a62f34d294aebc0de937f9df823ebf799e Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Fri, 3 Dec 2021 21:14:12 -0500 Subject: [PATCH 05/10] Add LabelVariable to imports --- fipy/variables/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fipy/variables/__init__.py b/fipy/variables/__init__.py index f3c7094ba0..b55464b2a8 100644 --- a/fipy/variables/__init__.py +++ b/fipy/variables/__init__.py @@ -12,6 +12,7 @@ from fipy.variables.surfactantVariable import * from fipy.variables.surfactantConvectionVariable import * from fipy.variables.distanceVariable import * +from fipy.variables.labelVariable import * __all__ = [] __all__.extend(variable.__all__) @@ -28,3 +29,4 @@ __all__.extend(surfactantVariable.__all__) __all__.extend(surfactantConvectionVariable.__all__) __all__.extend(distanceVariable.__all__) +__all__.extend(labelVariable.__all__) From afbd79e1687ea1c20f75f64cdfdf1410ce4cf89c Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Fri, 3 Dec 2021 22:21:38 -0500 Subject: [PATCH 06/10] Factor out transformation of gridded CellVariable to ndimage --- fipy/variables/cellVariable.py | 36 +++++++++++++++++++++++++++++++++ fipy/variables/labelVariable.py | 27 +++++++++---------------- 2 files changed, 45 insertions(+), 18 deletions(-) diff --git a/fipy/variables/cellVariable.py b/fipy/variables/cellVariable.py index 86f32fa24c..2c304b1e55 100644 --- a/fipy/variables/cellVariable.py +++ b/fipy/variables/cellVariable.py @@ -130,6 +130,42 @@ def globalValue(self): return self._getGlobalValue(self.mesh._localNonOverlappingCellIDs, self.mesh._globalNonOverlappingCellIDs) + @property + def ndimage(self): + """Global value as an ndarray suitable for scipy.ndimage + + The cell values of a `CellVariable` are stored in a 1D ndarray. + FiPy arranges its gridded cells in a right-handed Cartesian + fashion, with x increasing to the right, y increasing up, and z + increasing toward you. Conversely, NumPy arrays and ndimages are + arranged in stacks of increasing z, each consisting of rows of + increasing y, each element of which increases in x. As a result, we + reverse FiPy's (x,y,z) shape to NumPy's (z,y,x). + + >>> import fipy as fp + >>> mesh = fp.Grid2D(nx=2, ny=3) + >>> var = fp.CellVariable(mesh=mesh, value=mesh.x * mesh.y) + >>> print(var.ndimage) + [[0.25 0.75] + [0.75 2.25] + [1.25 3.75]] + + Returns + ------- + ndarray + Shape of mesh grid + + Note + ---- + Only suitable for a `CellVariable` defined on a `Grid?D` mesh. + """ + try: + shape = self.mesh.shape[::-1] + except AttributeError: + raise TypeError("Only CellVariables defined on a Grid mesh can " + "be represented as an ndimage") + return self.globalValue.reshape(shape) + def setValue(self, value, unit = None, where = None): _MeshVariable.setValue(self, value=self._globalToLocalValue(value), unit=unit, where=where) diff --git a/fipy/variables/labelVariable.py b/fipy/variables/labelVariable.py index 368d1e512a..30ae2701e6 100644 --- a/fipy/variables/labelVariable.py +++ b/fipy/variables/labelVariable.py @@ -20,7 +20,7 @@ class LabelVariable(CellVariable): >>> features = fp.CellVariable(mesh=mesh, name="features") >>> features.setValue(1., where=(mesh.x > 1) & (mesh.x < 3)) >>> features.setValue(0.5, where=(mesh.x > 4) & (mesh.x < 5)) - >>> print(features.value) + >>> print(features.ndimage) [ 0. 1. 1. 0. 0.5] Label the non-zero regions. @@ -28,7 +28,7 @@ class LabelVariable(CellVariable): >>> labels = fp.LabelVariable(features, name="labels") >>> print(labels.num_features) 2 - >>> print(labels) + >>> print(labels.ndimage) [0 1 1 0 2] To have no connectivity between cells, we can assign a structure with @@ -38,7 +38,7 @@ class LabelVariable(CellVariable): ... name="labels") >>> print(labels.num_features) 3 - >>> print(labels) + >>> print(labels.ndimage) [0 1 2 0 3] Similarly, create a 2D domain with two distinct non-zero regions. @@ -51,14 +51,7 @@ class LabelVariable(CellVariable): >>> features.setValue(0.5, where=((mesh.x > 3) & (mesh.x < 4) ... & (mesh.y > 3) & (mesh.y < 4))) - Note that FiPy arranges its gridded cells in a right-handed Cartesian - fashion, with x increasing to the right, y increasing up, and z - increasing toward you. Conversely, NumPy arrays and ndimages are - arranged in stacks of increasing z, each consisting of rows of - increasing y, each element of which increases in x. As a result, we - reverse FiPy's (x,y) shape to NumPy's (y, x): - - >>> print(features.value.reshape(mesh.shape[::-1])) + >>> print(features.ndimage) [[ 0. 0. 0. 0. 0. ] [ 0. 1. 1. 0. 0. ] [ 0. 1. 1. 0. 0. ] @@ -68,7 +61,7 @@ class LabelVariable(CellVariable): >>> labels = fp.LabelVariable(features, name="labels") >>> print(labels.num_features) 2 - >>> print(labels.value.reshape(mesh.shape[::-1])) + >>> print(labels.ndimage) [[0 0 0 0 0] [0 1 1 0 0] [0 1 1 0 0] @@ -87,7 +80,7 @@ class LabelVariable(CellVariable): ... name="labels") >>> print(labels.num_features) 1 - >>> print(labels.value.reshape(mesh.shape[::-1])) + >>> print(labels.ndimage) [[0 0 0 0 0] [0 1 1 0 0] [0 1 1 0 0] @@ -109,9 +102,7 @@ class LabelVariable(CellVariable): ... & (mesh.y > 2) & (mesh.y < 3) ... & (mesh.z > 2) & (mesh.z < 3))) - We reverse FiPy's (x,y, z) shape to NumPy's (z, y, x) - - >>> print(features.value.reshape(mesh.shape[::-1])) + >>> print(features.ndimage) [[[ 1. 1. 0. ] [ 1. 1. 0. ] [ 0. 0. 0.7]] @@ -127,7 +118,7 @@ class LabelVariable(CellVariable): >>> labels = fp.LabelVariable(features, name="labels") >>> print(labels.num_features) 3 - >>> print(labels.value.reshape(mesh.shape[::-1])) + >>> print(labels.ndimage) [[[1 1 0] [1 1 0] [0 0 2]] @@ -158,7 +149,7 @@ class LabelVariable(CellVariable): ... name="labels") >>> print(labels.num_features) 2 - >>> print(labels.value.reshape(mesh.shape[::-1])) + >>> print(labels.ndimage) [[[1 1 0] [1 1 0] [0 0 2]] From 1c19a17ed893951a23cad398b3ceae2178045faa Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Fri, 3 Dec 2021 22:24:36 -0500 Subject: [PATCH 07/10] Reformat doctest --- fipy/variables/labelVariable.py | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/fipy/variables/labelVariable.py b/fipy/variables/labelVariable.py index 30ae2701e6..bbf3d333c3 100644 --- a/fipy/variables/labelVariable.py +++ b/fipy/variables/labelVariable.py @@ -34,7 +34,8 @@ class LabelVariable(CellVariable): To have no connectivity between cells, we can assign a structure with no neighbors. - >>> labels = fp.LabelVariable(features, structure=[0,1,0], + >>> labels = fp.LabelVariable(features, + ... structure=[0,1,0], ... name="labels") >>> print(labels.num_features) 3 @@ -74,10 +75,11 @@ class LabelVariable(CellVariable): the structure array follows NumPy (y, x) ordering, rather than FiPy (x, y) ordering. - >>> labels = fp.LabelVariable(features, structure=[[1,1,0], - ... [1,1,1], - ... [0,1,1]], - ... name="labels") + >>> labels = fp.LabelVariable(features, + ... structure=[[1,1,0], + ... [1,1,1], + ... [0,1,1]], + ... name="labels") >>> print(labels.num_features) 1 >>> print(labels.ndimage) @@ -137,16 +139,17 @@ class LabelVariable(CellVariable): other two. Note that the structure array follows NumPy (z, y, x) ordering, rather than FiPy (x, y, z) ordering. - >>> labels = fp.LabelVariable(features, structure=[[[1,0,0], - ... [0,1,0], - ... [0,0,0]], - ... [[0,1,0], - ... [1,1,1], - ... [0,1,0]], - ... [[0,0,0], - ... [0,1,0], - ... [0,0,1]]], - ... name="labels") + >>> labels = fp.LabelVariable(features, + ... structure=[[[1,0,0], + ... [0,1,0], + ... [0,0,0]], + ... [[0,1,0], + ... [1,1,1], + ... [0,1,0]], + ... [[0,0,0], + ... [0,1,0], + ... [0,0,1]]], + ... name="labels") >>> print(labels.num_features) 2 >>> print(labels.ndimage) From e7cca1e76b1341c4e25fd04eec2f617d9babf97e Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Fri, 3 Dec 2021 22:45:19 -0500 Subject: [PATCH 08/10] Fix spelling --- fipy/variables/cellVariable.py | 13 +++++++------ fipy/variables/labelVariable.py | 4 ++-- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/fipy/variables/cellVariable.py b/fipy/variables/cellVariable.py index 2c304b1e55..a02f0aac64 100644 --- a/fipy/variables/cellVariable.py +++ b/fipy/variables/cellVariable.py @@ -132,15 +132,16 @@ def globalValue(self): @property def ndimage(self): - """Global value as an ndarray suitable for scipy.ndimage + """Global value as an `ndarray` suitable for `scipy.ndimage` - The cell values of a `CellVariable` are stored in a 1D ndarray. + The cell values of a `CellVariable` are stored in a 1D `ndarray. FiPy arranges its gridded cells in a right-handed Cartesian fashion, with x increasing to the right, y increasing up, and z - increasing toward you. Conversely, NumPy arrays and ndimages are - arranged in stacks of increasing z, each consisting of rows of - increasing y, each element of which increases in x. As a result, we - reverse FiPy's (x,y,z) shape to NumPy's (z,y,x). + increasing toward you. Conversely, NumPy arrays, particularly + `scipy.ndimage` arrays, are arranged in stacks of increasing z, + each consisting of rows of increasing y, each element of which + increases in x. As a result, we reverse FiPy's (x,y,z) shape to + NumPy's (z,y,x). >>> import fipy as fp >>> mesh = fp.Grid2D(nx=2, ny=3) diff --git a/fipy/variables/labelVariable.py b/fipy/variables/labelVariable.py index bbf3d333c3..d05ff35ced 100644 --- a/fipy/variables/labelVariable.py +++ b/fipy/variables/labelVariable.py @@ -9,7 +9,7 @@ __all__ = [text_to_native_str(n) for n in __all__] class LabelVariable(CellVariable): - """Label features in `var` using scipy.ndimage.label + """Label features in `var` using `scipy.ndimage.label` >>> import fipy as fp @@ -208,7 +208,7 @@ def __init__(self, var, name="", structure=None, dtype=int): def _calcValue(self): """Label features of `var` - Side-effect: sets self._num_features + Side-effect: sets :attr:`self._num_features`. """ from scipy import ndimage From 6a01a5300d2e7ac84ddb4cfc2284bc91a664ff34 Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Fri, 3 Dec 2021 22:47:14 -0500 Subject: [PATCH 09/10] Fix doctest whitespace --- fipy/variables/cellVariable.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fipy/variables/cellVariable.py b/fipy/variables/cellVariable.py index a02f0aac64..af2ccec989 100644 --- a/fipy/variables/cellVariable.py +++ b/fipy/variables/cellVariable.py @@ -147,9 +147,9 @@ def ndimage(self): >>> mesh = fp.Grid2D(nx=2, ny=3) >>> var = fp.CellVariable(mesh=mesh, value=mesh.x * mesh.y) >>> print(var.ndimage) - [[0.25 0.75] - [0.75 2.25] - [1.25 3.75]] + [[ 0.25 0.75] + [ 0.75 2.25] + [ 1.25 3.75]] Returns ------- From 021578a54605954c83af3f9037f445c98c9a0caf Mon Sep 17 00:00:00 2001 From: Jonathan Guyer Date: Tue, 1 Feb 2022 12:31:07 -0500 Subject: [PATCH 10/10] Fix typos --- fipy/variables/cellVariable.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fipy/variables/cellVariable.py b/fipy/variables/cellVariable.py index af2ccec989..f4a55574f2 100644 --- a/fipy/variables/cellVariable.py +++ b/fipy/variables/cellVariable.py @@ -134,7 +134,7 @@ def globalValue(self): def ndimage(self): """Global value as an `ndarray` suitable for `scipy.ndimage` - The cell values of a `CellVariable` are stored in a 1D `ndarray. + The cell values of a `CellVariable` are stored in a 1D `ndarray`. FiPy arranges its gridded cells in a right-handed Cartesian fashion, with x increasing to the right, y increasing up, and z increasing toward you. Conversely, NumPy arrays, particularly