resqpy 4.12.0__py3-none-any.whl → 4.12.2__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
resqpy/__init__.py CHANGED
@@ -28,6 +28,6 @@
28
28
 
29
29
  import logging
30
30
 
31
- __version__ = "4.12.0" # Set at build time
31
+ __version__ = "4.12.2" # Set at build time
32
32
  log = logging.getLogger(__name__)
33
33
  log.info(f"Imported resqpy version {__version__}")
resqpy/lines/_polyline.py CHANGED
@@ -8,15 +8,15 @@ import math as maths
8
8
  import numpy as np
9
9
  import warnings
10
10
 
11
- import resqpy.olio.intersection as meet
12
- import resqpy.lines
11
+ import resqpy.crs as rqc
12
+ import resqpy.lines._common as rql_c
13
13
  import resqpy.property as rqp
14
14
  import resqpy.olio.point_inclusion as pip
15
15
  import resqpy.olio.uuid as bu
16
16
  import resqpy.olio.vector_utilities as vu
17
17
  import resqpy.olio.write_hdf5 as rwh5
18
18
  import resqpy.olio.xml_et as rqet
19
- import resqpy.lines._common as rql_c
19
+ import resqpy.olio.intersection as meet
20
20
  from resqpy.olio.xml_namespaces import curly_namespace as ns
21
21
 
22
22
 
@@ -330,21 +330,17 @@ class Polyline(rql_c._BasePolyline):
330
330
  return result
331
331
 
332
332
  def is_clockwise(self, trust_metadata = True):
333
- """Returns True if first non-straight triplet of nodes is clockwise in the xy plane; False if anti-clockwise.
334
-
335
- note:
336
- this method currently assumes that the xy axes are left-handed
337
- """
333
+ """Returns True if closed polyline is clockwise when viewed from above; False if anti-clockwise."""
338
334
 
335
+ assert self.isclosed, 'Polyline.is_clockwise() called for open polyline (only applicable to closed polylines)'
339
336
  if trust_metadata and self.extra_metadata is not None and 'is_clockwise' in self.extra_metadata.keys():
340
337
  return str(self.extra_metadata['is_clockwise']).lower() == 'true'
341
- result = None
342
- for node in range(3, len(self.coordinates)):
343
- cw = vu.clockwise(self.coordinates[node - 2], self.coordinates[node - 1], self.coordinates[node])
344
- if cw == 0.0:
345
- continue # striaght line section
346
- result = (cw > 0.0)
347
- break
338
+ centre = np.mean(self.coordinates, axis = 0)
339
+ cw = vu.clockwise(centre, self.coordinates[0], self.coordinates[1])
340
+ result = (cw > 0.0)
341
+ crs = rqc.Crs(self.model, uuid = self.crs_uuid)
342
+ if crs.is_right_handed_xy():
343
+ result = not result
348
344
  if result is not None:
349
345
  self.append_extra_metadata({'is_clockwise': str(result).lower()})
350
346
  return result
@@ -716,8 +712,8 @@ class Polyline(rql_c._BasePolyline):
716
712
 
717
713
  assert mode in ['square', 'perimeter', 'circle']
718
714
  assert 0.0 <= norm_x <= 1.0 and 0.0 <= norm_y <= 1.0
719
- assert self.is_convex(
720
- ), 'attempt to find denormalised x,y within a polyline that is not a closed convex polygon'
715
+ assert self.is_convex(), \
716
+ 'attempt to find denormalised x,y within a polyline that is not a closed convex polygon'
721
717
  centre_xy = self.balanced_centre()[:2]
722
718
  x, y = None, None
723
719
  if mode == 'square':
@@ -466,23 +466,29 @@ class PolylineSet(rql_c._BasePolyline):
466
466
  closed_node = rqet.find_nested_tags(self.root, ['LinePatch', 'ClosedPolylines'])
467
467
  if closed_node is not None:
468
468
  closed_array[:] = self.get_bool_array(closed_node)
469
+ else:
470
+ closed_array = None
469
471
  if coordinates is None:
470
472
  coordinates = self.coordinates
471
473
  if crs_uuid is None:
472
474
  crs_uuid = self.crs_uuid
473
475
  if rep_int_root is None:
474
476
  rep_int_root = self.rep_int_root
477
+
475
478
  polys = []
476
479
  count = 0
477
480
  for i in range(len(count_perpol)):
478
481
  if i != len(count_perpol) - 1:
479
482
  subset = coordinates[count:int(count_perpol[i]) + count].copy()
480
483
  else:
481
- subset = coordinates[count:int(count_perpol[i]) + count + 1].copy()
482
- if vu.isclose(subset[0], subset[-1]):
483
- isclosed = True
484
+ subset = coordinates[count:int(count_perpol[i]) + count + 1].copy() # is this correct?
485
+ duplicated_end_points = np.all(np.isclose(subset[0], subset[-1])) and len(subset) > 2
486
+ if closed_array is None:
487
+ isclosed = duplicated_end_points
484
488
  else:
485
489
  isclosed = closed_array[i]
490
+ if isclosed and duplicated_end_points:
491
+ subset = subset[:-1]
486
492
  count += int(count_perpol[i])
487
493
  subtitle = f"{self.title} {i+1}"
488
494
  polys.append(
@@ -1,7 +1,7 @@
1
1
  """BlockedWell class."""
2
2
 
3
3
  # Nexus is a registered trademark of the Halliburton Company
4
- # RMS and ROXAR are registered trademarks of Roxar Software Solutions AS, an Emerson company
4
+ # RMS and ROXAR are registered trademarks of Roxar Software Solutions AS, an AspenTech company
5
5
 
6
6
  import logging
7
7
 
@@ -301,7 +301,20 @@ class BlockedWell(BaseResqpy):
301
301
  gi_node = rqet.find_tag(node, 'GridIndices')
302
302
  assert gi_node is not None, 'blocked well grid indices hdf5 reference not found in xml'
303
303
  rqwu.load_hdf5_array(self, gi_node, 'grid_indices', dtype = 'int')
304
- assert self.grid_indices is not None and self.grid_indices.ndim == 1 and self.grid_indices.size == self.node_count - 1
304
+ # assert self.grid_indices is not None and self.grid_indices.ndim == 1 and self.grid_indices.size == self.node_count - 1
305
+ # temporary code to handle blocked wells with incorrectly shaped grid indices wrt. nodes
306
+ assert self.grid_indices is not None and self.grid_indices.ndim == 1
307
+ if self.grid_indices.size != self.node_count - 1:
308
+ if self.grid_indices.size == self.cell_count and self.node_count == 2 * self.cell_count:
309
+ log.warning(f'handling node duplication or missing unblocked intervals in blocked well: {self.title}')
310
+
311
+ expanded_grid_indices = np.full(self.node_count - 1, -1, dtype = int)
312
+ expanded_grid_indices[::2] = self.grid_indices
313
+ self.grid_indices = expanded_grid_indices
314
+ else:
315
+ raise ValueError(
316
+ f'incorrect grid indices size with respect to node count in blocked well: {self.title}')
317
+ # end of temporary code
305
318
  unique_grid_indices = np.unique(self.grid_indices) # sorted list of unique values
306
319
  self.gridind_null = rqet.find_tag_int(gi_node, 'NullValue')
307
320
  if self.gridind_null is None:
@@ -1477,6 +1490,10 @@ class BlockedWell(BaseResqpy):
1477
1490
 
1478
1491
  grid_crs_list = self.__verify_number_of_grids_and_crs_units(column_list = column_list)
1479
1492
 
1493
+ if doing_kh or doing_xyz or doing_angles or doing_entry_exit:
1494
+ for grid in self.grid_list:
1495
+ grid.cache_all_geometry_arrays()
1496
+
1480
1497
  k_face_check = np.zeros((2, 2), dtype = int)
1481
1498
  k_face_check[1, 1] = 1 # now represents entry, exit of K-, K+
1482
1499
  k_face_check_end = k_face_check.copy()
@@ -3057,7 +3074,7 @@ class BlockedWell(BaseResqpy):
3057
3074
  if BlockedWell.__is_float_column(col_name):
3058
3075
  form = '{0:>' + str(width) + '.3f}'
3059
3076
  value = row[col_name]
3060
- if col_name == 'ANGLA' and (np.isnan(value) or value is None):
3077
+ if col_name == 'ANGLA' and (pd.isna(row[col_name]) or value is None or np.isnan(value)):
3061
3078
  value = 0.0
3062
3079
  fp.write(sep + form.format(float(value)))
3063
3080
  else:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: resqpy
3
- Version: 4.12.0
3
+ Version: 4.12.2
4
4
  Summary: Python API for working with RESQML models
5
5
  Home-page: https://github.com/bp/resqpy
6
6
  License: MIT
@@ -1,4 +1,4 @@
1
- resqpy/__init__.py,sha256=1MDzdn-7rfKUVPLI5UOSislrzOVhrQruH2pbqqjTOI0,556
1
+ resqpy/__init__.py,sha256=Xqeo9oQvKlNFxrm0jMMGSId0y_cuNRneZohRcEQBgpM,556
2
2
  resqpy/crs.py,sha256=iq0lO3aXzttmJBfuhUjS9IHlv8OV1wuByhFk0b4fvmI,24782
3
3
  resqpy/derived_model/__init__.py,sha256=NFvMSOKI3cxmH7lAbddV43JjoUj-r2G7ExEfOqinD1I,1982
4
4
  resqpy/derived_model/_add_edges_per_column_property_array.py,sha256=cpW3gwp6MSYIrtvFmCjoJXcyUsgGuCDbgmwlJCJebUs,6410
@@ -55,8 +55,8 @@ resqpy/grid_surface/_trajectory_intersects.py,sha256=Och9cZYU9Y7ofovhPzsLyIblRUl
55
55
  resqpy/grid_surface/grid_surface_cuda.py,sha256=rsTBYfB3YQefDWikTf8nwOwpGF4L4pAMPpma99P5nOk,39760
56
56
  resqpy/lines/__init__.py,sha256=zE7j-BeqkOowj_tsZWd2X_fT-RpbuIh17zfEyj2N0oY,539
57
57
  resqpy/lines/_common.py,sha256=nlgVgZ8utHXuHDyzuP0IpkUJViDNmmy7EBqwLzxSI2M,11960
58
- resqpy/lines/_polyline.py,sha256=nK7DS_f1N6HCR_OH-SC8tSr3GML9MTtdZell25ecLag,42464
59
- resqpy/lines/_polyline_set.py,sha256=KegnMeL3nT914f0SIVWOQA1p1A8zhcpx3TgzSOAna0I,27721
58
+ resqpy/lines/_polyline.py,sha256=OjxSKi9vPqFI4GjVkkA9ZDYewu-gu59bF4NNqJ0hUVo,42454
59
+ resqpy/lines/_polyline_set.py,sha256=3K3z_G9l_3mfjLdCL-YVscyj1FA6DHh1uj9rXPtWFOY,27986
60
60
  resqpy/model/__init__.py,sha256=hbxO-IpCOH_82TZqj6e1FjrWxO0tZu2gj2HCN9x-Svw,378
61
61
  resqpy/model/_catalogue.py,sha256=ZSzLaZWBLgrna6DPPfEQK72hmuRieLrWr5jhj51YIsI,30205
62
62
  resqpy/model/_context.py,sha256=0tLBVMcuuIj3i87Ig8lhFMLHE5GHgEA2PEl1NjKaohc,2840
@@ -182,7 +182,7 @@ resqpy/weights_and_measures/__init__.py,sha256=Kp1pPZFH4rS5_PkCERZBEzGoat6n_dSS0
182
182
  resqpy/weights_and_measures/nexus_units.py,sha256=y78sk6zb43LnwzGWQFV3g_Bwg5seUbgE1YROSOgu6UU,5434
183
183
  resqpy/weights_and_measures/weights_and_measures.py,sha256=i3Fv7hZczQmvTtPwzWvQb-XAxCG6Uta_vd4DV7XDwOU,16186
184
184
  resqpy/well/__init__.py,sha256=v5_gd7sSPRM9q2KsLiLWaw3jbnXFZkou38qeB7_HSN4,990
185
- resqpy/well/_blocked_well.py,sha256=8tMhqN53VSoLnf3J7-Xc_wa61yD6tFgvlluW1nWsaPU,189767
185
+ resqpy/well/_blocked_well.py,sha256=VKhgGNN-70CjgFUxa0FX5TyiIbBx0D57K3qqvasfyFU,190811
186
186
  resqpy/well/_deviation_survey.py,sha256=d3u31JbBqMCsaz6MUrtZium90wrC3omtm46A755fvgk,23115
187
187
  resqpy/well/_md_datum.py,sha256=rRrDQckTJwZtIEh28dlgXj32kcBSu-ZvHFYZOiQsyqg,7154
188
188
  resqpy/well/_trajectory.py,sha256=9sCGXZedICZK_O7qL-BTxUWGRClIVSRBRvP9RFNYk9g,50005
@@ -192,7 +192,7 @@ resqpy/well/_wellbore_marker_frame.py,sha256=xvYH2_2Ie3a18LReFymbUrZboOx7Rhv5DOD
192
192
  resqpy/well/blocked_well_frame.py,sha256=Lg7TgynfPv9WkklXTLt9VN6uBXWUqX1LI-Xmv_FBqYk,22555
193
193
  resqpy/well/well_object_funcs.py,sha256=LYTcC07ezlBxClfrug_B4iXXZUkXDPgsVufNzp361Wo,24703
194
194
  resqpy/well/well_utils.py,sha256=zwpYjT85nXAwWBhYB1Pygu2SgouZ-44k6hEOnpoMfBI,5969
195
- resqpy-4.12.0.dist-info/LICENSE,sha256=2duHPIkKQyESMdQ4hKjL8CYEsYRHXaYxt0YQkzsUYE4,1059
196
- resqpy-4.12.0.dist-info/METADATA,sha256=94Eo778gtrJbeqWo8aFT9RYqcQc5789qFsXYctxaEYc,4028
197
- resqpy-4.12.0.dist-info/WHEEL,sha256=d2fvjOD7sXsVzChCqf0Ty0JbHKBaLYwDbGQDwQTnJ50,88
198
- resqpy-4.12.0.dist-info/RECORD,,
195
+ resqpy-4.12.2.dist-info/LICENSE,sha256=2duHPIkKQyESMdQ4hKjL8CYEsYRHXaYxt0YQkzsUYE4,1059
196
+ resqpy-4.12.2.dist-info/METADATA,sha256=eHS5J4k7O7PR2HPIddfVXs1Gn_Jlg0jFo8AEz5iWgWM,4028
197
+ resqpy-4.12.2.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
198
+ resqpy-4.12.2.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 1.7.0
2
+ Generator: poetry-core 1.8.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any