evo-objects 0.6.3__tar.gz → 0.6.5__tar.gz
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.
- {evo_objects-0.6.3 → evo_objects-0.6.5}/PKG-INFO +2 -2
- {evo_objects-0.6.3 → evo_objects-0.6.5}/pyproject.toml +2 -2
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/data.py +2 -1
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/typed/_grid.py +25 -7
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/typed/base.py +8 -2
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/typed/block_model_ref.py +8 -4
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/typed/regular_grid.py +1 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/typed/regular_masked_grid.py +1 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/typed/tensor_grid.py +1 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/typed/types.py +50 -9
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/typed/variogram.py +12 -6
- {evo_objects-0.6.3 → evo_objects-0.6.5}/.gitignore +0 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/LICENSE.md +0 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/__init__.py +0 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/_model_config.py +0 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/client/__init__.py +0 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/client/api_client.py +0 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/client/object_client.py +0 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/client/parse.py +0 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/endpoints/__init__.py +0 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/endpoints/api/__init__.py +0 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/endpoints/api/data_api.py +0 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/endpoints/api/metadata_api.py +0 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/endpoints/api/objects_api.py +0 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/endpoints/api/stages_api.py +0 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/endpoints/models.py +0 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/exceptions.py +0 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/io.py +0 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/parquet/__init__.py +0 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/parquet/loader.py +0 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/py.typed +0 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/typed/__init__.py +0 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/typed/_data.py +0 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/typed/_downhole.py +0 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/typed/_model.py +0 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/typed/_prefetch.py +0 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/typed/_utils.py +0 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/typed/attributes.py +0 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/typed/downhole_collection.py +0 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/typed/downhole_intervals.py +0 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/typed/exceptions.py +0 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/typed/pointset.py +0 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/typed/spatial.py +0 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/utils/__init__.py +0 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/utils/data.py +0 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/utils/downhole.py +0 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/utils/table_formats.py +0 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/utils/tables.py +0 -0
- {evo_objects-0.6.3 → evo_objects-0.6.5}/src/evo/objects/utils/types.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: evo-objects
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.5
|
|
4
4
|
Summary: Python SDK for using the Seequent Evo Geoscience Object API
|
|
5
5
|
Project-URL: Source, https://github.com/SeequentEvo/evo-python-sdk
|
|
6
6
|
Project-URL: Tracker, https://github.com/SeequentEvo/evo-python-sdk/issues
|
|
@@ -9,7 +9,7 @@ Project-URL: Documentation, https://developer.seequent.com/
|
|
|
9
9
|
Author-email: Seequent <support@seequent.com>
|
|
10
10
|
License-File: LICENSE.md
|
|
11
11
|
Requires-Python: >=3.10
|
|
12
|
-
Requires-Dist: evo-sdk-common[jmespath]>=0.5.
|
|
12
|
+
Requires-Dist: evo-sdk-common[jmespath]>=0.5.28
|
|
13
13
|
Requires-Dist: pydantic<3,>=2
|
|
14
14
|
Provides-Extra: aiohttp
|
|
15
15
|
Requires-Dist: evo-sdk-common[aiohttp]; extra == 'aiohttp'
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "evo-objects"
|
|
3
3
|
description = "Python SDK for using the Seequent Evo Geoscience Object API"
|
|
4
|
-
version = "0.6.
|
|
4
|
+
version = "0.6.5"
|
|
5
5
|
requires-python = ">=3.10"
|
|
6
6
|
license-files = ["LICENSE.md"]
|
|
7
7
|
dynamic = ["readme"]
|
|
@@ -10,7 +10,7 @@ authors = [
|
|
|
10
10
|
]
|
|
11
11
|
|
|
12
12
|
dependencies = [
|
|
13
|
-
"evo-sdk-common[jmespath]>=0.5.
|
|
13
|
+
"evo-sdk-common[jmespath]>=0.5.28",
|
|
14
14
|
"pydantic>=2,<3",
|
|
15
15
|
]
|
|
16
16
|
|
|
@@ -91,7 +91,8 @@ class ObjectReference(str):
|
|
|
91
91
|
inst = str.__new__(cls, value)
|
|
92
92
|
|
|
93
93
|
parsed = urlparse(value)
|
|
94
|
-
if parsed.scheme
|
|
94
|
+
if not parsed.scheme:
|
|
95
|
+
# Valid hub URLs are always HTTPS, but it is sometimes useful to pass HTTP ones for testing, so these are allowed here too.
|
|
95
96
|
raise ValueError("Reference must be a valid HTTPS URL")
|
|
96
97
|
|
|
97
98
|
inst.hub_url = f"{parsed.scheme}://{parsed.netloc}/"
|
|
@@ -22,6 +22,7 @@ import pandas as pd
|
|
|
22
22
|
from pydantic import AliasChoices, Field
|
|
23
23
|
|
|
24
24
|
from evo.common import IFeedback
|
|
25
|
+
from evo.common.typed import FloatArrayLike3, IntArrayLike3
|
|
25
26
|
from evo.common.utils import NoFeedback
|
|
26
27
|
|
|
27
28
|
from ._model import DataLocation, SchemaLocation, SchemaModel
|
|
@@ -46,23 +47,35 @@ class Base3DGridData(BaseSpatialObjectData):
|
|
|
46
47
|
"""Base class for all 3D grid data.
|
|
47
48
|
|
|
48
49
|
Contains the common properties shared by all grid types: origin, size, rotation, and cell_data.
|
|
50
|
+
Origin and size accept their named types or three values in a list, tuple, or 1D array.
|
|
51
|
+
All inputs, including named types, are validated and normalized.
|
|
49
52
|
"""
|
|
50
53
|
|
|
51
|
-
origin: Point3
|
|
52
|
-
size: Size3i
|
|
54
|
+
origin: Point3 | FloatArrayLike3
|
|
55
|
+
size: Size3i | IntArrayLike3
|
|
53
56
|
cell_data: pd.DataFrame | None = None
|
|
54
57
|
rotation: Rotation | None = None
|
|
55
58
|
|
|
59
|
+
def __post_init__(self) -> None:
|
|
60
|
+
object.__setattr__(self, "origin", Point3.from_array_like(self.origin))
|
|
61
|
+
object.__setattr__(self, "size", Size3i.from_array_like(self.size))
|
|
62
|
+
|
|
56
63
|
|
|
57
64
|
@dataclass(kw_only=True, frozen=True)
|
|
58
65
|
class BaseRegular3DGridData(Base3DGridData):
|
|
59
66
|
"""Base class for regular 3D grid data (both masked and non-masked).
|
|
60
67
|
|
|
61
68
|
Contains the common properties shared by Regular3DGridData and RegularMasked3DGridData.
|
|
62
|
-
Adds cell_size to the base grid properties
|
|
69
|
+
Adds cell_size to the base grid properties; it accepts a Size3d or three
|
|
70
|
+
values in a list, tuple, or 1D array.
|
|
71
|
+
All inputs, including Size3d instances, are validated and normalized.
|
|
63
72
|
"""
|
|
64
73
|
|
|
65
|
-
cell_size: Size3d
|
|
74
|
+
cell_size: Size3d | FloatArrayLike3
|
|
75
|
+
|
|
76
|
+
def __post_init__(self) -> None:
|
|
77
|
+
super().__post_init__()
|
|
78
|
+
object.__setattr__(self, "cell_size", Size3d.from_array_like(self.cell_size))
|
|
66
79
|
|
|
67
80
|
def compute_bounding_box(self) -> BoundingBox:
|
|
68
81
|
return BoundingBox.from_regular_grid(self.origin, self.size, self.cell_size, self.rotation)
|
|
@@ -223,15 +236,20 @@ class RegularBlockModelData:
|
|
|
223
236
|
"""
|
|
224
237
|
|
|
225
238
|
name: str
|
|
226
|
-
origin: Point3
|
|
227
|
-
n_blocks: Size3i
|
|
228
|
-
block_size: Size3d
|
|
239
|
+
origin: Point3 | FloatArrayLike3
|
|
240
|
+
n_blocks: Size3i | IntArrayLike3
|
|
241
|
+
block_size: Size3d | FloatArrayLike3
|
|
229
242
|
cell_data: pd.DataFrame | None = None
|
|
230
243
|
description: str | None = None
|
|
231
244
|
coordinate_reference_system: str | None = None
|
|
232
245
|
size_unit_id: str | None = None
|
|
233
246
|
units: dict[str, str] = field(default_factory=dict)
|
|
234
247
|
|
|
248
|
+
def __post_init__(self) -> None:
|
|
249
|
+
object.__setattr__(self, "origin", Point3.from_array_like(self.origin))
|
|
250
|
+
object.__setattr__(self, "n_blocks", Size3i.from_array_like(self.n_blocks))
|
|
251
|
+
object.__setattr__(self, "block_size", Size3d.from_array_like(self.block_size))
|
|
252
|
+
|
|
235
253
|
|
|
236
254
|
@dataclass(frozen=True, kw_only=True)
|
|
237
255
|
class BlockModelData(BaseSpatialObjectData):
|
|
@@ -362,12 +362,18 @@ class _BaseObject(SchemaModel):
|
|
|
362
362
|
|
|
363
363
|
:return: A new instance with refreshed data.
|
|
364
364
|
|
|
365
|
-
Example
|
|
365
|
+
Example::
|
|
366
|
+
|
|
366
367
|
>>> # After a remote operation modifies the object...
|
|
367
368
|
>>> obj = await obj.refresh()
|
|
368
369
|
>>> obj.attributes # Now shows the latest attributes
|
|
369
370
|
"""
|
|
370
|
-
|
|
371
|
+
# metadata.url pins the current version_id, which would just re-download the same version.
|
|
372
|
+
latest_reference = ObjectReference.new(
|
|
373
|
+
environment=self.metadata.environment,
|
|
374
|
+
object_id=self.metadata.id,
|
|
375
|
+
)
|
|
376
|
+
return await self.from_reference(self._api_context, latest_reference)
|
|
371
377
|
|
|
372
378
|
def search(self, expression: str) -> Any:
|
|
373
379
|
"""Search the object metadata using a JMESPath expression.
|
|
@@ -192,7 +192,8 @@ class BlockModel(BaseSpatialObject):
|
|
|
192
192
|
:param fb: Optional feedback interface for progress reporting.
|
|
193
193
|
:return: DataFrame containing the block model data with user-friendly column names.
|
|
194
194
|
|
|
195
|
-
Example
|
|
195
|
+
Example::
|
|
196
|
+
|
|
196
197
|
>>> df = await block_model.to_dataframe()
|
|
197
198
|
>>> df.head()
|
|
198
199
|
"""
|
|
@@ -207,7 +208,8 @@ class BlockModel(BaseSpatialObject):
|
|
|
207
208
|
|
|
208
209
|
:return: A new BlockModel instance with refreshed data.
|
|
209
210
|
|
|
210
|
-
Example
|
|
211
|
+
Example::
|
|
212
|
+
|
|
211
213
|
>>> # After running kriging that adds attributes...
|
|
212
214
|
>>> block_model = await block_model.refresh()
|
|
213
215
|
>>> block_model.attributes # Now shows the new attributes
|
|
@@ -335,7 +337,8 @@ class BlockModel(BaseSpatialObject):
|
|
|
335
337
|
:param fb: Optional feedback interface for progress reporting.
|
|
336
338
|
:return: The updated BlockModel instance (refreshed from server).
|
|
337
339
|
|
|
338
|
-
Example
|
|
340
|
+
Example::
|
|
341
|
+
|
|
339
342
|
>>> from evo.blockmodels import Units
|
|
340
343
|
>>> block_model = await block_model.set_attribute_units({
|
|
341
344
|
... "Au": Units.GRAMS_PER_TONNE,
|
|
@@ -361,7 +364,8 @@ class BlockModel(BaseSpatialObject):
|
|
|
361
364
|
:param fb: Optional feedback interface for progress reporting.
|
|
362
365
|
:return: A Report instance representing the created report.
|
|
363
366
|
|
|
364
|
-
Example
|
|
367
|
+
Example::
|
|
368
|
+
|
|
365
369
|
>>> from evo.blockmodels.typed import ReportSpecificationData, ReportColumnSpec, ReportCategorySpec
|
|
366
370
|
>>> report = await block_model.create_report(ReportSpecificationData(
|
|
367
371
|
... name="Gold Resource Report",
|
|
@@ -36,6 +36,7 @@ class Regular3DGridData(BaseRegular3DGridData):
|
|
|
36
36
|
vertex_data: pd.DataFrame | None = None
|
|
37
37
|
|
|
38
38
|
def __post_init__(self):
|
|
39
|
+
super().__post_init__()
|
|
39
40
|
if self.cell_data is not None and self.cell_data.shape[0] != self.size.total_size:
|
|
40
41
|
raise ObjectValidationError(
|
|
41
42
|
f"The number of rows in the cell_data dataframe ({self.cell_data.shape[0]}) does not match the number of cells in the grid ({self.size.nx * self.size.ny * self.size.nz})."
|
|
@@ -43,6 +43,7 @@ class RegularMasked3DGridData(BaseRegular3DGridData):
|
|
|
43
43
|
mask: np.ndarray
|
|
44
44
|
|
|
45
45
|
def __post_init__(self):
|
|
46
|
+
super().__post_init__()
|
|
46
47
|
if self.mask.shape[0] != self.size.total_size:
|
|
47
48
|
raise ObjectValidationError(
|
|
48
49
|
f"The number of rows in the mask ({self.mask.shape[0]}) does not match the number of cells in the grid ({self.size.nx * self.size.ny * self.size.nz})."
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
from __future__ import annotations
|
|
13
13
|
|
|
14
14
|
from dataclasses import dataclass
|
|
15
|
+
from numbers import Real
|
|
15
16
|
from typing import Annotated, Any, overload
|
|
16
17
|
|
|
17
18
|
import numpy as np
|
|
@@ -20,7 +21,7 @@ import pydantic
|
|
|
20
21
|
|
|
21
22
|
# Import basic geometry types from evo.common and re-export
|
|
22
23
|
from evo.common.crs import EpsgCode, parse_crs
|
|
23
|
-
from evo.common.typed import Point3, Size3d, Size3i
|
|
24
|
+
from evo.common.typed import FloatArrayLike3, Point3, Size3d, Size3i, _validate_array_like
|
|
24
25
|
|
|
25
26
|
__all__ = [
|
|
26
27
|
"BoundingBox",
|
|
@@ -204,12 +205,26 @@ class BoundingBox:
|
|
|
204
205
|
|
|
205
206
|
@dataclass(frozen=True)
|
|
206
207
|
class Rotation:
|
|
207
|
-
"""A
|
|
208
|
+
"""A clockwise intrinsic ZXZ Euler rotation in degrees.
|
|
209
|
+
|
|
210
|
+
Dip azimuth [0, 360], dip [0, 180], and pitch [0, 360] rotate about
|
|
211
|
+
successive local Z, X, and Z axes, respectively. For column vectors,
|
|
212
|
+
the rotation matrix is Rz(dip azimuth) @ Rx(dip) @ Rz(pitch).
|
|
213
|
+
"""
|
|
208
214
|
|
|
209
215
|
dip_azimuth: float
|
|
210
216
|
dip: float
|
|
211
217
|
pitch: float
|
|
212
218
|
|
|
219
|
+
def __post_init__(self) -> None:
|
|
220
|
+
for name, value, lower, upper in (
|
|
221
|
+
("dip_azimuth", self.dip_azimuth, 0, 360),
|
|
222
|
+
("dip", self.dip, 0, 180),
|
|
223
|
+
("pitch", self.pitch, 0, 360),
|
|
224
|
+
):
|
|
225
|
+
if not isinstance(value, Real) or isinstance(value, bool) or not lower <= value <= upper:
|
|
226
|
+
raise ValueError(f"{name} must be a finite angle between {lower} and {upper} degrees (inclusive)")
|
|
227
|
+
|
|
213
228
|
def as_rotation_matrix(self) -> np.ndarray:
|
|
214
229
|
"""Convert the rotation to a rotation matrix.
|
|
215
230
|
|
|
@@ -246,6 +261,12 @@ class Rotation:
|
|
|
246
261
|
# Combined intrinsic rotations: dip_azimuth -> dip -> pitch
|
|
247
262
|
return dip_azimuth_rotation_matrix @ dip_rotation_matrix @ pitch_rotation_matrix
|
|
248
263
|
|
|
264
|
+
@classmethod
|
|
265
|
+
def from_array_like(cls, value: Rotation | FloatArrayLike3) -> Rotation:
|
|
266
|
+
if isinstance(value, Rotation):
|
|
267
|
+
value = (value.dip_azimuth, value.dip, value.pitch)
|
|
268
|
+
return cls(*_validate_array_like(value, kind=Real, positive=False))
|
|
269
|
+
|
|
249
270
|
|
|
250
271
|
@dataclass
|
|
251
272
|
class EllipsoidRanges:
|
|
@@ -256,9 +277,9 @@ class EllipsoidRanges:
|
|
|
256
277
|
minor: float
|
|
257
278
|
|
|
258
279
|
def __init__(self, major: float, semi_major: float, minor: float):
|
|
259
|
-
self.major =
|
|
260
|
-
|
|
261
|
-
|
|
280
|
+
self.major, self.semi_major, self.minor = _validate_array_like(
|
|
281
|
+
(major, semi_major, minor), kind=Real, positive=True
|
|
282
|
+
)
|
|
262
283
|
|
|
263
284
|
def to_dict(self) -> dict[str, Any]:
|
|
264
285
|
return {"major": self.major, "semi_major": self.semi_major, "minor": self.minor}
|
|
@@ -270,17 +291,37 @@ class EllipsoidRanges:
|
|
|
270
291
|
minor=self.minor * factor,
|
|
271
292
|
)
|
|
272
293
|
|
|
294
|
+
@classmethod
|
|
295
|
+
def from_array_like(cls, value: EllipsoidRanges | FloatArrayLike3) -> EllipsoidRanges:
|
|
296
|
+
if isinstance(value, EllipsoidRanges):
|
|
297
|
+
value = (value.major, value.semi_major, value.minor)
|
|
298
|
+
return cls(*_validate_array_like(value, kind=Real, positive=True))
|
|
299
|
+
|
|
273
300
|
|
|
274
301
|
@dataclass
|
|
275
302
|
class Ellipsoid:
|
|
276
|
-
"""An ellipsoid defining a spatial region.
|
|
303
|
+
"""An ellipsoid defining a spatial region.
|
|
304
|
+
|
|
305
|
+
Ranges are ordered major, semi-major, minor. Rotation angles are in
|
|
306
|
+
degrees and ordered dip azimuth [0, 360], dip [0, 180], pitch [0, 360].
|
|
307
|
+
They specify clockwise intrinsic rotations about the successive Z, X,
|
|
308
|
+
and Z axes, respectively.
|
|
309
|
+
|
|
310
|
+
Ranges accept an EllipsoidRanges instance or a three-value list, tuple,
|
|
311
|
+
or 1D NumPy array. Rotation accepts a Rotation instance or the same
|
|
312
|
+
three-value sequence forms; omitting it applies no rotation.
|
|
313
|
+
"""
|
|
277
314
|
|
|
278
315
|
ranges: EllipsoidRanges
|
|
279
316
|
_rotation: Rotation | None = None
|
|
280
317
|
|
|
281
|
-
def __init__(
|
|
282
|
-
self
|
|
283
|
-
|
|
318
|
+
def __init__(
|
|
319
|
+
self,
|
|
320
|
+
ranges: EllipsoidRanges | FloatArrayLike3,
|
|
321
|
+
rotation: Rotation | FloatArrayLike3 | None = None,
|
|
322
|
+
):
|
|
323
|
+
self.ranges = EllipsoidRanges.from_array_like(ranges)
|
|
324
|
+
self._rotation = Rotation.from_array_like(rotation) if rotation is not None else None
|
|
284
325
|
|
|
285
326
|
@property
|
|
286
327
|
def rotation(self) -> Rotation:
|
|
@@ -70,7 +70,8 @@ class VariogramStructure:
|
|
|
70
70
|
- Creating search ellipsoids via scaled()
|
|
71
71
|
- Kriging search neighborhoods
|
|
72
72
|
|
|
73
|
-
Example
|
|
73
|
+
Example::
|
|
74
|
+
|
|
74
75
|
>>> # Get ellipsoid from variogram structure
|
|
75
76
|
>>> var_ell = variogram.structures[0].to_ellipsoid()
|
|
76
77
|
>>>
|
|
@@ -277,7 +278,8 @@ class VariogramData(BaseObjectData):
|
|
|
277
278
|
- `modelling_space`: Set to "data" for original units or "normalscore" for gaussian space
|
|
278
279
|
- `data_variance`: Should match the sill value for non-normalized data
|
|
279
280
|
|
|
280
|
-
Example using typed structures (recommended)
|
|
281
|
+
Example using typed structures (recommended)::
|
|
282
|
+
|
|
281
283
|
>>> data = VariogramData(
|
|
282
284
|
... name="My Variogram",
|
|
283
285
|
... sill=1.0,
|
|
@@ -407,7 +409,8 @@ class Variogram(BaseObject):
|
|
|
407
409
|
Returns:
|
|
408
410
|
Ellipsoid configured with the structure's anisotropy ranges and rotation.
|
|
409
411
|
|
|
410
|
-
Example
|
|
412
|
+
Example::
|
|
413
|
+
|
|
411
414
|
>>> # Get ellipsoid from structure with largest range (default)
|
|
412
415
|
>>> var_ell = variogram.get_ellipsoid()
|
|
413
416
|
>>>
|
|
@@ -475,7 +478,8 @@ class Variogram(BaseObject):
|
|
|
475
478
|
Returns:
|
|
476
479
|
Tuple of (major_curve, semi_major_curve, minor_curve) as VariogramCurveData.
|
|
477
480
|
|
|
478
|
-
Example with Plotly
|
|
481
|
+
Example with Plotly::
|
|
482
|
+
|
|
479
483
|
>>> major, semi_maj, minor = variogram.get_principal_directions()
|
|
480
484
|
>>> import plotly.graph_objects as go
|
|
481
485
|
>>> fig = go.Figure()
|
|
@@ -549,7 +553,8 @@ class Variogram(BaseObject):
|
|
|
549
553
|
Returns:
|
|
550
554
|
Tuple of (distance, semivariance) as numpy arrays, suitable for plotting.
|
|
551
555
|
|
|
552
|
-
Example with Plotly
|
|
556
|
+
Example with Plotly::
|
|
557
|
+
|
|
553
558
|
>>> distance, semivariance = variogram.get_direction(azimuth=45, dip=30)
|
|
554
559
|
>>> import plotly.graph_objects as go
|
|
555
560
|
>>> fig = go.Figure()
|
|
@@ -557,7 +562,8 @@ class Variogram(BaseObject):
|
|
|
557
562
|
>>> fig.update_layout(xaxis_title='Distance', yaxis_title='Semivariance')
|
|
558
563
|
>>> fig.show()
|
|
559
564
|
|
|
560
|
-
Example with Matplotlib
|
|
565
|
+
Example with Matplotlib::
|
|
566
|
+
|
|
561
567
|
>>> distance, semivariance = variogram.get_direction(azimuth=0, dip=0)
|
|
562
568
|
>>> import matplotlib.pyplot as plt
|
|
563
569
|
>>> plt.plot(distance, semivariance)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|