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.
Files changed (122) hide show
  1. cxtgeo.py +558 -0
  2. cxtgeoPYTHON_wrap.c +19537 -0
  3. xtgeo/__init__.py +248 -0
  4. xtgeo/_cxtgeo.cp313-win_amd64.pyd +0 -0
  5. xtgeo/_internal.cp313-win_amd64.pyd +0 -0
  6. xtgeo/common/__init__.py +19 -0
  7. xtgeo/common/_angles.py +29 -0
  8. xtgeo/common/_xyz_enum.py +50 -0
  9. xtgeo/common/calc.py +396 -0
  10. xtgeo/common/constants.py +30 -0
  11. xtgeo/common/exceptions.py +42 -0
  12. xtgeo/common/log.py +93 -0
  13. xtgeo/common/sys.py +166 -0
  14. xtgeo/common/types.py +18 -0
  15. xtgeo/common/version.py +34 -0
  16. xtgeo/common/xtgeo_dialog.py +604 -0
  17. xtgeo/cube/__init__.py +9 -0
  18. xtgeo/cube/_cube_export.py +214 -0
  19. xtgeo/cube/_cube_import.py +532 -0
  20. xtgeo/cube/_cube_roxapi.py +180 -0
  21. xtgeo/cube/_cube_utils.py +287 -0
  22. xtgeo/cube/_cube_window_attributes.py +273 -0
  23. xtgeo/cube/cube1.py +1023 -0
  24. xtgeo/grid3d/__init__.py +15 -0
  25. xtgeo/grid3d/_ecl_grid.py +778 -0
  26. xtgeo/grid3d/_ecl_inte_head.py +152 -0
  27. xtgeo/grid3d/_ecl_logi_head.py +71 -0
  28. xtgeo/grid3d/_ecl_output_file.py +81 -0
  29. xtgeo/grid3d/_egrid.py +1004 -0
  30. xtgeo/grid3d/_find_gridprop_in_eclrun.py +625 -0
  31. xtgeo/grid3d/_grdecl_format.py +309 -0
  32. xtgeo/grid3d/_grdecl_grid.py +400 -0
  33. xtgeo/grid3d/_grid3d.py +29 -0
  34. xtgeo/grid3d/_grid3d_fence.py +284 -0
  35. xtgeo/grid3d/_grid3d_utils.py +228 -0
  36. xtgeo/grid3d/_grid_boundary.py +76 -0
  37. xtgeo/grid3d/_grid_etc1.py +1683 -0
  38. xtgeo/grid3d/_grid_export.py +222 -0
  39. xtgeo/grid3d/_grid_hybrid.py +50 -0
  40. xtgeo/grid3d/_grid_import.py +79 -0
  41. xtgeo/grid3d/_grid_import_ecl.py +101 -0
  42. xtgeo/grid3d/_grid_import_roff.py +135 -0
  43. xtgeo/grid3d/_grid_import_xtgcpgeom.py +375 -0
  44. xtgeo/grid3d/_grid_refine.py +258 -0
  45. xtgeo/grid3d/_grid_roxapi.py +292 -0
  46. xtgeo/grid3d/_grid_translate_coords.py +154 -0
  47. xtgeo/grid3d/_grid_wellzone.py +165 -0
  48. xtgeo/grid3d/_gridprop_export.py +202 -0
  49. xtgeo/grid3d/_gridprop_import_eclrun.py +164 -0
  50. xtgeo/grid3d/_gridprop_import_grdecl.py +132 -0
  51. xtgeo/grid3d/_gridprop_import_roff.py +52 -0
  52. xtgeo/grid3d/_gridprop_import_xtgcpprop.py +168 -0
  53. xtgeo/grid3d/_gridprop_lowlevel.py +171 -0
  54. xtgeo/grid3d/_gridprop_op1.py +272 -0
  55. xtgeo/grid3d/_gridprop_roxapi.py +301 -0
  56. xtgeo/grid3d/_gridprop_value_init.py +140 -0
  57. xtgeo/grid3d/_gridprops_import_eclrun.py +344 -0
  58. xtgeo/grid3d/_gridprops_import_roff.py +83 -0
  59. xtgeo/grid3d/_roff_grid.py +470 -0
  60. xtgeo/grid3d/_roff_parameter.py +303 -0
  61. xtgeo/grid3d/grid.py +3010 -0
  62. xtgeo/grid3d/grid_properties.py +699 -0
  63. xtgeo/grid3d/grid_property.py +1313 -0
  64. xtgeo/grid3d/types.py +15 -0
  65. xtgeo/interfaces/rms/__init__.py +18 -0
  66. xtgeo/interfaces/rms/_regular_surface.py +460 -0
  67. xtgeo/interfaces/rms/_rms_base.py +100 -0
  68. xtgeo/interfaces/rms/_rmsapi_package.py +69 -0
  69. xtgeo/interfaces/rms/rmsapi_utils.py +438 -0
  70. xtgeo/io/__init__.py +1 -0
  71. xtgeo/io/_file.py +603 -0
  72. xtgeo/metadata/__init__.py +17 -0
  73. xtgeo/metadata/metadata.py +435 -0
  74. xtgeo/roxutils/__init__.py +7 -0
  75. xtgeo/roxutils/_roxar_loader.py +54 -0
  76. xtgeo/roxutils/_roxutils_etc.py +122 -0
  77. xtgeo/roxutils/roxutils.py +207 -0
  78. xtgeo/surface/__init__.py +20 -0
  79. xtgeo/surface/_regsurf_boundary.py +26 -0
  80. xtgeo/surface/_regsurf_cube.py +210 -0
  81. xtgeo/surface/_regsurf_cube_window.py +391 -0
  82. xtgeo/surface/_regsurf_cube_window_v2.py +297 -0
  83. xtgeo/surface/_regsurf_cube_window_v3.py +360 -0
  84. xtgeo/surface/_regsurf_export.py +388 -0
  85. xtgeo/surface/_regsurf_grid3d.py +275 -0
  86. xtgeo/surface/_regsurf_gridding.py +347 -0
  87. xtgeo/surface/_regsurf_ijxyz_parser.py +278 -0
  88. xtgeo/surface/_regsurf_import.py +347 -0
  89. xtgeo/surface/_regsurf_lowlevel.py +122 -0
  90. xtgeo/surface/_regsurf_oper.py +538 -0
  91. xtgeo/surface/_regsurf_utils.py +81 -0
  92. xtgeo/surface/_surfs_import.py +43 -0
  93. xtgeo/surface/_zmap_parser.py +138 -0
  94. xtgeo/surface/regular_surface.py +3043 -0
  95. xtgeo/surface/surfaces.py +276 -0
  96. xtgeo/well/__init__.py +24 -0
  97. xtgeo/well/_blockedwell_roxapi.py +241 -0
  98. xtgeo/well/_blockedwells_roxapi.py +68 -0
  99. xtgeo/well/_well_aux.py +30 -0
  100. xtgeo/well/_well_io.py +327 -0
  101. xtgeo/well/_well_oper.py +483 -0
  102. xtgeo/well/_well_roxapi.py +304 -0
  103. xtgeo/well/_wellmarkers.py +486 -0
  104. xtgeo/well/_wells_utils.py +158 -0
  105. xtgeo/well/blocked_well.py +220 -0
  106. xtgeo/well/blocked_wells.py +134 -0
  107. xtgeo/well/well1.py +1516 -0
  108. xtgeo/well/wells.py +211 -0
  109. xtgeo/xyz/__init__.py +6 -0
  110. xtgeo/xyz/_polygons_oper.py +272 -0
  111. xtgeo/xyz/_xyz.py +758 -0
  112. xtgeo/xyz/_xyz_data.py +646 -0
  113. xtgeo/xyz/_xyz_io.py +737 -0
  114. xtgeo/xyz/_xyz_lowlevel.py +42 -0
  115. xtgeo/xyz/_xyz_oper.py +613 -0
  116. xtgeo/xyz/_xyz_roxapi.py +766 -0
  117. xtgeo/xyz/points.py +698 -0
  118. xtgeo/xyz/polygons.py +827 -0
  119. xtgeo-4.14.1.dist-info/METADATA +146 -0
  120. xtgeo-4.14.1.dist-info/RECORD +122 -0
  121. xtgeo-4.14.1.dist-info/WHEEL +5 -0
  122. xtgeo-4.14.1.dist-info/licenses/LICENSE.md +165 -0
@@ -0,0 +1,303 @@
1
+ from __future__ import annotations
2
+
3
+ import warnings
4
+ from collections import defaultdict
5
+ from dataclasses import dataclass
6
+ from typing import TYPE_CHECKING, Any
7
+
8
+ import numpy as np
9
+ import roffio
10
+
11
+ from xtgeo.common.constants import UNDEF_INT_LIMIT, UNDEF_LIMIT
12
+
13
+ if TYPE_CHECKING:
14
+ from xtgeo.common.types import FileLike
15
+
16
+ from .grid_property import GridProperty
17
+
18
+
19
+ @dataclass
20
+ class RoffParameter:
21
+ """
22
+ Roff parameter contains a parameter (1 value per grid cell) in a roff file.
23
+
24
+ Parameters are either discrete (int) or floating point. Discrete values can
25
+ come with code names giving the meaning of the values. The list code_names
26
+ gives the name for each value in code_values.
27
+
28
+ The value -999 for discrete parameters (255 for byte valued discrete
29
+ parameters) and -999.0 for floating point parameters are used undefined
30
+ value.
31
+
32
+ Args:
33
+ nx (int): The number of cells in x direction.
34
+ ny (int): The number of cells in y direction.
35
+ nz (int): The number of cells in z direction.
36
+ names (str): The name of the parameter
37
+ values (array of int32 or float, or bytes): One value per cell in c
38
+ order.
39
+ code_names (List of str): The name of the coded value.
40
+ code_values (array of int32): The code values.
41
+ """
42
+
43
+ nx: int
44
+ ny: int
45
+ nz: int
46
+
47
+ name: str
48
+ values: np.ndarray | bytes
49
+
50
+ code_names: list[str] | None = None
51
+ code_values: np.ndarray | None = None
52
+
53
+ def __eq__(self, other: Any) -> bool:
54
+ if not isinstance(other, RoffParameter):
55
+ return False
56
+ return (
57
+ self.nx == other.nx
58
+ and self.ny == other.ny
59
+ and self.nz == other.nz
60
+ and self.name == other.name
61
+ and np.array_equal(self.values, other.values)
62
+ and self.same_codes(other)
63
+ )
64
+
65
+ def same_codes(self, other: RoffParameter) -> bool:
66
+ """
67
+ Args:
68
+ other (RoffParameter): Any roff parameter
69
+ Returns:
70
+ True if the roff parameters have the same coded values.
71
+ """
72
+ if self.code_names is None:
73
+ return other.code_names is None
74
+ if self.code_values is None:
75
+ return other.code_values is None
76
+
77
+ if other.code_names is None:
78
+ return self.code_names is None
79
+ if other.code_values is None:
80
+ return self.code_values is None
81
+
82
+ return dict(zip(self.code_values, self.code_names)) == dict(
83
+ zip(other.code_values, other.code_names)
84
+ )
85
+
86
+ @property
87
+ def undefined_value(self) -> int | float:
88
+ """
89
+ Returns:
90
+ The undefined value for the type of values in the
91
+ roff parameter (either 255, -999, or -999.0)
92
+ """
93
+ if isinstance(self.values, bytes) or np.issubdtype(self.values.dtype, np.uint8):
94
+ return 255
95
+ if np.issubdtype(self.values.dtype, np.integer):
96
+ return -999
97
+ if np.issubdtype(self.values.dtype, np.floating):
98
+ return -999.0
99
+ raise ValueError(f"Parameter values of unsupported type {type(self.values)}")
100
+
101
+ @property
102
+ def is_discrete(self) -> bool:
103
+ """
104
+ Returns:
105
+ True if the RoffParameter is a discrete type
106
+ """
107
+ return bool(
108
+ isinstance(self.values, bytes)
109
+ or np.issubdtype(self.values.dtype, np.integer)
110
+ )
111
+
112
+ def xtgeo_codes(self) -> dict[int, str]:
113
+ """
114
+ Returns:
115
+ The discrete codes of the parameter in the format of
116
+ xtgeo.GridProperty.
117
+ """
118
+ return (
119
+ dict(zip(self.code_values, self.code_names))
120
+ if self.code_names is not None and self.code_values is not None
121
+ else {}
122
+ )
123
+
124
+ def xtgeo_values(self) -> np.ndarray:
125
+ """
126
+ Args:
127
+ The value to use for undefined. Defaults to that defined by
128
+ roff.
129
+ Returns:
130
+ The values in the format of xtgeo grid property
131
+ """
132
+ if isinstance(self.values, bytes):
133
+ vals: np.ndarray = np.ndarray(len(self.values), np.uint8, self.values)
134
+ else:
135
+ vals = self.values.copy()
136
+
137
+ vals = np.flip(vals.reshape((self.nx, self.ny, self.nz)), -1)
138
+ vals = vals.astype(np.int32) if self.is_discrete else vals.astype(np.float64)
139
+ return np.ma.masked_values(vals, self.undefined_value)
140
+
141
+ @staticmethod
142
+ def from_xtgeo_grid_property(gridproperty: GridProperty) -> RoffParameter:
143
+ """
144
+ Args:
145
+ xtgeo_grid_property (xtgeo.GridProperty): Any xtgeo.GridProperty
146
+ Returns:
147
+ That grid property as a RoffParameter
148
+ """
149
+ code_names = None
150
+ code_values = None
151
+ if gridproperty.isdiscrete:
152
+ code_names = list(gridproperty.codes.values())
153
+ code_values = np.array(list(gridproperty.codes.keys()), dtype=np.int32)
154
+
155
+ if not np.ma.isMaskedArray(gridproperty.values):
156
+ values = np.ma.masked_greater(
157
+ gridproperty.values,
158
+ UNDEF_INT_LIMIT if gridproperty.isdiscrete else UNDEF_LIMIT,
159
+ )
160
+ else:
161
+ values = gridproperty.values
162
+
163
+ if gridproperty.isdiscrete:
164
+ values = values.astype(np.int32).filled(-999)
165
+ else:
166
+ # Although the roff format can contain double,
167
+ # double typed parameters are not read by RMS so we
168
+ # need to convert to float32 here
169
+ values = values.astype(np.float32).filled(-999.0)
170
+
171
+ return RoffParameter(
172
+ nx=gridproperty.ncol,
173
+ ny=gridproperty.nrow,
174
+ nz=gridproperty.nlay,
175
+ name=gridproperty.name or "",
176
+ values=np.asarray(np.flip(values, -1).ravel()),
177
+ code_names=code_names,
178
+ code_values=code_values,
179
+ )
180
+
181
+ def to_file(
182
+ self,
183
+ filelike: FileLike,
184
+ roff_format: roffio.Format = roffio.Format.BINARY,
185
+ ) -> None:
186
+ """
187
+ Writes the RoffParameter to a roff file
188
+ Args:
189
+ filelike (str or byte stream): The file to write to.
190
+ roff_format (roffio.Format): The format to write the file in.
191
+ """
192
+ data: dict[str, dict[str, Any]] = {
193
+ "filedata": {"filetype": "parameter"},
194
+ "dimensions": {"nX": self.nx, "nY": self.ny, "nZ": self.nz},
195
+ "parameter": {"name": self.name},
196
+ }
197
+ if self.code_names is not None:
198
+ data["parameter"]["codeNames"] = list(self.code_names)
199
+ if self.code_values is not None:
200
+ data["parameter"]["codeValues"] = self.code_values
201
+ data["parameter"]["data"] = self.values
202
+ with warnings.catch_warnings():
203
+ warnings.filterwarnings("ignore", r"casting array")
204
+ roffio.write(filelike, data, roff_format=roff_format)
205
+
206
+ @staticmethod
207
+ def from_file(filelike: FileLike, name: str | None = None) -> RoffParameter:
208
+ """
209
+ Read a RoffParameter from a roff file
210
+ Args:
211
+ filelike (str or byte stream): The file to read from.
212
+ name(str or None): The name of the parameter to get from the file,
213
+ if name=None, returns the first parameter read.
214
+ Returns:
215
+ The RoffGrid in the roff file.
216
+ """
217
+
218
+ def should_skip_parameter(tag: str, key: str) -> bool:
219
+ if tag == "parameter" and key[0] == "name":
220
+ return not (name is None or key[1] == name)
221
+ return False
222
+
223
+ translate_kws = {
224
+ "dimensions": {"nX": "nx", "nY": "ny", "nZ": "nz"},
225
+ "parameter": {
226
+ "name": "name",
227
+ "data": "values",
228
+ "codeValues": "code_values",
229
+ "codeNames": "code_names",
230
+ },
231
+ }
232
+ optional_keywords = defaultdict(
233
+ list,
234
+ {"parameter": ["codeValues", "codeNames"]},
235
+ )
236
+ # The found dictionary contains all tags/tagkeys which we are
237
+ # interested in with None as the initial value. We go through the
238
+ # tag/tagkeys in the file and replace as they are found.
239
+ found = {
240
+ tag_name: dict.fromkeys(tag_keys)
241
+ for tag_name, tag_keys in translate_kws.items()
242
+ }
243
+ found["filedata"] = {"filetype": None}
244
+ with roffio.lazy_read(filelike) as tag_generator:
245
+ for tag, keys in tag_generator:
246
+ if tag in found:
247
+ if tag == "parameter" and found["parameter"]["data"] is not None:
248
+ # We have already found the right parameter so skip
249
+ # reading and potentially overwriting
250
+ continue
251
+ # We do not destruct keys yet as this fetches the value too early.
252
+ # key is not a tuple but an object that fetches the value when
253
+ # __getitem__ is called.
254
+ for key in keys:
255
+ if should_skip_parameter(tag, key):
256
+ # Found a parameter, but not the one we are looking for
257
+ # reset and look on
258
+ for key_name in found["parameter"]:
259
+ found["parameter"][key_name] = None
260
+ break
261
+ if key[0] in found[tag]:
262
+ if found[tag][key[0]] is not None:
263
+ raise ValueError(
264
+ f"Multiple tag, tagkey pair {tag}, {key[0]}"
265
+ f" in {filelike}"
266
+ )
267
+ found[tag][key[0]] = key[1]
268
+
269
+ if name is not None and (found["parameter"]["name"] != name):
270
+ raise ValueError(
271
+ "Did not find parameter"
272
+ f" {name} in roff file, got {found['parameter']['name']}"
273
+ )
274
+
275
+ for tag_name, keys in found.items():
276
+ for key_name, value in keys.items():
277
+ if value is None and key_name not in optional_keywords[tag_name]:
278
+ raise ValueError(
279
+ f"Missing non-optional keyword {tag_name}:{key_name}"
280
+ )
281
+
282
+ filetype = found["filedata"]["filetype"]
283
+ if filetype not in ["grid", "parameter"]:
284
+ raise ValueError(
285
+ f"File {filelike} did not"
286
+ f" have filetype parameter or grid, found {filetype}"
287
+ )
288
+
289
+ roff: dict[str, Any] = {}
290
+ for tag, tag_keys in translate_kws.items():
291
+ for key, translated in tag_keys.items():
292
+ if found[tag][key] is not None:
293
+ roff[translated] = found[tag][key]
294
+
295
+ return RoffParameter(
296
+ nx=roff["nx"],
297
+ ny=roff["ny"],
298
+ nz=roff["nz"],
299
+ name=roff["name"],
300
+ values=roff["values"],
301
+ code_names=roff.get("code_names"),
302
+ code_values=roff.get("code_values"),
303
+ )