xtgeo 4.14.1__cp313-cp313-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cxtgeo.py +558 -0
- cxtgeoPYTHON_wrap.c +19537 -0
- xtgeo/__init__.py +248 -0
- xtgeo/_cxtgeo.cp313-win_amd64.pyd +0 -0
- xtgeo/_internal.cp313-win_amd64.pyd +0 -0
- xtgeo/common/__init__.py +19 -0
- xtgeo/common/_angles.py +29 -0
- xtgeo/common/_xyz_enum.py +50 -0
- xtgeo/common/calc.py +396 -0
- xtgeo/common/constants.py +30 -0
- xtgeo/common/exceptions.py +42 -0
- xtgeo/common/log.py +93 -0
- xtgeo/common/sys.py +166 -0
- xtgeo/common/types.py +18 -0
- xtgeo/common/version.py +34 -0
- xtgeo/common/xtgeo_dialog.py +604 -0
- xtgeo/cube/__init__.py +9 -0
- xtgeo/cube/_cube_export.py +214 -0
- xtgeo/cube/_cube_import.py +532 -0
- xtgeo/cube/_cube_roxapi.py +180 -0
- xtgeo/cube/_cube_utils.py +287 -0
- xtgeo/cube/_cube_window_attributes.py +273 -0
- xtgeo/cube/cube1.py +1023 -0
- xtgeo/grid3d/__init__.py +15 -0
- xtgeo/grid3d/_ecl_grid.py +778 -0
- xtgeo/grid3d/_ecl_inte_head.py +152 -0
- xtgeo/grid3d/_ecl_logi_head.py +71 -0
- xtgeo/grid3d/_ecl_output_file.py +81 -0
- xtgeo/grid3d/_egrid.py +1004 -0
- xtgeo/grid3d/_find_gridprop_in_eclrun.py +625 -0
- xtgeo/grid3d/_grdecl_format.py +309 -0
- xtgeo/grid3d/_grdecl_grid.py +400 -0
- xtgeo/grid3d/_grid3d.py +29 -0
- xtgeo/grid3d/_grid3d_fence.py +284 -0
- xtgeo/grid3d/_grid3d_utils.py +228 -0
- xtgeo/grid3d/_grid_boundary.py +76 -0
- xtgeo/grid3d/_grid_etc1.py +1683 -0
- xtgeo/grid3d/_grid_export.py +222 -0
- xtgeo/grid3d/_grid_hybrid.py +50 -0
- xtgeo/grid3d/_grid_import.py +79 -0
- xtgeo/grid3d/_grid_import_ecl.py +101 -0
- xtgeo/grid3d/_grid_import_roff.py +135 -0
- xtgeo/grid3d/_grid_import_xtgcpgeom.py +375 -0
- xtgeo/grid3d/_grid_refine.py +258 -0
- xtgeo/grid3d/_grid_roxapi.py +292 -0
- xtgeo/grid3d/_grid_translate_coords.py +154 -0
- xtgeo/grid3d/_grid_wellzone.py +165 -0
- xtgeo/grid3d/_gridprop_export.py +202 -0
- xtgeo/grid3d/_gridprop_import_eclrun.py +164 -0
- xtgeo/grid3d/_gridprop_import_grdecl.py +132 -0
- xtgeo/grid3d/_gridprop_import_roff.py +52 -0
- xtgeo/grid3d/_gridprop_import_xtgcpprop.py +168 -0
- xtgeo/grid3d/_gridprop_lowlevel.py +171 -0
- xtgeo/grid3d/_gridprop_op1.py +272 -0
- xtgeo/grid3d/_gridprop_roxapi.py +301 -0
- xtgeo/grid3d/_gridprop_value_init.py +140 -0
- xtgeo/grid3d/_gridprops_import_eclrun.py +344 -0
- xtgeo/grid3d/_gridprops_import_roff.py +83 -0
- xtgeo/grid3d/_roff_grid.py +470 -0
- xtgeo/grid3d/_roff_parameter.py +303 -0
- xtgeo/grid3d/grid.py +3010 -0
- xtgeo/grid3d/grid_properties.py +699 -0
- xtgeo/grid3d/grid_property.py +1313 -0
- xtgeo/grid3d/types.py +15 -0
- xtgeo/interfaces/rms/__init__.py +18 -0
- xtgeo/interfaces/rms/_regular_surface.py +460 -0
- xtgeo/interfaces/rms/_rms_base.py +100 -0
- xtgeo/interfaces/rms/_rmsapi_package.py +69 -0
- xtgeo/interfaces/rms/rmsapi_utils.py +438 -0
- xtgeo/io/__init__.py +1 -0
- xtgeo/io/_file.py +603 -0
- xtgeo/metadata/__init__.py +17 -0
- xtgeo/metadata/metadata.py +435 -0
- xtgeo/roxutils/__init__.py +7 -0
- xtgeo/roxutils/_roxar_loader.py +54 -0
- xtgeo/roxutils/_roxutils_etc.py +122 -0
- xtgeo/roxutils/roxutils.py +207 -0
- xtgeo/surface/__init__.py +20 -0
- xtgeo/surface/_regsurf_boundary.py +26 -0
- xtgeo/surface/_regsurf_cube.py +210 -0
- xtgeo/surface/_regsurf_cube_window.py +391 -0
- xtgeo/surface/_regsurf_cube_window_v2.py +297 -0
- xtgeo/surface/_regsurf_cube_window_v3.py +360 -0
- xtgeo/surface/_regsurf_export.py +388 -0
- xtgeo/surface/_regsurf_grid3d.py +275 -0
- xtgeo/surface/_regsurf_gridding.py +347 -0
- xtgeo/surface/_regsurf_ijxyz_parser.py +278 -0
- xtgeo/surface/_regsurf_import.py +347 -0
- xtgeo/surface/_regsurf_lowlevel.py +122 -0
- xtgeo/surface/_regsurf_oper.py +538 -0
- xtgeo/surface/_regsurf_utils.py +81 -0
- xtgeo/surface/_surfs_import.py +43 -0
- xtgeo/surface/_zmap_parser.py +138 -0
- xtgeo/surface/regular_surface.py +3043 -0
- xtgeo/surface/surfaces.py +276 -0
- xtgeo/well/__init__.py +24 -0
- xtgeo/well/_blockedwell_roxapi.py +241 -0
- xtgeo/well/_blockedwells_roxapi.py +68 -0
- xtgeo/well/_well_aux.py +30 -0
- xtgeo/well/_well_io.py +327 -0
- xtgeo/well/_well_oper.py +483 -0
- xtgeo/well/_well_roxapi.py +304 -0
- xtgeo/well/_wellmarkers.py +486 -0
- xtgeo/well/_wells_utils.py +158 -0
- xtgeo/well/blocked_well.py +220 -0
- xtgeo/well/blocked_wells.py +134 -0
- xtgeo/well/well1.py +1516 -0
- xtgeo/well/wells.py +211 -0
- xtgeo/xyz/__init__.py +6 -0
- xtgeo/xyz/_polygons_oper.py +272 -0
- xtgeo/xyz/_xyz.py +758 -0
- xtgeo/xyz/_xyz_data.py +646 -0
- xtgeo/xyz/_xyz_io.py +737 -0
- xtgeo/xyz/_xyz_lowlevel.py +42 -0
- xtgeo/xyz/_xyz_oper.py +613 -0
- xtgeo/xyz/_xyz_roxapi.py +766 -0
- xtgeo/xyz/points.py +698 -0
- xtgeo/xyz/polygons.py +827 -0
- xtgeo-4.14.1.dist-info/METADATA +146 -0
- xtgeo-4.14.1.dist-info/RECORD +122 -0
- xtgeo-4.14.1.dist-info/WHEEL +5 -0
- xtgeo-4.14.1.dist-info/licenses/LICENSE.md +165 -0
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
"""Regular surface vs Cube, slice a window interval v3, in pure numpy."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import warnings
|
|
6
|
+
from typing import TYPE_CHECKING
|
|
7
|
+
|
|
8
|
+
import numpy as np
|
|
9
|
+
|
|
10
|
+
from xtgeo.common.log import null_logger
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from xtgeo.cube.cube1 import Cube
|
|
14
|
+
|
|
15
|
+
from .regular_surface import RegularSurface
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
warnings.filterwarnings(action="ignore", message="All-NaN slice encountered")
|
|
19
|
+
warnings.filterwarnings(action="ignore", message="Mean of empty slice")
|
|
20
|
+
warnings.filterwarnings(action="ignore", message="Degree of freedom")
|
|
21
|
+
|
|
22
|
+
logger = null_logger(__name__)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
STATATTRS = [
|
|
26
|
+
"min",
|
|
27
|
+
"max",
|
|
28
|
+
"mean",
|
|
29
|
+
"var",
|
|
30
|
+
"rms",
|
|
31
|
+
"maxpos",
|
|
32
|
+
"maxneg",
|
|
33
|
+
"maxabs",
|
|
34
|
+
"meanabs",
|
|
35
|
+
"meanpos",
|
|
36
|
+
"meanneg",
|
|
37
|
+
]
|
|
38
|
+
SUMATTRS = [
|
|
39
|
+
"sumpos",
|
|
40
|
+
"sumneg",
|
|
41
|
+
"sumabs",
|
|
42
|
+
]
|
|
43
|
+
ALLATTRS = STATATTRS + SUMATTRS
|
|
44
|
+
|
|
45
|
+
# self ~ RegularSurface() instance
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _cut_cube_deadtraces(cube: Cube, deadtraces: bool) -> np.ndarray:
|
|
49
|
+
"""Take the cube numpy values and filter away dead traces as np.nan."""
|
|
50
|
+
logger.info("Assign dead traces")
|
|
51
|
+
dvalues = cube.values.copy()
|
|
52
|
+
|
|
53
|
+
if deadtraces and 2 in cube.traceidcodes:
|
|
54
|
+
dvalues[cube.traceidcodes == 2] = np.nan
|
|
55
|
+
logger.info("Dead traces encountered in this cube, set values to np.nan")
|
|
56
|
+
else:
|
|
57
|
+
logger.info("No dead traces encountered in this cube, or deadtraces is False")
|
|
58
|
+
|
|
59
|
+
return dvalues
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _get_iso_maskthreshold_surface(
|
|
63
|
+
upper: RegularSurface,
|
|
64
|
+
lower: RegularSurface,
|
|
65
|
+
maskthreshold: float,
|
|
66
|
+
) -> RegularSurface:
|
|
67
|
+
"""Return a surface with value 0 where isochore <= threshold"""
|
|
68
|
+
logger.info("Maskthreshold based on isochore")
|
|
69
|
+
result = upper.copy()
|
|
70
|
+
result.fill()
|
|
71
|
+
diff = lower - upper
|
|
72
|
+
result.values = np.ma.where(diff.values <= maskthreshold, 0, 1)
|
|
73
|
+
return result
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def _proxy_surf_outside_cube(
|
|
77
|
+
self,
|
|
78
|
+
cube: Cube,
|
|
79
|
+
scube: RegularSurface,
|
|
80
|
+
) -> RegularSurface:
|
|
81
|
+
"""Proxy for the part of input surface that is outside the cube area."""
|
|
82
|
+
logger.info("Get a proxy for part of original surface being outside the cube")
|
|
83
|
+
outside = self.copy()
|
|
84
|
+
outside.values = 0.0
|
|
85
|
+
|
|
86
|
+
boundary = scube.get_boundary_polygons()
|
|
87
|
+
outside.set_outside(boundary, 1.0)
|
|
88
|
+
return outside # is 1 outside the cube area, 0 within the cube
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def _upper_lower_surface(
|
|
92
|
+
self,
|
|
93
|
+
cube: Cube,
|
|
94
|
+
scube: RegularSurface,
|
|
95
|
+
zsurf: RegularSurface,
|
|
96
|
+
other: RegularSurface,
|
|
97
|
+
other_position: str,
|
|
98
|
+
zrange: float,
|
|
99
|
+
) -> tuple[RegularSurface, RegularSurface]:
|
|
100
|
+
"""Return upper and lower surface, sampled to cube resolution."""
|
|
101
|
+
|
|
102
|
+
logger.info("Define surfaces to apply...")
|
|
103
|
+
this = zsurf if zsurf is not None else self.copy()
|
|
104
|
+
|
|
105
|
+
if other is not None:
|
|
106
|
+
if other_position.lower() == "below":
|
|
107
|
+
surf1 = this
|
|
108
|
+
surf2 = other
|
|
109
|
+
else:
|
|
110
|
+
surf1 = other # avoid changing self instance
|
|
111
|
+
surf2 = this
|
|
112
|
+
else:
|
|
113
|
+
surf1 = this.copy()
|
|
114
|
+
surf2 = this.copy()
|
|
115
|
+
surf1.values -= zrange
|
|
116
|
+
surf2.values += zrange
|
|
117
|
+
|
|
118
|
+
# get the surfaces on cube resolution
|
|
119
|
+
lower = scube.copy()
|
|
120
|
+
scube.resample(surf1)
|
|
121
|
+
lower.resample(surf2)
|
|
122
|
+
|
|
123
|
+
logger.info(
|
|
124
|
+
"Return resmapled surfaces, avg for upper and lower is %s, %s",
|
|
125
|
+
scube.values.mean(),
|
|
126
|
+
lower.values.mean(),
|
|
127
|
+
)
|
|
128
|
+
return scube, lower
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def _create_depth_cube(cube: Cube) -> np.ndarray:
|
|
132
|
+
"""Create a cube (np array) where values are cube depths; to be used as filter."""
|
|
133
|
+
logger.info("Create a depth cube...")
|
|
134
|
+
dcube = cube.values.copy()
|
|
135
|
+
darr = [cube.zori + n * cube.zinc for n in range(dcube.shape[2])]
|
|
136
|
+
dcube[:, :, :] = darr
|
|
137
|
+
|
|
138
|
+
logger.info("Created a depth cube starting from %s", np.mean(dcube))
|
|
139
|
+
|
|
140
|
+
return dcube
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def _refine_cubes_vertically(cvalues, dvalues, ndiv=2):
|
|
144
|
+
"""Refine the cubes vertically for better resolution."""
|
|
145
|
+
if not ndiv:
|
|
146
|
+
ndiv = 2 # default
|
|
147
|
+
logger.info("Resampling vertically, according to ndiv = %s", ndiv)
|
|
148
|
+
if ndiv <= 1:
|
|
149
|
+
logger.info("ndiv is less or equal to 1; no refinement done")
|
|
150
|
+
return cvalues, dvalues
|
|
151
|
+
|
|
152
|
+
logger.info("Original shape is %s", cvalues.shape)
|
|
153
|
+
|
|
154
|
+
# Determine the new shape
|
|
155
|
+
new_shape = (cvalues.shape[0], cvalues.shape[1], ndiv * cvalues.shape[2])
|
|
156
|
+
cref = np.zeros(new_shape)
|
|
157
|
+
dref = np.zeros(new_shape)
|
|
158
|
+
|
|
159
|
+
# Compute new indices for interpolation
|
|
160
|
+
new_x = np.linspace(0, cvalues.shape[2] - 1, new_shape[2])
|
|
161
|
+
|
|
162
|
+
# Interpolate for each layer and column
|
|
163
|
+
for i in range(cvalues.shape[0]):
|
|
164
|
+
for j in range(cvalues.shape[1]):
|
|
165
|
+
cref[i, j, :] = np.interp(
|
|
166
|
+
new_x, np.arange(cvalues.shape[2]), cvalues[i, j, :]
|
|
167
|
+
)
|
|
168
|
+
dref[i, j, :] = np.interp(
|
|
169
|
+
new_x, np.arange(dvalues.shape[2]), dvalues[i, j, :]
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
logger.info("Resampling done, new shape is %s", cref.shape)
|
|
173
|
+
return cref, dref
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def _filter_cube_values_upper_lower(cvalues, dvalues, upper, lower):
|
|
177
|
+
"""Filter the cube (cvalues) based on depth interval."""
|
|
178
|
+
|
|
179
|
+
nnans = np.count_nonzero(np.isnan(cvalues))
|
|
180
|
+
logger.info("Filter cube in depth... number of nans is %s", nnans)
|
|
181
|
+
|
|
182
|
+
upv = np.expand_dims(upper.values, axis=2)
|
|
183
|
+
lov = np.expand_dims(lower.values, axis=2)
|
|
184
|
+
|
|
185
|
+
cvalues[dvalues < upv] = np.nan
|
|
186
|
+
cvalues[dvalues > lov] = np.nan
|
|
187
|
+
|
|
188
|
+
nnans = np.count_nonzero(np.isnan(cvalues))
|
|
189
|
+
ndefi = np.count_nonzero(~np.isnan(cvalues))
|
|
190
|
+
logger.info("Filter cube in depth done, updated number of nans is %s", nnans)
|
|
191
|
+
logger.info("Filter cube in depth done, remaining is %s", ndefi)
|
|
192
|
+
return cvalues
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def _expand_attributes(attribute: str | list) -> list:
|
|
196
|
+
"""The 'attribute' may be a name, 'all', or a list of attributes"""
|
|
197
|
+
useattrs = None
|
|
198
|
+
if isinstance(attribute, str):
|
|
199
|
+
useattrs = ALLATTRS if attribute == "all" else [attribute]
|
|
200
|
+
else:
|
|
201
|
+
useattrs = attribute
|
|
202
|
+
|
|
203
|
+
if not all(item in ALLATTRS for item in useattrs):
|
|
204
|
+
raise ValueError(
|
|
205
|
+
f"One or more values are not a valid, input list is {useattrs}, "
|
|
206
|
+
f"allowed list is {ALLATTRS}"
|
|
207
|
+
)
|
|
208
|
+
return useattrs
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
def _compute_stats(
|
|
212
|
+
cref: np.ndarray,
|
|
213
|
+
attr: str,
|
|
214
|
+
self: RegularSurface,
|
|
215
|
+
upper: RegularSurface,
|
|
216
|
+
masksurf: RegularSurface,
|
|
217
|
+
sampling: str,
|
|
218
|
+
snapxy: bool,
|
|
219
|
+
) -> RegularSurface:
|
|
220
|
+
"""Compute the attribute and return the attribute map"""
|
|
221
|
+
logger.info("Compute stats...")
|
|
222
|
+
|
|
223
|
+
if attr == "mean":
|
|
224
|
+
values = np.nanmean(cref, axis=2)
|
|
225
|
+
elif attr == "var":
|
|
226
|
+
values = np.nanvar(cref, axis=2)
|
|
227
|
+
elif attr == "max":
|
|
228
|
+
values = np.nanmax(cref, axis=2)
|
|
229
|
+
elif attr == "min":
|
|
230
|
+
values = np.nanmin(cref, axis=2)
|
|
231
|
+
elif attr == "rms":
|
|
232
|
+
values = np.sqrt(np.nanmean(np.square(cref), axis=2))
|
|
233
|
+
elif attr == "maxneg":
|
|
234
|
+
use = cref.copy()
|
|
235
|
+
use[cref >= 0] = np.nan
|
|
236
|
+
values = np.nanmin(use, axis=2)
|
|
237
|
+
elif attr == "maxpos":
|
|
238
|
+
use = cref.copy()
|
|
239
|
+
use[cref < 0] = np.nan
|
|
240
|
+
values = np.nanmax(use, axis=2)
|
|
241
|
+
elif attr == "maxabs":
|
|
242
|
+
use = cref.copy()
|
|
243
|
+
use = np.abs(use)
|
|
244
|
+
values = np.nanmax(use, axis=2)
|
|
245
|
+
elif attr == "meanabs":
|
|
246
|
+
use = cref.copy()
|
|
247
|
+
use = np.abs(use)
|
|
248
|
+
values = np.nanmean(use, axis=2)
|
|
249
|
+
elif attr == "meanpos":
|
|
250
|
+
use = cref.copy()
|
|
251
|
+
use[cref < 0] = np.nan
|
|
252
|
+
values = np.nanmean(use, axis=2)
|
|
253
|
+
elif attr == "meanneg":
|
|
254
|
+
use = cref.copy()
|
|
255
|
+
use[cref >= 0] = np.nan
|
|
256
|
+
values = np.nanmean(use, axis=2)
|
|
257
|
+
elif attr == "sumneg":
|
|
258
|
+
use = cref.copy()
|
|
259
|
+
use[cref >= 0] = np.nan
|
|
260
|
+
values = np.nansum(use, axis=2)
|
|
261
|
+
values = np.ma.masked_greater_equal(values, 0.0) # to make undefined map areas
|
|
262
|
+
elif attr == "sumpos":
|
|
263
|
+
use = cref.copy()
|
|
264
|
+
use[cref < 0] = np.nan
|
|
265
|
+
values = np.nansum(use, axis=2)
|
|
266
|
+
values = np.ma.masked_less_equal(values, 0.0) # to make undefined map areas
|
|
267
|
+
elif attr == "sumabs":
|
|
268
|
+
use = cref.copy()
|
|
269
|
+
use = np.abs(use)
|
|
270
|
+
values = np.nansum(use, axis=2)
|
|
271
|
+
else:
|
|
272
|
+
raise ValueError(f"The attribute name {attr} is not supported")
|
|
273
|
+
|
|
274
|
+
actual = self.copy()
|
|
275
|
+
sampled = upper.copy()
|
|
276
|
+
|
|
277
|
+
sampled.values = np.ma.masked_invalid(values)
|
|
278
|
+
sampled.values = np.ma.masked_where(masksurf.values == 0, sampled.values)
|
|
279
|
+
|
|
280
|
+
if not snapxy:
|
|
281
|
+
sampling_option = "nearest" if sampling in ("nearest", "cube") else "bilinear"
|
|
282
|
+
actual.resample(
|
|
283
|
+
sampled, sampling=sampling_option
|
|
284
|
+
) # will be on input map resolution
|
|
285
|
+
else:
|
|
286
|
+
actual = sampled
|
|
287
|
+
|
|
288
|
+
logger.info("Compute stats... done")
|
|
289
|
+
return actual
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
def slice_cube_window(
|
|
293
|
+
self,
|
|
294
|
+
cube: Cube,
|
|
295
|
+
scube: RegularSurface,
|
|
296
|
+
zsurf: RegularSurface | None = None,
|
|
297
|
+
other: RegularSurface | None = None,
|
|
298
|
+
other_position: str = "below",
|
|
299
|
+
sampling: str = "nearest",
|
|
300
|
+
mask: bool = True,
|
|
301
|
+
zrange: float = 10.0,
|
|
302
|
+
ndiv: int | None = None,
|
|
303
|
+
attribute: str = "max",
|
|
304
|
+
maskthreshold: float = 0.1,
|
|
305
|
+
snapxy: bool = False,
|
|
306
|
+
showprogress: bool = False,
|
|
307
|
+
deadtraces: bool = True,
|
|
308
|
+
):
|
|
309
|
+
"""Main entry point towards caller"""
|
|
310
|
+
if showprogress:
|
|
311
|
+
print("progress: initialising for attributes...")
|
|
312
|
+
|
|
313
|
+
cvalues = _cut_cube_deadtraces(cube, deadtraces)
|
|
314
|
+
|
|
315
|
+
upper, lower = _upper_lower_surface(
|
|
316
|
+
self, cube, scube, zsurf, other, other_position, zrange
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
outside_proxy = None
|
|
320
|
+
if not mask:
|
|
321
|
+
outside_proxy = _proxy_surf_outside_cube(self, cube, scube)
|
|
322
|
+
|
|
323
|
+
masksurf = _get_iso_maskthreshold_surface(upper, lower, maskthreshold)
|
|
324
|
+
|
|
325
|
+
dvalues = _create_depth_cube(cube)
|
|
326
|
+
|
|
327
|
+
apply_ndiv = 1 if sampling == "cube" else ndiv
|
|
328
|
+
if showprogress:
|
|
329
|
+
print(f"progress: refine according to actual ndiv = {apply_ndiv}...")
|
|
330
|
+
|
|
331
|
+
cref, dref = _refine_cubes_vertically(cvalues, dvalues, apply_ndiv)
|
|
332
|
+
|
|
333
|
+
cref = _filter_cube_values_upper_lower(cref, dref, upper, lower)
|
|
334
|
+
|
|
335
|
+
cval = _filter_cube_values_upper_lower(cvalues, dvalues, upper, lower)
|
|
336
|
+
|
|
337
|
+
use_attrs = _expand_attributes(attribute)
|
|
338
|
+
|
|
339
|
+
attrs = {}
|
|
340
|
+
if showprogress:
|
|
341
|
+
print("progress: compute mean, variance, etc attributes...")
|
|
342
|
+
for attr in use_attrs:
|
|
343
|
+
if attr in SUMATTRS:
|
|
344
|
+
# use cval, which is not refined vertically
|
|
345
|
+
res = _compute_stats(cval, attr, self, upper, masksurf, sampling, snapxy)
|
|
346
|
+
else:
|
|
347
|
+
res = _compute_stats(cref, attr, self, upper, masksurf, sampling, snapxy)
|
|
348
|
+
|
|
349
|
+
if outside_proxy and not snapxy:
|
|
350
|
+
res.values = np.ma.where(outside_proxy > 0, self.values, res.values)
|
|
351
|
+
|
|
352
|
+
attrs[attr] = res
|
|
353
|
+
|
|
354
|
+
# if attribute is str, self shall be updated and None returned,
|
|
355
|
+
# otherwise a dict of attributes objects shall be returned
|
|
356
|
+
if isinstance(attrs, dict) and len(attrs) == 1 and isinstance(attribute, str):
|
|
357
|
+
self.values = attrs[attribute].values
|
|
358
|
+
return None
|
|
359
|
+
|
|
360
|
+
return attrs
|