xtgeo 4.13.0__cp312-cp312-win_amd64.whl → 4.13.1__cp312-cp312-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.

Potentially problematic release.


This version of xtgeo might be problematic. Click here for more details.

cxtgeo.py CHANGED
@@ -475,12 +475,6 @@ def grd3d_get_lay_slice(nx, ny, nz, swig_np_dbl_in_v1, swig_np_dbl_in_v2, swig_n
475
475
  def grd3d_make_z_consistent(nx, ny, nz, swig_np_dbl_inplace_v1, zsep):
476
476
  return _cxtgeo.grd3d_make_z_consistent(nx, ny, nz, swig_np_dbl_inplace_v1, zsep)
477
477
 
478
- def grd3d_translate(nx, ny, nz, xflip, yflip, zflip, xshift, yshift, zshift, swig_np_dbl_inplace_v1, swig_np_dbl_inplace_v2):
479
- return _cxtgeo.grd3d_translate(nx, ny, nz, xflip, yflip, zflip, xshift, yshift, zshift, swig_np_dbl_inplace_v1, swig_np_dbl_inplace_v2)
480
-
481
- def grd3d_reverse_jrows(nx, ny, nz, swig_np_dbl_inplace_v1, swig_np_dbl_inplace_v2, swig_np_int_inplace_v1):
482
- return _cxtgeo.grd3d_reverse_jrows(nx, ny, nz, swig_np_dbl_inplace_v1, swig_np_dbl_inplace_v2, swig_np_int_inplace_v1)
483
-
484
478
  def grd3d_point_val_crange(x, y, z, nx, ny, nz, p_coor_v, zcornsv, actnumsv, p_val_v, value, imin, imax, jmin, jmax, kmin, kmax, ibs, option):
485
479
  return _cxtgeo.grd3d_point_val_crange(x, y, z, nx, ny, nz, p_coor_v, zcornsv, actnumsv, p_val_v, value, imin, imax, jmin, jmax, kmin, kmax, ibs, option)
486
480
 
cxtgeoPYTHON_wrap.c CHANGED
@@ -14740,208 +14740,6 @@ fail:
14740
14740
  }
14741
14741
 
14742
14742
 
14743
- SWIGINTERN PyObject *_wrap_grd3d_translate(PyObject *self, PyObject *args) {
14744
- PyObject *resultobj = 0;
14745
- int arg1 ;
14746
- int arg2 ;
14747
- int arg3 ;
14748
- int arg4 ;
14749
- int arg5 ;
14750
- int arg6 ;
14751
- double arg7 ;
14752
- double arg8 ;
14753
- double arg9 ;
14754
- double *arg10 = (double *) 0 ;
14755
- long arg11 ;
14756
- double *arg12 = (double *) 0 ;
14757
- long arg13 ;
14758
- int val1 ;
14759
- int ecode1 = 0 ;
14760
- int val2 ;
14761
- int ecode2 = 0 ;
14762
- int val3 ;
14763
- int ecode3 = 0 ;
14764
- int val4 ;
14765
- int ecode4 = 0 ;
14766
- int val5 ;
14767
- int ecode5 = 0 ;
14768
- int val6 ;
14769
- int ecode6 = 0 ;
14770
- double val7 ;
14771
- int ecode7 = 0 ;
14772
- double val8 ;
14773
- int ecode8 = 0 ;
14774
- double val9 ;
14775
- int ecode9 = 0 ;
14776
- PyArrayObject *array10 = NULL ;
14777
- int i10 = 1 ;
14778
- PyArrayObject *array12 = NULL ;
14779
- int i12 = 1 ;
14780
- PyObject *swig_obj[11] ;
14781
- int result;
14782
-
14783
- (void)self;
14784
- if (!SWIG_Python_UnpackTuple(args, "grd3d_translate", 11, 11, swig_obj)) SWIG_fail;
14785
- ecode1 = SWIG_AsVal_int(swig_obj[0], &val1);
14786
- if (!SWIG_IsOK(ecode1)) {
14787
- SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "grd3d_translate" "', argument " "1"" of type '" "int""'");
14788
- }
14789
- arg1 = (int)(val1);
14790
- ecode2 = SWIG_AsVal_int(swig_obj[1], &val2);
14791
- if (!SWIG_IsOK(ecode2)) {
14792
- SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "grd3d_translate" "', argument " "2"" of type '" "int""'");
14793
- }
14794
- arg2 = (int)(val2);
14795
- ecode3 = SWIG_AsVal_int(swig_obj[2], &val3);
14796
- if (!SWIG_IsOK(ecode3)) {
14797
- SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "grd3d_translate" "', argument " "3"" of type '" "int""'");
14798
- }
14799
- arg3 = (int)(val3);
14800
- ecode4 = SWIG_AsVal_int(swig_obj[3], &val4);
14801
- if (!SWIG_IsOK(ecode4)) {
14802
- SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "grd3d_translate" "', argument " "4"" of type '" "int""'");
14803
- }
14804
- arg4 = (int)(val4);
14805
- ecode5 = SWIG_AsVal_int(swig_obj[4], &val5);
14806
- if (!SWIG_IsOK(ecode5)) {
14807
- SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "grd3d_translate" "', argument " "5"" of type '" "int""'");
14808
- }
14809
- arg5 = (int)(val5);
14810
- ecode6 = SWIG_AsVal_int(swig_obj[5], &val6);
14811
- if (!SWIG_IsOK(ecode6)) {
14812
- SWIG_exception_fail(SWIG_ArgError(ecode6), "in method '" "grd3d_translate" "', argument " "6"" of type '" "int""'");
14813
- }
14814
- arg6 = (int)(val6);
14815
- ecode7 = SWIG_AsVal_double(swig_obj[6], &val7);
14816
- if (!SWIG_IsOK(ecode7)) {
14817
- SWIG_exception_fail(SWIG_ArgError(ecode7), "in method '" "grd3d_translate" "', argument " "7"" of type '" "double""'");
14818
- }
14819
- arg7 = (double)(val7);
14820
- ecode8 = SWIG_AsVal_double(swig_obj[7], &val8);
14821
- if (!SWIG_IsOK(ecode8)) {
14822
- SWIG_exception_fail(SWIG_ArgError(ecode8), "in method '" "grd3d_translate" "', argument " "8"" of type '" "double""'");
14823
- }
14824
- arg8 = (double)(val8);
14825
- ecode9 = SWIG_AsVal_double(swig_obj[8], &val9);
14826
- if (!SWIG_IsOK(ecode9)) {
14827
- SWIG_exception_fail(SWIG_ArgError(ecode9), "in method '" "grd3d_translate" "', argument " "9"" of type '" "double""'");
14828
- }
14829
- arg9 = (double)(val9);
14830
- {
14831
- array10 = obj_to_array_no_conversion(swig_obj[9], NPY_DOUBLE);
14832
- if (!array10 || !require_dimensions(array10,1) || !require_contiguous(array10)
14833
- || !require_native(array10)) SWIG_fail;
14834
- arg10 = (double*) array_data(array10);
14835
- arg11 = 1;
14836
- for (i10=0; i10 < array_numdims(array10); ++i10) arg11 *= array_size(array10,i10);
14837
- }
14838
- {
14839
- array12 = obj_to_array_no_conversion(swig_obj[10], NPY_DOUBLE);
14840
- if (!array12 || !require_dimensions(array12,1) || !require_contiguous(array12)
14841
- || !require_native(array12)) SWIG_fail;
14842
- arg12 = (double*) array_data(array12);
14843
- arg13 = 1;
14844
- for (i12=0; i12 < array_numdims(array12); ++i12) arg13 *= array_size(array12,i12);
14845
- }
14846
- {
14847
- char *err;
14848
- clear_exception();
14849
- result = (int)grd3d_translate(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12,arg13);
14850
- if ((err = check_exception())) {
14851
- PyErr_SetString(PY_XTGeoCLibError, err);
14852
- return NULL;
14853
- }
14854
- }
14855
- resultobj = SWIG_From_int((int)(result));
14856
- return resultobj;
14857
- fail:
14858
- return NULL;
14859
- }
14860
-
14861
-
14862
- SWIGINTERN PyObject *_wrap_grd3d_reverse_jrows(PyObject *self, PyObject *args) {
14863
- PyObject *resultobj = 0;
14864
- int arg1 ;
14865
- int arg2 ;
14866
- int arg3 ;
14867
- double *arg4 = (double *) 0 ;
14868
- long arg5 ;
14869
- double *arg6 = (double *) 0 ;
14870
- long arg7 ;
14871
- int *arg8 = (int *) 0 ;
14872
- long arg9 ;
14873
- int val1 ;
14874
- int ecode1 = 0 ;
14875
- int val2 ;
14876
- int ecode2 = 0 ;
14877
- int val3 ;
14878
- int ecode3 = 0 ;
14879
- PyArrayObject *array4 = NULL ;
14880
- int i4 = 1 ;
14881
- PyArrayObject *array6 = NULL ;
14882
- int i6 = 1 ;
14883
- PyArrayObject *array8 = NULL ;
14884
- int i8 = 1 ;
14885
- PyObject *swig_obj[6] ;
14886
- int result;
14887
-
14888
- (void)self;
14889
- if (!SWIG_Python_UnpackTuple(args, "grd3d_reverse_jrows", 6, 6, swig_obj)) SWIG_fail;
14890
- ecode1 = SWIG_AsVal_int(swig_obj[0], &val1);
14891
- if (!SWIG_IsOK(ecode1)) {
14892
- SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "grd3d_reverse_jrows" "', argument " "1"" of type '" "int""'");
14893
- }
14894
- arg1 = (int)(val1);
14895
- ecode2 = SWIG_AsVal_int(swig_obj[1], &val2);
14896
- if (!SWIG_IsOK(ecode2)) {
14897
- SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "grd3d_reverse_jrows" "', argument " "2"" of type '" "int""'");
14898
- }
14899
- arg2 = (int)(val2);
14900
- ecode3 = SWIG_AsVal_int(swig_obj[2], &val3);
14901
- if (!SWIG_IsOK(ecode3)) {
14902
- SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "grd3d_reverse_jrows" "', argument " "3"" of type '" "int""'");
14903
- }
14904
- arg3 = (int)(val3);
14905
- {
14906
- array4 = obj_to_array_no_conversion(swig_obj[3], NPY_DOUBLE);
14907
- if (!array4 || !require_dimensions(array4,1) || !require_contiguous(array4)
14908
- || !require_native(array4)) SWIG_fail;
14909
- arg4 = (double*) array_data(array4);
14910
- arg5 = 1;
14911
- for (i4=0; i4 < array_numdims(array4); ++i4) arg5 *= array_size(array4,i4);
14912
- }
14913
- {
14914
- array6 = obj_to_array_no_conversion(swig_obj[4], NPY_DOUBLE);
14915
- if (!array6 || !require_dimensions(array6,1) || !require_contiguous(array6)
14916
- || !require_native(array6)) SWIG_fail;
14917
- arg6 = (double*) array_data(array6);
14918
- arg7 = 1;
14919
- for (i6=0; i6 < array_numdims(array6); ++i6) arg7 *= array_size(array6,i6);
14920
- }
14921
- {
14922
- array8 = obj_to_array_no_conversion(swig_obj[5], NPY_INT);
14923
- if (!array8 || !require_dimensions(array8,1) || !require_contiguous(array8)
14924
- || !require_native(array8)) SWIG_fail;
14925
- arg8 = (int*) array_data(array8);
14926
- arg9 = 1;
14927
- for (i8=0; i8 < array_numdims(array8); ++i8) arg9 *= array_size(array8,i8);
14928
- }
14929
- {
14930
- char *err;
14931
- clear_exception();
14932
- result = (int)grd3d_reverse_jrows(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9);
14933
- if ((err = check_exception())) {
14934
- PyErr_SetString(PY_XTGeoCLibError, err);
14935
- return NULL;
14936
- }
14937
- }
14938
- resultobj = SWIG_From_int((int)(result));
14939
- return resultobj;
14940
- fail:
14941
- return NULL;
14942
- }
14943
-
14944
-
14945
14743
  SWIGINTERN PyObject *_wrap_grd3d_point_val_crange(PyObject *self, PyObject *args) {
14946
14744
  PyObject *resultobj = 0;
14947
14745
  double arg1 ;
@@ -19124,8 +18922,6 @@ static PyMethodDef SwigMethods[] = {
19124
18922
  { "grd3d_reduce_onelayer", _wrap_grd3d_reduce_onelayer, METH_VARARGS, NULL},
19125
18923
  { "grd3d_get_lay_slice", _wrap_grd3d_get_lay_slice, METH_VARARGS, NULL},
19126
18924
  { "grd3d_make_z_consistent", _wrap_grd3d_make_z_consistent, METH_VARARGS, NULL},
19127
- { "grd3d_translate", _wrap_grd3d_translate, METH_VARARGS, NULL},
19128
- { "grd3d_reverse_jrows", _wrap_grd3d_reverse_jrows, METH_VARARGS, NULL},
19129
18925
  { "grd3d_point_val_crange", _wrap_grd3d_point_val_crange, METH_VARARGS, NULL},
19130
18926
  { "grd3d_point_in_cell", _wrap_grd3d_point_in_cell, METH_VARARGS, NULL},
19131
18927
  { "grd3d_get_randomline", _wrap_grd3d_get_randomline, METH_VARARGS, NULL},
Binary file
Binary file
xtgeo/common/version.py CHANGED
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '4.13.0'
32
- __version_tuple__ = version_tuple = (4, 13, 0)
31
+ __version__ = version = '4.13.1'
32
+ __version_tuple__ = version_tuple = (4, 13, 1)
33
33
 
34
- __commit_id__ = commit_id = 'g766805bb7'
34
+ __commit_id__ = commit_id = 'gdae14dc56'
@@ -1259,85 +1259,86 @@ def reduce_to_one_layer(self: Grid) -> None:
1259
1259
  self._subgrids = None
1260
1260
 
1261
1261
 
1262
- def translate_coordinates(
1263
- self: Grid,
1264
- translate: tuple[float, float, float] = (0.0, 0.0, 0.0),
1265
- flip: tuple[int, int, int] = (1, 1, 1),
1262
+ def reverse_row_axis(
1263
+ self: Grid, ijk_handedness: Literal["left", "right"] | None = None
1266
1264
  ) -> None:
1267
- """Translate grid coordinates."""
1268
- self._set_xtgformat1()
1265
+ """Flip the row-axis for xtgformat=2 grid arrays.
1269
1266
 
1270
- tx, ty, tz = translate
1271
- fx, fy, fz = flip
1267
+ This reverses the J-direction (rows) by flipping along axis 1 for both
1268
+ coordsv and zcornsv arrays, and also handles the corner ordering within
1269
+ each pillar to maintain proper geometry.
1270
+ """
1271
+ if ijk_handedness == self.ijk_handedness:
1272
+ return
1272
1273
 
1273
- ier = _cxtgeo.grd3d_translate(
1274
- self._ncol,
1275
- self._nrow,
1276
- self._nlay,
1277
- fx,
1278
- fy,
1279
- fz,
1280
- tx,
1281
- ty,
1282
- tz,
1283
- self._coordsv,
1284
- self._zcornsv,
1285
- )
1286
- if ier != 0:
1287
- raise RuntimeError(f"Something went wrong in translate, code: {ier}")
1274
+ self._set_xtgformat2()
1288
1275
 
1289
- logger.info("Translation of coords done")
1276
+ # Flip coordsv along the row axis (axis 1) and make contiguous with copy()
1277
+ self._coordsv = np.flip(self._coordsv, axis=1).copy()
1290
1278
 
1279
+ # For zcornsv, we need to flip along row axis and also swap corner ordering
1280
+ # Original corner order: SW, SE, NW, NE (indices 0,1,2,3)
1281
+ # After row flip: NW, NE, SW, SE (should become indices 0,1,2,3)
1282
+ # So we need to rearrange: [2,3,0,1]
1283
+ zcorns_flipped = np.flip(self._zcornsv, axis=1) # Flip along row axis
1284
+ self._zcornsv = zcorns_flipped[:, :, :, [2, 3, 0, 1]].copy() # Reorder corners
1291
1285
 
1292
- def reverse_row_axis(
1293
- self: Grid, ijk_handedness: Literal["left", "right"] | None = None
1294
- ) -> None:
1295
- """Reverse rows (aka flip) for geometry and assosiated properties."""
1296
- if ijk_handedness == self.ijk_handedness:
1297
- return
1286
+ # Also flip actnum along row axis
1287
+ self._actnumsv = np.flip(self._actnumsv, axis=1).copy()
1298
1288
 
1299
- # update the handedness
1300
- if ijk_handedness is None:
1301
- self._ijk_handedness = estimate_handedness(self)
1289
+ # Update handedness
1290
+ if self._ijk_handedness == "left":
1291
+ self._ijk_handedness = "right"
1292
+ else:
1293
+ self._ijk_handedness = "left"
1302
1294
 
1303
- original_handedness = self._ijk_handedness
1304
- original_xtgformat = self._xtgformat
1295
+ # Handle properties if they exist
1296
+ if self._props and self._props.props:
1297
+ for prop in self._props.props:
1298
+ prop.values = np.flip(prop.values, axis=1).copy()
1305
1299
 
1306
- self._set_xtgformat1()
1300
+ logger.info("Reversing of row axis done")
1307
1301
 
1308
- ier = _cxtgeo.grd3d_reverse_jrows(
1309
- self._ncol,
1310
- self._nrow,
1311
- self._nlay,
1312
- self._coordsv.ravel(),
1313
- self._zcornsv.ravel(),
1314
- self._actnumsv.ravel(),
1315
- )
1316
1302
 
1317
- if ier != 0:
1318
- raise RuntimeError(f"Something went wrong in jswapping, code: {ier}")
1303
+ def reverse_column_axis(
1304
+ self: Grid, ijk_handedness: Literal["left", "right"] | None = None
1305
+ ) -> None:
1306
+ """Flip the column-axis for xtgformat=2 grid arrays.
1319
1307
 
1320
- if self._props is None:
1308
+ This reverses the I-direction (columns) by flipping along axis 0 for both
1309
+ coordsv and zcornsv arrays, and also handles the corner ordering within
1310
+ each pillar to maintain proper geometry.
1311
+ """
1312
+ if ijk_handedness == self.ijk_handedness:
1321
1313
  return
1322
1314
 
1323
- # do it for properties
1324
- if self._props.props:
1325
- for prp in self._props.props:
1326
- prp.values = prp.values[:, ::-1, :]
1315
+ self._set_xtgformat2()
1316
+
1317
+ # Flip coordsv along the column axis (axis 0) and make contiguous with copy()
1318
+ self._coordsv = np.flip(self._coordsv, axis=0).copy()
1319
+
1320
+ # For zcornsv, we need to flip along column axis and also swap corner ordering
1321
+ # Original corner order: SW, SE, NW, NE (indices 0,1,2,3)
1322
+ # After column flip: SE, SW, NE, NW (should become indices 0,1,2,3)
1323
+ # So we need to rearrange: [1,0,3,2]
1324
+ zcorns_flipped = np.flip(self._zcornsv, axis=0) # Flip along column axis
1325
+ self._zcornsv = zcorns_flipped[:, :, :, [1, 0, 3, 2]].copy() # Reorder corners
1327
1326
 
1328
- # update the handedness
1329
- if ijk_handedness is None:
1330
- self._ijk_handedness = estimate_handedness(self)
1327
+ # Also flip actnum along column axis
1328
+ self._actnumsv = np.flip(self._actnumsv, axis=0).copy()
1331
1329
 
1332
- if original_handedness == "left":
1330
+ # Update handedness
1331
+ if self._ijk_handedness == "left":
1333
1332
  self._ijk_handedness = "right"
1334
1333
  else:
1335
1334
  self._ijk_handedness = "left"
1336
1335
 
1337
- if original_xtgformat == 2:
1338
- self._set_xtgformat2()
1336
+ # Handle properties if they exist
1337
+ if self._props and self._props.props:
1338
+ for prop in self._props.props:
1339
+ prop.values = np.flip(prop.values, axis=0).copy()
1339
1340
 
1340
- logger.info("Reversing of rows done")
1341
+ logger.info("Reversing of column axis done")
1341
1342
 
1342
1343
 
1343
1344
  def get_adjacent_cells(
@@ -0,0 +1,154 @@
1
+ """Private module for translating coordiantes plus flipping and rotation."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import math
6
+ from typing import TYPE_CHECKING
7
+
8
+ import numpy as np
9
+
10
+ if TYPE_CHECKING:
11
+ from xtgeo.grid3d import Grid
12
+
13
+
14
+ def _rotate_grid3d(
15
+ new_grd: Grid, add_rotation: float, rotation_xy: tuple[float, float] | None = None
16
+ ) -> None:
17
+ """Rotate the grid around the cell 1,1,1 corner, or some other coordinate."""
18
+
19
+ # Convert angle to radians
20
+ angle_rad = math.radians(add_rotation)
21
+
22
+ # Create rotation matrix coefficients
23
+ cos_theta = math.cos(angle_rad)
24
+ sin_theta = math.sin(angle_rad)
25
+
26
+ # extract
27
+ coord_array = new_grd._coordsv.copy()
28
+ rotated_coords = coord_array.copy()
29
+
30
+ if rotation_xy is None:
31
+ x0, y0, _ = new_grd._coordsv[0, 0, :3]
32
+ else:
33
+ x0, y0 = rotation_xy
34
+
35
+ x_coords = coord_array[:, :, [0, 3]].copy() # x1 and x2
36
+ y_coords = coord_array[:, :, [1, 4]].copy() # y1 and y2
37
+
38
+ # Translate to origin
39
+ x_translated = x_coords - x0
40
+ y_translated = y_coords - y0
41
+
42
+ # Rotate using rotation matrix
43
+ x_rotated = x_translated * cos_theta - y_translated * sin_theta
44
+ y_rotated = x_translated * sin_theta + y_translated * cos_theta
45
+
46
+ # Translate back and assign
47
+ rotated_coords[:, :, [0, 3]] = x_rotated + x0
48
+ rotated_coords[:, :, [1, 4]] = y_rotated + y0
49
+
50
+ # Z coordinates remain unchanged (indices 2 and 5)
51
+ new_grd._coordsv = rotated_coords.copy()
52
+
53
+
54
+ def _flip_vertically(grid: Grid) -> None:
55
+ """Flip the grid vertically."""
56
+
57
+ # find average depth of corners
58
+ avg_z = grid._zcornsv.mean()
59
+
60
+ grid._zcornsv = grid._zcornsv[:, :, ::-1, :]
61
+ grid._zcornsv *= -1
62
+
63
+ # find the new average and compute the difference for shifting
64
+ new_avg_z = grid._zcornsv.mean()
65
+ diff = avg_z - new_avg_z
66
+ grid._zcornsv += diff
67
+
68
+ grid._actnumsv = np.flip(grid._actnumsv, axis=2).copy()
69
+
70
+ # Handle properties if they exist
71
+ if grid._props and grid._props.props:
72
+ for prop in grid._props.props:
73
+ prop.values = np.flip(prop.values, axis=2).copy()
74
+
75
+ # When we flip the grid, the subgrid info must also be flipped
76
+ subgrids = grid.get_subgrids()
77
+ if subgrids:
78
+ reverted = dict(reversed(subgrids.items()))
79
+ grid.set_subgrids(reverted)
80
+
81
+ if grid._ijk_handedness == "left":
82
+ grid._ijk_handedness = "right"
83
+ else:
84
+ grid._ijk_handedness = "left"
85
+
86
+
87
+ def _translate_geometry(grid: Grid, translate: tuple[float, float, float]) -> None:
88
+ grid._coordsv[:, :, 0] += translate[0]
89
+ grid._coordsv[:, :, 1] += translate[1]
90
+ grid._coordsv[:, :, 2] += translate[2]
91
+ grid._coordsv[:, :, 3] += translate[0]
92
+ grid._coordsv[:, :, 4] += translate[1]
93
+ grid._coordsv[:, :, 5] += translate[2]
94
+
95
+ grid._zcornsv += translate[2]
96
+
97
+
98
+ def _transfer_to_target(grid: Grid, target: tuple[float, float, float]) -> None:
99
+ # get the coordinates for the active cells
100
+ x, y, z = grid.get_xyz(asmasked=True)
101
+
102
+ # set the grid center to the desired target coordinates
103
+ shift_x = target[0] - x.values.mean()
104
+ shift_y = target[1] - y.values.mean()
105
+ shift_z = target[2] - z.values.mean()
106
+
107
+ _translate_geometry(grid, (shift_x, shift_y, shift_z))
108
+
109
+
110
+ def translate_coordinates(
111
+ self: Grid,
112
+ translate: tuple[float, float, float] = (0.0, 0.0, 0.0),
113
+ flip: tuple[int, int, int] = (1, 1, 1),
114
+ add_rotation: float = 0.0,
115
+ rotation_point: tuple[float, float] | None = None,
116
+ target_coordinates: tuple[float, float, float] | None = None,
117
+ ) -> None:
118
+ """Rotate, flip grid and translate grid coordinates.
119
+
120
+ This should be done in a sequence like this
121
+ 1) Add rotation (with value ``add_rotation``) to rotate the grid counter-clockwise
122
+ 2) Flip the grid
123
+ 3a) translate the grid by adding (x, y, z), OR
124
+ 3b) set a target location the grid centre.
125
+
126
+ """
127
+ self._set_xtgformat2()
128
+
129
+ if abs(add_rotation) > 1e-10: # Skip rotation if angle is essentially zero
130
+ _rotate_grid3d(self, add_rotation, rotation_xy=rotation_point)
131
+
132
+ if flip[2] == -1:
133
+ _flip_vertically(self)
134
+
135
+ if flip[0] == -1:
136
+ self.reverse_column_axis()
137
+
138
+ if flip[1] == -1:
139
+ self.reverse_row_axis()
140
+
141
+ use_translate = False
142
+ if not all(abs(x) < 1e-10 for x in translate):
143
+ _translate_geometry(self, translate)
144
+ use_translate = True
145
+
146
+ if target_coordinates and use_translate:
147
+ raise ValueError(
148
+ "Using both key 'translate' and key 'target_coordinates' is not allowed. "
149
+ "Use either."
150
+ )
151
+
152
+ if target_coordinates:
153
+ # transfer the grid's geometrical centre to a given location
154
+ _transfer_to_target(self, target_coordinates)
xtgeo/grid3d/grid.py CHANGED
@@ -28,6 +28,7 @@ from . import (
28
28
  _grid_import_ecl,
29
29
  _grid_refine,
30
30
  _grid_roxapi,
31
+ _grid_translate_coords,
31
32
  _grid_wellzone,
32
33
  _gridprop_lowlevel,
33
34
  )
@@ -2480,21 +2481,48 @@ class Grid(_Grid3D):
2480
2481
  def translate_coordinates(
2481
2482
  self,
2482
2483
  translate: tuple[float, float, float] = (0.0, 0.0, 0.0),
2484
+ target_coordinates: tuple[float, float, float] | None = None,
2483
2485
  flip: tuple[int, int, int] = (1, 1, 1),
2484
- ) -> None:
2485
- """Translate (move) and/or flip grid coordinates in 3D.
2486
+ add_rotation: float = 0.0,
2487
+ rotation_point: tuple[float, float] | None = None,
2488
+ ) -> Grid | None:
2489
+ """Translate (move), flip and rotate the 3D grid geometry.
2486
2490
 
2487
- By 'flip' here, it means that the full coordinate array are multiplied
2488
- with -1.
2491
+ By 'flip' here, it means that the full coordinate arrays are inverted.
2489
2492
 
2490
2493
  Args:
2491
- translate (tuple): Translation distance in X, Y, Z coordinates
2492
- flip (tuple): Flip array. The flip values must be 1 or -1.
2494
+ translate: Translation distance in X, Y, Z coordinates; these
2495
+ values will be added to the current coordinates.
2496
+ target_coordinates: Position for the centerpoint of the active grid cells.
2497
+ Note that key ``translate`` cannot be used with this key; i.e. use
2498
+ either ``translate`` or ``target_coordinates``
2499
+ flip: Flip array. The flip values must be 1 or -1, meaning 1 for
2500
+ keeping the current, and -1 for activating an axis flip.
2501
+ add_rotation: The grid geometry will get an additional rotation by this
2502
+ value, in degrees and counter clock wise.
2503
+ rotation_point: Which (x, y) coordiate to be set as origin when adding
2504
+ rotation. Default is the corner of the first cell number.
2505
+
2506
+ Note:
2507
+ Grid properties attached to the grid will also be transformed
2508
+
2509
+ Example::
2510
+ import xtgeo
2511
+ grd = xtgeo.grid_from_roxar(project, "simpleb8")
2512
+ poro = xtgeo.gridproperty_from_roxar(project, "simpleb8", "PORO")
2513
+ grd.props = [poro]
2514
+
2515
+ grd.translate_coordinates(translate=(10,10, 20), flip=(1,1,-1),
2516
+ add_rotation=30)
2517
+
2518
+ grd.to_roxar(project, "simpleb8_translated")
2519
+ poro1 = grd.get_prop_by_name("PORO")
2520
+ poro1.to_roxar(project, "simpleb8_translated", "PORO")
2493
2521
 
2494
- Raises:
2495
- RuntimeError: If translation goes wrong for unknown reasons
2496
2522
  """
2497
- _grid_etc1.translate_coordinates(self, translate=translate, flip=flip)
2523
+ _grid_translate_coords.translate_coordinates(
2524
+ self, translate, flip, add_rotation, rotation_point, target_coordinates
2525
+ )
2498
2526
 
2499
2527
  def reverse_row_axis(
2500
2528
  self, ijk_handedness: Literal["left", "right"] | None = None
@@ -2502,7 +2530,7 @@ class Grid(_Grid3D):
2502
2530
  """Reverse the row axis (J indices).
2503
2531
 
2504
2532
  This means that IJK system will switched between a left vs right handed system.
2505
- It is here (by using ijk_handedness key), possible to set a wanted stated.
2533
+ It is here (by using ijk_handedness key), possible to set a wanted handedness.
2506
2534
 
2507
2535
  Note that properties that are assosiated with the grid (through the
2508
2536
  :py:attr:`~gridprops` or :py:attr:`~props` attribute) will also be
@@ -2528,6 +2556,38 @@ class Grid(_Grid3D):
2528
2556
  """
2529
2557
  _grid_etc1.reverse_row_axis(self, ijk_handedness=ijk_handedness)
2530
2558
 
2559
+ def reverse_column_axis(
2560
+ self, ijk_handedness: Literal["left", "right"] | None = None
2561
+ ) -> None:
2562
+ """Reverse the column axis (I indices).
2563
+
2564
+ This means that IJK system will switched between a left vs right handed system.
2565
+ It is here (by using ijk_handedness key), possible to set a wanted handedness.
2566
+
2567
+ Note that properties that are assosiated with the grid (through the
2568
+ :py:attr:`~gridprops` or :py:attr:`~props` attribute) will also be
2569
+ reversed (which is desirable).
2570
+
2571
+ Args:
2572
+ ijk_handedness (str): If set to "right" or "left", do only reverse columns
2573
+ if handedness is not already achieved.
2574
+
2575
+ Example::
2576
+
2577
+ grd = xtgeo.grid_from_file("somefile.roff")
2578
+ prop1 = xtgeo.gridproperty_from_file("somepropfile1.roff")
2579
+ prop2 = xtgeo.gridproperty_from_file("somepropfile2.roff")
2580
+
2581
+ grd.props = [prop1, prop2]
2582
+
2583
+ # secure that the grid geometry is IJK right-handed
2584
+ grd.reverse_column_axis(ijk_handedness="right")
2585
+
2586
+ .. versionadded:: 4.14
2587
+
2588
+ """
2589
+ _grid_etc1.reverse_column_axis(self, ijk_handedness=ijk_handedness)
2590
+
2531
2591
  def make_zconsistent(self, zsep: float | int = 1e-5) -> None:
2532
2592
  """Make the 3D grid consistent in Z, by a minimal gap (zsep).
2533
2593
 
xtgeo/io/_file.py CHANGED
@@ -227,7 +227,7 @@ class FileWrapper:
227
227
  date = obj.metadata.opt.datetime # type: ignore
228
228
  newname = short + "--" + desc
229
229
  if date:
230
- newname += "--" + date
230
+ newname += "--" + str(date)
231
231
  else:
232
232
  # return without modifications of self._file to avoid with_suffix() issues
233
233
  # if the file name stem itself contains multiple '.'
@@ -21,6 +21,12 @@ from xtgeo.common.log import null_logger
21
21
  if TYPE_CHECKING:
22
22
  from datetime import datetime
23
23
 
24
+ from xtgeo.cube.cube1 import Cube
25
+ from xtgeo.grid3d.grid import Grid, GridProperty
26
+ from xtgeo.surface.regular_surface import RegularSurface
27
+ from xtgeo.well.well1 import Well
28
+
29
+
24
30
  logger = null_logger(__name__)
25
31
 
26
32
 
@@ -56,11 +62,11 @@ class _OptionalMetaData:
56
62
  def __init__(self) -> None:
57
63
  self._name = "A Longer Descriptive Name e.g. from SMDA"
58
64
  self._shortname = "TheShortName"
59
- self._datatype = None
65
+ self._datatype: str | None = None
60
66
  self._md5sum: str | None = None
61
67
  self._description = "Some description"
62
68
  self._crs = None
63
- self._datetime: datetime | None = None
69
+ self._datetime: datetime | str | None = None
64
70
  self._deltadatetime = None
65
71
  self._visuals = {"colortable": "rainbow", "lower": None, "upper": None}
66
72
  self._domain = "depth"
@@ -84,11 +90,11 @@ class _OptionalMetaData:
84
90
  self._name = newname
85
91
 
86
92
  @property
87
- def datetime(self) -> datetime | None:
93
+ def datetime(self) -> datetime | str | None:
88
94
  return self._datetime
89
95
 
90
96
  @datetime.setter
91
- def datetime(self, newdate: datetime) -> None:
97
+ def datetime(self, newdate: datetime | str) -> None:
92
98
  # TODO: validation
93
99
  self._datetime = newdate
94
100
 
@@ -147,15 +153,15 @@ class _OptionalMetaData:
147
153
  class MetaData:
148
154
  """Generic metadata class, not intended to be used directly."""
149
155
 
150
- def __init__(self):
156
+ def __init__(self) -> None:
151
157
  """Generic metadata class __init__, not be used directly."""
152
- self._required = {}
158
+ self._required: dict[str, Any] = {}
153
159
  self._optional = _OptionalMetaData()
154
160
  self._freeform = {}
155
161
 
156
162
  self._freeform = {"smda": "whatever"}
157
163
 
158
- def get_metadata(self):
164
+ def get_metadata(self) -> dict[str, Any]:
159
165
  """Get all metadata that are present."""
160
166
  allmeta = {}
161
167
  allmeta["_required_"] = self._required
@@ -164,7 +170,7 @@ class MetaData:
164
170
  return allmeta
165
171
 
166
172
  @property
167
- def optional(self):
173
+ def optional(self) -> dict[str, Any]:
168
174
  """Return or set optional metadata.
169
175
 
170
176
  When setting optional names, it can be done in several ways...
@@ -176,7 +182,7 @@ class MetaData:
176
182
  return self._optional.get_meta()
177
183
 
178
184
  @optional.setter
179
- def optional(self, indict):
185
+ def optional(self, indict: dict[str, Any]) -> None:
180
186
  # setting the optional key, including validation
181
187
  if not isinstance(indict, dict):
182
188
  raise ValueError(f"Input must be a dictionary, not a {type(indict)}")
@@ -185,7 +191,7 @@ class MetaData:
185
191
  setattr(self._optional, "_" + key, value)
186
192
 
187
193
  @property
188
- def opt(self):
194
+ def opt(self) -> _OptionalMetaData:
189
195
  """Return the metadata optional instance.
190
196
 
191
197
  This makes access to the _OptionalMetaData instance.
@@ -198,26 +204,17 @@ class MetaData:
198
204
  """
199
205
  return self._optional
200
206
 
201
- @optional.setter
202
- def optional(self, indict):
203
- # setting the optional key, including validation
204
- if not isinstance(indict, dict):
205
- raise ValueError(f"Input must be a dictionary, not a {type(indict)}")
206
-
207
- for key, value in indict.items():
208
- setattr(self._optional, "_" + key, value)
209
-
210
207
  @property
211
- def freeform(self):
208
+ def freeform(self) -> dict[str, Any]:
212
209
  """Get or set the current freeform metadata dictionary."""
213
210
  return self._freeform
214
211
 
215
212
  @freeform.setter
216
- def freeform(self, adict):
213
+ def freeform(self, adict: dict[str, Any]) -> None:
217
214
  """Freeform is a whatever you want set, without any validation."""
218
215
  self._freeform = adict.copy()
219
216
 
220
- def generate_fmu_name(self):
217
+ def generate_fmu_name(self) -> str:
221
218
  """Generate FMU name on form xxxx--yyyy--date but no suffix."""
222
219
  fname = ""
223
220
  first = "prefix"
@@ -233,7 +230,7 @@ class MetaData:
233
230
  class MetaDataRegularSurface(MetaData):
234
231
  """Metadata for RegularSurface() objects."""
235
232
 
236
- REQUIRED = {
233
+ REQUIRED: dict[str, Any] = {
237
234
  "ncol": 1,
238
235
  "nrow": 1,
239
236
  "xori": 0.0,
@@ -245,20 +242,20 @@ class MetaDataRegularSurface(MetaData):
245
242
  "undef": UNDEF,
246
243
  }
247
244
 
248
- def __init__(self):
245
+ def __init__(self) -> None:
249
246
  """Docstring."""
250
247
  super().__init__()
251
- self._required = __class__.REQUIRED
248
+ self._required = self.REQUIRED
252
249
  self._optional._datatype = "Regular Surface"
253
250
 
254
251
  @property
255
- def required(self):
252
+ def required(self) -> dict[str, Any]:
256
253
  """Get of set required metadata."""
257
254
  return self._required
258
255
 
259
256
  @required.setter
260
- def required(self, obj):
261
- if not isinstance(obj, xtgeo.RegularSurface):
257
+ def required(self, obj: RegularSurface) -> None:
258
+ if not isinstance(obj, xtgeo.RegularSurface): # type: ignore[attr-defined]
262
259
  raise ValueError("Input object is not a RegularSurface()")
263
260
 
264
261
  self._required["ncol"] = obj.ncol
@@ -276,7 +273,7 @@ class MetaDataRegularCube(MetaData):
276
273
  """Metadata for Cube() objects."""
277
274
 
278
275
  # allowed optional keys; these are set to avoid discussions
279
- REQUIRED = {
276
+ REQUIRED: dict[str, Any] = {
280
277
  "ncol": 1,
281
278
  "nrow": 1,
282
279
  "nlay": 1,
@@ -292,20 +289,20 @@ class MetaDataRegularCube(MetaData):
292
289
  "undef": UNDEF,
293
290
  }
294
291
 
295
- def __init__(self):
292
+ def __init__(self) -> None:
296
293
  """Docstring."""
297
294
  super().__init__()
298
- self._required = __class__.REQUIRED
295
+ self._required = self.REQUIRED
299
296
  self._optional._datatype = "Regular Cube"
300
297
 
301
298
  @property
302
- def required(self):
299
+ def required(self) -> dict[str, Any]:
303
300
  """Get of set required metadata."""
304
301
  return self._required
305
302
 
306
303
  @required.setter
307
- def required(self, obj):
308
- if not isinstance(obj, xtgeo.Cube):
304
+ def required(self, obj: Cube) -> None:
305
+ if not isinstance(obj, xtgeo.Cube): # type: ignore[attr-defined]
309
306
  raise ValueError("Input object is not a regular Cube()")
310
307
 
311
308
  self._required["ncol"] = obj.ncol
@@ -326,7 +323,7 @@ class MetaDataRegularCube(MetaData):
326
323
  class MetaDataCPGeometry(MetaData):
327
324
  """Metadata for Grid() objects of type simplified CornerPoint Geometry."""
328
325
 
329
- REQUIRED = {
326
+ REQUIRED: dict[str, Any] = {
330
327
  "ncol": 1,
331
328
  "nrow": 1,
332
329
  "nlay": 1,
@@ -338,20 +335,20 @@ class MetaDataCPGeometry(MetaData):
338
335
  "zscale": 1.0,
339
336
  }
340
337
 
341
- def __init__(self):
338
+ def __init__(self) -> None:
342
339
  """Docstring."""
343
340
  super().__init__()
344
- self._required = __class__.REQUIRED
341
+ self._required = self.REQUIRED
345
342
  self._optional._datatype = "CornerPoint GridGeometry"
346
343
 
347
344
  @property
348
- def required(self):
345
+ def required(self) -> dict[str, Any]:
349
346
  """Get of set required metadata."""
350
347
  return self._required
351
348
 
352
349
  @required.setter
353
- def required(self, obj):
354
- if not isinstance(obj, xtgeo.Grid):
350
+ def required(self, obj: Grid) -> None:
351
+ if not isinstance(obj, xtgeo.Grid): # type: ignore[attr-defined]
355
352
  raise ValueError("Input object is not a Grid()")
356
353
 
357
354
  self._required["ncol"] = obj.ncol
@@ -369,7 +366,7 @@ class MetaDataCPGeometry(MetaData):
369
366
  class MetaDataCPProperty(MetaData):
370
367
  """Metadata for GridProperty() objects belonging to CPGeometry."""
371
368
 
372
- REQUIRED = {
369
+ REQUIRED: dict[str, Any] = {
373
370
  "ncol": 1,
374
371
  "nrow": 1,
375
372
  "nlay": 1,
@@ -377,20 +374,20 @@ class MetaDataCPProperty(MetaData):
377
374
  "discrete": False,
378
375
  }
379
376
 
380
- def __init__(self):
377
+ def __init__(self) -> None:
381
378
  """Docstring."""
382
379
  super().__init__()
383
- self._required = __class__.REQUIRED
380
+ self._required = self.REQUIRED
384
381
  self._optional._datatype = "CornerPoint GridProperty"
385
382
 
386
383
  @property
387
- def required(self):
384
+ def required(self) -> dict[str, Any]:
388
385
  """Get of set required metadata."""
389
386
  return self._required
390
387
 
391
388
  @required.setter
392
- def required(self, obj):
393
- if not isinstance(obj, xtgeo.GridProperty):
389
+ def required(self, obj: GridProperty) -> None:
390
+ if not isinstance(obj, xtgeo.GridProperty): # type: ignore[attr-defined]
394
391
  raise ValueError("Input object is not a GridProperty()")
395
392
 
396
393
  self._required["ncol"] = obj.ncol
@@ -403,7 +400,7 @@ class MetaDataCPProperty(MetaData):
403
400
  class MetaDataWell(MetaData):
404
401
  """Metadata for single Well() objects."""
405
402
 
406
- REQUIRED = {
403
+ REQUIRED: dict[str, Any] = {
407
404
  "rkb": 0.0,
408
405
  "xpos": 0.0,
409
406
  "ypos": 0.0,
@@ -413,20 +410,20 @@ class MetaDataWell(MetaData):
413
410
  "zonelogname": None,
414
411
  }
415
412
 
416
- def __init__(self):
413
+ def __init__(self) -> None:
417
414
  """Initialisation for Well metadata."""
418
415
  super().__init__()
419
- self._required = __class__.REQUIRED
416
+ self._required = self.REQUIRED
420
417
  self._optional._datatype = "Well"
421
418
 
422
419
  @property
423
- def required(self):
420
+ def required(self) -> dict[str, Any]:
424
421
  """Get of set required metadata."""
425
422
  return self._required
426
423
 
427
424
  @required.setter
428
- def required(self, obj):
429
- if not isinstance(obj, xtgeo.Well):
425
+ def required(self, obj: Well) -> None:
426
+ if not isinstance(obj, xtgeo.Well): # type: ignore[attr-defined]
430
427
  raise ValueError("Input object is not a Well() instance!")
431
428
 
432
429
  self._required["rkb"] = obj.rkb
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: xtgeo
3
- Version: 4.13.0
3
+ Version: 4.13.1
4
4
  Summary: XTGeo is a Python library for 3D grids, surfaces, wells, etc
5
5
  Keywords: grids,surfaces,wells,cubes
6
6
  Author-Email: Equinor <fg_fmu-atlas@equinor.com>
@@ -1,8 +1,8 @@
1
- cxtgeo.py,sha256=LpfocX7SkcH-Mm-gU7vK4ZnVJVGhAaoQVXTt00YOmlA,32678
2
- cxtgeoPYTHON_wrap.c,sha256=Jqhwcya3gd-D86SRQpO3t0tfguuj2ODX64spcw_HxVg,636863
1
+ cxtgeo.py,sha256=Am9tF-v-D87wEB9lzenKD601MEQUDVLkgy0ZL0eZ2zw,32172
2
+ cxtgeoPYTHON_wrap.c,sha256=NAOsLVPMklaVIaeRS9Z-k2-obR5na8HnUEQrWS6HfGM,629898
3
3
  xtgeo/__init__.py,sha256=edNCOXuPS5qjutDGX5-2Pz0T2Lpx1GoeG3IoeXUdBw8,5834
4
- xtgeo/_cxtgeo.cp312-win_amd64.pyd,sha256=SsWTB5o7z0Nfdq9Ov_RcYs8pAp55VKzssmIosM9vitI,698368
5
- xtgeo/_internal.cp312-win_amd64.pyd,sha256=xywygmJ-rjGXQAUfsrLeixYkWeYFVG1bJOxoXMDQXuQ,1122304
4
+ xtgeo/_cxtgeo.cp312-win_amd64.pyd,sha256=Jh-AW4B_kR7jxf41l8YU2izrn3H9z_tnyiLE8RyFz5Y,689664
5
+ xtgeo/_internal.cp312-win_amd64.pyd,sha256=kR9Qg2URU7VnL1VPLlSey0cfMLzyg9NuwIhjkSc9oCE,1122304
6
6
  xtgeo/common/__init__.py,sha256=6R_OizhLnAoJUmUoQtGqgNvGcn1HWc4udc6YvRRlxWQ,480
7
7
  xtgeo/common/_angles.py,sha256=fAX5FzgqIjjIDe9_C7gy6zPjdaSQuzMb8Z2XdKSx-6Y,851
8
8
  xtgeo/common/_xyz_enum.py,sha256=gb1PVOWMTRb4YGDq9Q0YVVkKqMyI_xBg1vUBvOLXlfs,1095
@@ -12,7 +12,7 @@ xtgeo/common/exceptions.py,sha256=OZyU9C8cS4NhCnjQyREfuoVy9mdvGCiccd4nC9yn_N4,12
12
12
  xtgeo/common/log.py,sha256=8-wTrZd87UNr_ZEb_lZvR1khUeKmIO_UECMpV_Q_btM,2835
13
13
  xtgeo/common/sys.py,sha256=lvvmS4D7qaAVVg5UueNSt44WeEgpZcmyINEGKLHXctM,5144
14
14
  xtgeo/common/types.py,sha256=LanIGZh0HU2XXfJelZA-FC__J6fLB1DzuN7jj7hNSgU,362
15
- xtgeo/common/version.py,sha256=3GfILrgbGmS7LIafEAcI93zYnldfjDfKDxNluh7L6I0,748
15
+ xtgeo/common/version.py,sha256=OGkAupIM0EdocaPdwDfusf_WN0L4C7ZBzaQIrLvgxxw,748
16
16
  xtgeo/common/xtgeo_dialog.py,sha256=XX445byFvdRjT2Eg9Mgd3ChRQ9d1Mj5MEdsBRYBSo8A,17733
17
17
  xtgeo/cube/__init__.py,sha256=5_F9Cefu4081jIwDqsyJGKTlrVLe1UfwI8wQXVRYPDM,169
18
18
  xtgeo/cube/_cube_export.py,sha256=YcU_0c_kFyh8T_ytY8XRR9Bmt8KK3J1taMLzo_w_m4c,6659
@@ -34,7 +34,7 @@ xtgeo/grid3d/_grid3d.py,sha256=rTqfhwK4dNX1A5M-xUC-9hWwfxrkX6_TVgwc79KCXCI,769
34
34
  xtgeo/grid3d/_grid3d_fence.py,sha256=yDmKwlErNCl13vV7opJjKlzlwCzwk2gSJnzIb4jGpHg,9501
35
35
  xtgeo/grid3d/_grid3d_utils.py,sha256=VBbdzah_D8yeaMU4vMQRYTFRKq95QaGqPk4oXYBWdHw,7477
36
36
  xtgeo/grid3d/_grid_boundary.py,sha256=xNumtMeOfjmwS5vzv1Nl_yZpGiDEQXk896pXzugdUVs,2384
37
- xtgeo/grid3d/_grid_etc1.py,sha256=DBq1__wemVhjfk42HrADrwwygXbb0DckEvSvYue0yHo,45551
37
+ xtgeo/grid3d/_grid_etc1.py,sha256=wrZhrqxM2_1NTgGawQyyy0WWN-bGRMdE1t7yFd6RxlU,46602
38
38
  xtgeo/grid3d/_grid_export.py,sha256=G36va-Kz93W-P2z8Qr-0Dq-o7Abfsd3OC8ESCAFRh2M,7492
39
39
  xtgeo/grid3d/_grid_hybrid.py,sha256=jMkLIEkab3f9_I8cKAc9wKczZZ3HpBFhwYwyBme6fe4,1305
40
40
  xtgeo/grid3d/_grid_import.py,sha256=Y11JDjf5tZkDth69aTtbkMfMjRbVvSnQbV3lt-jCuA8,2672
@@ -43,6 +43,7 @@ xtgeo/grid3d/_grid_import_roff.py,sha256=davWOUvCYPbvSFKm5bDCJJNPR-9uW_bOn4faGBh
43
43
  xtgeo/grid3d/_grid_import_xtgcpgeom.py,sha256=ZVqkf1QAvv8iDFZxV-2AhGimUjAdFcMwFml7yqocACU,10577
44
44
  xtgeo/grid3d/_grid_refine.py,sha256=jjYgBySFOE1qDaZwPshttkawjyVWPbHW1h3dj7qprQI,8816
45
45
  xtgeo/grid3d/_grid_roxapi.py,sha256=ixanN3VNGQM3QeVxXLHj_hKZJSiG3cdZwHc2NdXg_ms,9199
46
+ xtgeo/grid3d/_grid_translate_coords.py,sha256=EvexYZyvtsTFsd2Pdg9UkmNXq8ZE2Q-jX0Dv48Ib8Lk,4850
46
47
  xtgeo/grid3d/_grid_wellzone.py,sha256=5OwMsmksC0Wza5XXfUiDHCzSLWqmV3JbSORDUFPXZho,5951
47
48
  xtgeo/grid3d/_gridprop_export.py,sha256=wKYm6UhRCrDwf74V_HuWvdlYKgET6iIm8i1fGpPgbGY,6735
48
49
  xtgeo/grid3d/_gridprop_import_eclrun.py,sha256=E8fgp5VFbJknoitP-t2JJv5LcIUuLutIDJuVXBS_ugE,5260
@@ -57,14 +58,14 @@ xtgeo/grid3d/_gridprops_import_eclrun.py,sha256=M7hvBazZPjYsKOYBL1SHCcYqztgonARu
57
58
  xtgeo/grid3d/_gridprops_import_roff.py,sha256=fCCMwa8OgLXk9zMvFpr4nfsKLkmBFKKLSfLwUHenyTA,2550
58
59
  xtgeo/grid3d/_roff_grid.py,sha256=kppx044-JmfLvaIt5NPABnIoLwJ1BGQc2gFeog7Cl0g,17742
59
60
  xtgeo/grid3d/_roff_parameter.py,sha256=9gVlFMyT2QbwUvm_FCJG0hTvJPrK2Y86kbeljs2eCbc,11376
60
- xtgeo/grid3d/grid.py,sha256=P-uO-wBiN1wok-RVpcICd49zW3iI86s9QpXwU7BPOT0,110086
61
+ xtgeo/grid3d/grid.py,sha256=sjQnS-peWf1ZcI7P_NMJq-WQcrpHWLslTuDjdkCcY2c,112768
61
62
  xtgeo/grid3d/grid_properties.py,sha256=OlIyo1PXrTRFHGn8avXdBXNpFM5DJuLjVRB9koayKGQ,24993
62
63
  xtgeo/grid3d/grid_property.py,sha256=Wm9H6Nzqs8fSD35eg3NqTb-i6HGThsRmwbynZLg1nMo,45980
63
64
  xtgeo/grid3d/types.py,sha256=eaBHJL91zXV0ipaY30K_ZpEdUfjj681CoAbKfvNZ_5Q,290
64
65
  xtgeo/io/__init__.py,sha256=k5OQUG7ePoTleAh8ECiwowCg1imL6dx9O7gPUArcQQw,23
65
- xtgeo/io/_file.py,sha256=-bacKEMpbPMF1al3gqoV5pu0J57g26mRdSasxNk20Gg,21085
66
+ xtgeo/io/_file.py,sha256=ij_SgzZJTks4W9j0KX26qEHU0JTF9ZJCCklgajj0eQQ,21090
66
67
  xtgeo/metadata/__init__.py,sha256=VV81ga8OzzrowieSQZ5bZxo3Ug70Dch89iwZF1mOshA,337
67
- xtgeo/metadata/metadata.py,sha256=0EVNcXXDh3mimYNZYW3FIYe3bXIzeEKRyqZOzBhu31E,12874
68
+ xtgeo/metadata/metadata.py,sha256=4avOpkzwPWV9HblUhRptvnOpKKfMk8tB4KiZPgwl1p4,13339
68
69
  xtgeo/roxutils/__init__.py,sha256=_f2qb32IFeZ_8YhcTDFlNgsWyH0HPDJQ7V0qUbjmUSs,99
69
70
  xtgeo/roxutils/_roxar_loader.py,sha256=mKg3SsHJDzaGEYQwuY2yPcTxOnCybKmq3IeLmteCJPg,1958
70
71
  xtgeo/roxutils/_roxutils_etc.py,sha256=Lma5Hskrld2PDLicSTkASse2t3eqxvtnure9uDCyjxo,3852
@@ -111,7 +112,7 @@ xtgeo/xyz/_xyz_oper.py,sha256=_uCR-PYEsPQkBKh82oDvUsz7Y2vqsjqoiEdfmd8HIEU,20058
111
112
  xtgeo/xyz/_xyz_roxapi.py,sha256=NWgnPShA8amuHgSTqvy5_y21Qyx2s_6IWP1qPyHTPb8,26585
112
113
  xtgeo/xyz/points.py,sha256=LObAxc8EC5-wxWFX8HJ9F-ouw0uoHdOpvswd-SIB8KQ,23280
113
114
  xtgeo/xyz/polygons.py,sha256=JjvA5BiW0HzaVmuZjnKB55n0OJXZfjOBQHfSNcZBDiA,28791
114
- xtgeo-4.13.0.dist-info/METADATA,sha256=g7Q3-TQzr0JfUPoAFqOJrNDHadbmRe_dqN2HoZChR2U,5779
115
- xtgeo-4.13.0.dist-info/WHEEL,sha256=chqeLhPBtPdrOoreR34YMcofSk3yWDQhkrsDJ2n48LU,106
116
- xtgeo-4.13.0.dist-info/licenses/LICENSE.md,sha256=fTqV5eBpeAZO0_jit8j4Ref9ikBSlHJ8xwj5TLg7gFk,7817
117
- xtgeo-4.13.0.dist-info/RECORD,,
115
+ xtgeo-4.13.1.dist-info/METADATA,sha256=20bqQS_a1pJsjxiMvqiW71i8Mv-k8gaMNxHxlF8dzgs,5779
116
+ xtgeo-4.13.1.dist-info/WHEEL,sha256=chqeLhPBtPdrOoreR34YMcofSk3yWDQhkrsDJ2n48LU,106
117
+ xtgeo-4.13.1.dist-info/licenses/LICENSE.md,sha256=fTqV5eBpeAZO0_jit8j4Ref9ikBSlHJ8xwj5TLg7gFk,7817
118
+ xtgeo-4.13.1.dist-info/RECORD,,
File without changes