resqpy 4.18.11__py3-none-any.whl → 5.1.0__py3-none-any.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.
- resqpy/__init__.py +1 -1
 - resqpy/grid/__init__.py +2 -3
 - resqpy/grid/_grid.py +1 -7
 - resqpy/grid_surface/_find_faces.py +98 -29
 - resqpy/lines/_polyline.py +24 -33
 - resqpy/model/_model.py +9 -9
 - resqpy/multi_processing/wrappers/grid_surface_mp.py +91 -44
 - resqpy/olio/triangulation.py +19 -17
 - resqpy/olio/volume.py +0 -20
 - resqpy/property/__init__.py +3 -2
 - resqpy/property/_collection_get_attributes.py +2 -0
 - resqpy/rq_import/_grid_from_cp.py +2 -2
 - resqpy/surface/_surface.py +377 -53
 - resqpy/surface/_tri_mesh.py +3 -1
 - resqpy/time_series/_any_time_series.py +5 -4
 - resqpy/well/_blocked_well.py +1916 -1910
 - resqpy/well/_md_datum.py +11 -21
 - resqpy/well/_wellbore_frame.py +10 -2
 - resqpy/well/well_utils.py +33 -0
 - {resqpy-4.18.11.dist-info → resqpy-5.1.0.dist-info}/METADATA +8 -8
 - {resqpy-4.18.11.dist-info → resqpy-5.1.0.dist-info}/RECORD +23 -24
 - {resqpy-4.18.11.dist-info → resqpy-5.1.0.dist-info}/WHEEL +1 -1
 - resqpy/grid/_moved_functions.py +0 -15
 - {resqpy-4.18.11.dist-info → resqpy-5.1.0.dist-info}/LICENSE +0 -0
 
    
        resqpy/__init__.py
    CHANGED
    
    
    
        resqpy/grid/__init__.py
    CHANGED
    
    | 
         @@ -1,14 +1,13 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            """The Grid Module."""
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            __all__ = [
         
     | 
| 
       4 
     | 
    
         
            -
                'Grid', 'RegularGrid', 'extract_grid_parent', ' 
     | 
| 
       5 
     | 
    
         
            -
                ' 
     | 
| 
      
 4 
     | 
    
         
            +
                'Grid', 'RegularGrid', 'extract_grid_parent', 'find_cell_for_x_sect_xz', 'grid_flavour', 'is_regular_grid',
         
     | 
| 
      
 5 
     | 
    
         
            +
                'any_grid'
         
     | 
| 
       6 
6 
     | 
    
         
             
            ]
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
       8 
8 
     | 
    
         
             
            from ._grid import Grid
         
     | 
| 
       9 
9 
     | 
    
         
             
            from ._regular_grid import RegularGrid
         
     | 
| 
       10 
10 
     | 
    
         
             
            from ._grid_types import grid_flavour, is_regular_grid, any_grid
         
     | 
| 
       11 
     | 
    
         
            -
            from ._moved_functions import establish_zone_property_kind
         
     | 
| 
       12 
11 
     | 
    
         
             
            from ._extract_functions import extract_grid_parent, extent_kji_from_root
         
     | 
| 
       13 
12 
     | 
    
         
             
            from ._points_functions import find_cell_for_x_sect_xz
         
     | 
| 
       14 
13 
     | 
    
         | 
    
        resqpy/grid/_grid.py
    CHANGED
    
    | 
         @@ -680,13 +680,7 @@ class Grid(BaseResqpy): 
     | 
|
| 
       680 
680 
     | 
    
         
             
                    return _create_grid_xml(self, ijk, ext_uuid, add_as_part, add_relationships, write_active, write_geometry,
         
     | 
| 
       681 
681 
     | 
    
         
             
                                            use_lattice, use_parametric_lines)
         
     | 
| 
       682 
682 
     | 
    
         | 
| 
       683 
     | 
    
         
            -
                 
     | 
| 
       684 
     | 
    
         
            -
                    """Deprecated: please use `unsplit_x_section_points` instead."""
         
     | 
| 
       685 
     | 
    
         
            -
                    warnings.warn('Deprecated: please use `unsplit_x_section_points` instead.', DeprecationWarning)
         
     | 
| 
       686 
     | 
    
         
            -
             
     | 
| 
       687 
     | 
    
         
            -
                    return unsplit_x_section_points(self, axis, ref_slice0 = ref_slice0, plus_face = plus_face, masked = masked)
         
     | 
| 
       688 
     | 
    
         
            -
             
     | 
| 
       689 
     | 
    
         
            -
                # The implementations of the below functions have been moved to separate modules.
         
     | 
| 
      
 683 
     | 
    
         
            +
                # the implementations of the functions below have been moved to separate modules
         
     | 
| 
       690 
684 
     | 
    
         | 
| 
       691 
685 
     | 
    
         
             
                def cell_geometry_is_defined(self, cell_kji0 = None, cell_geometry_is_defined_root = None, cache_array = True):
         
     | 
| 
       692 
686 
     | 
    
         
             
                    """Returns True if the geometry of the specified cell is defined.
         
     | 
| 
         @@ -558,6 +558,8 @@ def find_faces_to_represent_surface_regular_dense_optimised(grid, 
     | 
|
| 
       558 
558 
     | 
    
         
             
                    to a grid connection set; use the non-dense version of the function for a reduced memory footprint;
         
     | 
| 
       559 
559 
     | 
    
         
             
                    this function is DEPRECATED pending proving of newer find_faces_to_represent_surface_regular_optimised()
         
     | 
| 
       560 
560 
     | 
    
         
             
                """
         
     | 
| 
      
 561 
     | 
    
         
            +
                warnings.warn('DEPRECATED: grid_surface.find_faces_to_represent_surface_regular_dense_optimised() function; ' +
         
     | 
| 
      
 562 
     | 
    
         
            +
                              'use find_faces_to_represent_surface_regular_optimised() instead')
         
     | 
| 
       561 
563 
     | 
    
         | 
| 
       562 
564 
     | 
    
         
             
                assert isinstance(grid, grr.RegularGrid)
         
     | 
| 
       563 
565 
     | 
    
         
             
                assert grid.is_aligned
         
     | 
| 
         @@ -878,7 +880,8 @@ def find_faces_to_represent_surface_regular_optimised(grid, 
     | 
|
| 
       878 
880 
     | 
    
         
             
                                                                  return_properties = None,
         
     | 
| 
       879 
881 
     | 
    
         
             
                                                                  raw_bisector = False,
         
     | 
| 
       880 
882 
     | 
    
         
             
                                                                  n_batches = 20,
         
     | 
| 
       881 
     | 
    
         
            -
                                                                  packed_bisectors = False 
     | 
| 
      
 883 
     | 
    
         
            +
                                                                  packed_bisectors = False,
         
     | 
| 
      
 884 
     | 
    
         
            +
                                                                  patch_indices = None):
         
     | 
| 
       882 
885 
     | 
    
         
             
                """Returns a grid connection set containing those cell faces which are deemed to represent the surface.
         
     | 
| 
       883 
886 
     | 
    
         | 
| 
       884 
887 
     | 
    
         
             
                argumants:
         
     | 
| 
         @@ -914,11 +917,14 @@ def find_faces_to_represent_surface_regular_optimised(grid, 
     | 
|
| 
       914 
917 
     | 
    
         
             
                       threading allows some parallelism between the batches)
         
     | 
| 
       915 
918 
     | 
    
         
             
                    packed_bisectors (bool, default False): if True and return properties include 'grid bisector' then
         
     | 
| 
       916 
919 
     | 
    
         
             
                       non curtain bisectors are returned in packed form
         
     | 
| 
      
 920 
     | 
    
         
            +
                    patch_indices (numpy int array, optional): if present, an array over grid cells indicating which 
         
     | 
| 
      
 921 
     | 
    
         
            +
                       patch of surface is applicable in terms of a bisector, for each cell
         
     | 
| 
       917 
922 
     | 
    
         | 
| 
       918 
923 
     | 
    
         
             
                returns:
         
     | 
| 
       919 
924 
     | 
    
         
             
                    gcs  or  (gcs, gcs_props)
         
     | 
| 
       920 
925 
     | 
    
         
             
                    where gcs is a new GridConnectionSet with a single feature, not yet written to hdf5 nor xml created;
         
     | 
| 
       921 
     | 
    
         
            -
                    gcs_props is a dictionary mapping from requested return_properties string to numpy array
         
     | 
| 
      
 926 
     | 
    
         
            +
                    gcs_props is a dictionary mapping from requested return_properties string to numpy array (or tuple
         
     | 
| 
      
 927 
     | 
    
         
            +
                        of numpy array and curtain bool in the case of grid bisector)
         
     | 
| 
       922 
928 
     | 
    
         | 
| 
       923 
929 
     | 
    
         
             
                notes:
         
     | 
| 
       924 
930 
     | 
    
         
             
                    this function is designed for aligned regular grids only;
         
     | 
| 
         @@ -927,7 +933,9 @@ def find_faces_to_represent_surface_regular_optimised(grid, 
     | 
|
| 
       927 
933 
     | 
    
         
             
                    no trimming of the surface is carried out here: for computational efficiency, it is recommended
         
     | 
| 
       928 
934 
     | 
    
         
             
                    to trim first;
         
     | 
| 
       929 
935 
     | 
    
         
             
                    organisational objects for the feature are created if needed;
         
     | 
| 
       930 
     | 
    
         
            -
                    if the offset return property is requested, the implicit units will be the z units of the grid's crs
         
     | 
| 
      
 936 
     | 
    
         
            +
                    if the offset return property is requested, the implicit units will be the z units of the grid's crs;
         
     | 
| 
      
 937 
     | 
    
         
            +
                    if patch_indices is present and grid bisectors are being returned, a composite bisector array is returned
         
     | 
| 
      
 938 
     | 
    
         
            +
                    with elements set from individual bisectors for each patch of surface
         
     | 
| 
       931 
939 
     | 
    
         
             
                """
         
     | 
| 
       932 
940 
     | 
    
         | 
| 
       933 
941 
     | 
    
         
             
                assert isinstance(grid, grr.RegularGrid)
         
     | 
| 
         @@ -957,7 +965,10 @@ def find_faces_to_represent_surface_regular_optimised(grid, 
     | 
|
| 
       957 
965 
     | 
    
         
             
                    return_flange_bool = "flange bool" in return_properties
         
     | 
| 
       958 
966 
     | 
    
         
             
                    if return_flange_bool:
         
     | 
| 
       959 
967 
     | 
    
         
             
                        return_triangles = True
         
     | 
| 
       960 
     | 
    
         
            -
             
     | 
| 
      
 968 
     | 
    
         
            +
                patchwork = return_bisector and patch_indices is not None
         
     | 
| 
      
 969 
     | 
    
         
            +
                if patchwork:
         
     | 
| 
      
 970 
     | 
    
         
            +
                    return_triangles = True  # triangle numbers are used to infer patch index
         
     | 
| 
      
 971 
     | 
    
         
            +
                    assert patch_indices.shape == tuple(grid.extent_kji)
         
     | 
| 
       961 
972 
     | 
    
         
             
                if title is None:
         
     | 
| 
       962 
973 
     | 
    
         
             
                    title = name
         
     | 
| 
       963 
974 
     | 
    
         | 
| 
         @@ -1163,7 +1174,7 @@ def find_faces_to_represent_surface_regular_optimised(grid, 
     | 
|
| 
       1163 
1174 
     | 
    
         
             
                                                               k_faces_kji0 = k_faces_kji0,
         
     | 
| 
       1164 
1175 
     | 
    
         
             
                                                               j_faces_kji0 = j_faces_kji0,
         
     | 
| 
       1165 
1176 
     | 
    
         
             
                                                               i_faces_kji0 = i_faces_kji0,
         
     | 
| 
       1166 
     | 
    
         
            -
                                                               remove_duplicates =  
     | 
| 
      
 1177 
     | 
    
         
            +
                                                               remove_duplicates = not patchwork,
         
     | 
| 
       1167 
1178 
     | 
    
         
             
                                                               k_properties = k_props,
         
     | 
| 
       1168 
1179 
     | 
    
         
             
                                                               j_properties = j_props,
         
     | 
| 
       1169 
1180 
     | 
    
         
             
                                                               i_properties = i_props,
         
     | 
| 
         @@ -1174,6 +1185,7 @@ def find_faces_to_represent_surface_regular_optimised(grid, 
     | 
|
| 
       1174 
1185 
     | 
    
         
             
                # log.debug('finished coversion to gcs')
         
     | 
| 
       1175 
1186 
     | 
    
         | 
| 
       1176 
1187 
     | 
    
         
             
                # NB. following assumes faces have been added to gcs in a particular order!
         
     | 
| 
      
 1188 
     | 
    
         
            +
                all_tris = None
         
     | 
| 
       1177 
1189 
     | 
    
         
             
                if return_triangles:
         
     | 
| 
       1178 
1190 
     | 
    
         
             
                    # log.debug('preparing triangles array')
         
     | 
| 
       1179 
1191 
     | 
    
         
             
                    k_triangles = np.empty((0,), dtype = np.int32) if k_props is None else k_props.pop(0)
         
     | 
| 
         @@ -1184,6 +1196,7 @@ def find_faces_to_represent_surface_regular_optimised(grid, 
     | 
|
| 
       1184 
1196 
     | 
    
         
             
                    assert all_tris.shape == (gcs.count,)
         
     | 
| 
       1185 
1197 
     | 
    
         | 
| 
       1186 
1198 
     | 
    
         
             
                # NB. following assumes faces have been added to gcs in a particular order!
         
     | 
| 
      
 1199 
     | 
    
         
            +
                all_depths = None
         
     | 
| 
       1187 
1200 
     | 
    
         
             
                if return_depths:
         
     | 
| 
       1188 
1201 
     | 
    
         
             
                    # log.debug('preparing depths array')
         
     | 
| 
       1189 
1202 
     | 
    
         
             
                    k_depths = np.empty((0,), dtype = np.float64) if k_props is None else k_props.pop(0)
         
     | 
| 
         @@ -1194,6 +1207,7 @@ def find_faces_to_represent_surface_regular_optimised(grid, 
     | 
|
| 
       1194 
1207 
     | 
    
         
             
                    assert all_depths.shape == (gcs.count,)
         
     | 
| 
       1195 
1208 
     | 
    
         | 
| 
       1196 
1209 
     | 
    
         
             
                # NB. following assumes faces have been added to gcs in a particular order!
         
     | 
| 
      
 1210 
     | 
    
         
            +
                all_offsets = None
         
     | 
| 
       1197 
1211 
     | 
    
         
             
                if return_offsets:
         
     | 
| 
       1198 
1212 
     | 
    
         
             
                    # log.debug('preparing offsets array')
         
     | 
| 
       1199 
1213 
     | 
    
         
             
                    k_offsets = np.empty((0,), dtype = np.float64) if k_props is None else k_props[0]
         
     | 
| 
         @@ -1203,6 +1217,7 @@ def find_faces_to_represent_surface_regular_optimised(grid, 
     | 
|
| 
       1203 
1217 
     | 
    
         
             
                    # log.debug(f'gcs count: {gcs.count}; all offsets shape: {all_offsets.shape}')
         
     | 
| 
       1204 
1218 
     | 
    
         
             
                    assert all_offsets.shape == (gcs.count,)
         
     | 
| 
       1205 
1219 
     | 
    
         | 
| 
      
 1220 
     | 
    
         
            +
                all_flange = None
         
     | 
| 
       1206 
1221 
     | 
    
         
             
                if return_flange_bool:
         
     | 
| 
       1207 
1222 
     | 
    
         
             
                    # log.debug('preparing flange array')
         
     | 
| 
       1208 
1223 
     | 
    
         
             
                    flange_bool_uuid = surface.model.uuid(title = "flange bool",
         
     | 
| 
         @@ -1215,8 +1230,9 @@ def find_faces_to_represent_surface_regular_optimised(grid, 
     | 
|
| 
       1215 
1230 
     | 
    
         
             
                    assert all_flange.shape == (gcs.count,)
         
     | 
| 
       1216 
1231 
     | 
    
         | 
| 
       1217 
1232 
     | 
    
         
             
                # note: following is a grid cells property, not a gcs property
         
     | 
| 
      
 1233 
     | 
    
         
            +
                bisector = None
         
     | 
| 
       1218 
1234 
     | 
    
         
             
                if return_bisector:
         
     | 
| 
       1219 
     | 
    
         
            -
                    if is_curtain:
         
     | 
| 
      
 1235 
     | 
    
         
            +
                    if is_curtain and not patchwork:
         
     | 
| 
       1220 
1236 
     | 
    
         
             
                        log.debug("preparing columns bisector")
         
     | 
| 
       1221 
1237 
     | 
    
         
             
                        if j_faces_kji0 is None:
         
     | 
| 
       1222 
1238 
     | 
    
         
             
                            j_faces_ji0 = np.empty((0, 2), dtype = np.int32)
         
     | 
| 
         @@ -1228,8 +1244,51 @@ def find_faces_to_represent_surface_regular_optimised(grid, 
     | 
|
| 
       1228 
1244 
     | 
    
         
             
                            i_faces_ji0 = i_faces_kji0[:, 1:]
         
     | 
| 
       1229 
1245 
     | 
    
         
             
                        bisector = column_bisector_from_face_indices((grid.nj, grid.ni), j_faces_ji0, i_faces_ji0)
         
     | 
| 
       1230 
1246 
     | 
    
         
             
                        # log.debug('finished preparing columns bisector')
         
     | 
| 
      
 1247 
     | 
    
         
            +
                    elif patchwork:
         
     | 
| 
      
 1248 
     | 
    
         
            +
                        n_patches = surface.number_of_patches()
         
     | 
| 
      
 1249 
     | 
    
         
            +
                        nkf = len(k_faces_kji0)
         
     | 
| 
      
 1250 
     | 
    
         
            +
                        njf = len(j_faces_kji0)
         
     | 
| 
      
 1251 
     | 
    
         
            +
                        nif = len(i_faces_kji0)
         
     | 
| 
      
 1252 
     | 
    
         
            +
                        # fetch patch indices for triangle hits
         
     | 
| 
      
 1253 
     | 
    
         
            +
                        assert all_tris is not None and len(all_tris) == nkf + njf + nif
         
     | 
| 
      
 1254 
     | 
    
         
            +
                        patch_indices_k = surface.patch_indices_for_triangle_indices(all_tris[:nkf])
         
     | 
| 
      
 1255 
     | 
    
         
            +
                        patch_indices_j = surface.patch_indices_for_triangle_indices(all_tris[nkf:nkf + njf])
         
     | 
| 
      
 1256 
     | 
    
         
            +
                        patch_indices_i = surface.patch_indices_for_triangle_indices(all_tris[nkf + njf:])
         
     | 
| 
      
 1257 
     | 
    
         
            +
                        # add extra dimension to bisector array (at axis 0) for patches
         
     | 
| 
      
 1258 
     | 
    
         
            +
                        pb_shape = tuple([n_patches] + list(grid.extent_kji))
         
     | 
| 
      
 1259 
     | 
    
         
            +
                        if packed_bisectors:
         
     | 
| 
      
 1260 
     | 
    
         
            +
                            bisector = np.ones(_shape_packed(grid.extent_kji), dtype = np.uint8)
         
     | 
| 
      
 1261 
     | 
    
         
            +
                        else:
         
     | 
| 
      
 1262 
     | 
    
         
            +
                            bisector = np.ones(tuple(grid.extent_kji), dtype = np.bool_)
         
     | 
| 
      
 1263 
     | 
    
         
            +
                        # populate 4D bisector with an axis zero slice for each patch
         
     | 
| 
      
 1264 
     | 
    
         
            +
                        for patch in range(n_patches):
         
     | 
| 
      
 1265 
     | 
    
         
            +
                            mask = (patch_indices == patch)
         
     | 
| 
      
 1266 
     | 
    
         
            +
                            if np.count_nonzero(mask) == 0:
         
     | 
| 
      
 1267 
     | 
    
         
            +
                                log.warning(f'patch {patch} of surface {surface.title} is not applicable to any cells in grid')
         
     | 
| 
      
 1268 
     | 
    
         
            +
                                continue
         
     | 
| 
      
 1269 
     | 
    
         
            +
                            if packed_bisectors:
         
     | 
| 
      
 1270 
     | 
    
         
            +
                                mask = np.packbits(mask, axis = -1)
         
     | 
| 
      
 1271 
     | 
    
         
            +
                                patch_bisector, is_curtain =  \
         
     | 
| 
      
 1272 
     | 
    
         
            +
                                    packed_bisector_from_face_indices(tuple(grid.extent_kji),
         
     | 
| 
      
 1273 
     | 
    
         
            +
                                                                      k_faces_kji0[(patch_indices_k == patch).astype(bool)],
         
     | 
| 
      
 1274 
     | 
    
         
            +
                                                                      j_faces_kji0[(patch_indices_j == patch).astype(bool)],
         
     | 
| 
      
 1275 
     | 
    
         
            +
                                                                      i_faces_kji0[(patch_indices_i == patch).astype(bool)],
         
     | 
| 
      
 1276 
     | 
    
         
            +
                                                                      raw_bisector)
         
     | 
| 
      
 1277 
     | 
    
         
            +
                                bisector = np.bitwise_or(np.bitwise_and(mask, patch_bisector), bisector)
         
     | 
| 
      
 1278 
     | 
    
         
            +
                            else:
         
     | 
| 
      
 1279 
     | 
    
         
            +
                                patch_bisector, is_curtain =  \
         
     | 
| 
      
 1280 
     | 
    
         
            +
                                    bisector_from_face_indices(tuple(grid.extent_kji),
         
     | 
| 
      
 1281 
     | 
    
         
            +
                                                               k_faces_kji0[(patch_indices_k == patch).astype(bool)],
         
     | 
| 
      
 1282 
     | 
    
         
            +
                                                               j_faces_kji0[(patch_indices_j == patch).astype(bool)],
         
     | 
| 
      
 1283 
     | 
    
         
            +
                                                               i_faces_kji0[(patch_indices_i == patch).astype(bool)],
         
     | 
| 
      
 1284 
     | 
    
         
            +
                                                               raw_bisector)
         
     | 
| 
      
 1285 
     | 
    
         
            +
                                bisector[mask] = patch_bisector[mask]
         
     | 
| 
      
 1286 
     | 
    
         
            +
                            if is_curtain:
         
     | 
| 
      
 1287 
     | 
    
         
            +
                                # TODO: downgrade following to debug once downstream functionality tested
         
     | 
| 
      
 1288 
     | 
    
         
            +
                                log.warning(f'ignoring curtain nature of bisector for patch {patch} of surface: {surface.title}')
         
     | 
| 
      
 1289 
     | 
    
         
            +
                                is_curtain = False
         
     | 
| 
       1231 
1290 
     | 
    
         
             
                    else:
         
     | 
| 
       1232 
     | 
    
         
            -
                        log.debug("preparing cells bisector")
         
     | 
| 
      
 1291 
     | 
    
         
            +
                        log.debug("preparing singlular cells bisector")
         
     | 
| 
       1233 
1292 
     | 
    
         
             
                        if ((k_faces_kji0 is None or len(k_faces_kji0) == 0) and
         
     | 
| 
       1234 
1293 
     | 
    
         
             
                            (j_faces_kji0 is None or len(j_faces_kji0) == 0) and (i_faces_kji0 is None or len(i_faces_kji0) == 0)):
         
     | 
| 
       1235 
1294 
     | 
    
         
             
                            bisector = np.ones((grid.nj, grid.ni), dtype = bool)
         
     | 
| 
         @@ -1247,6 +1306,7 @@ def find_faces_to_represent_surface_regular_optimised(grid, 
     | 
|
| 
       1247 
1306 
     | 
    
         
             
                                bisector = bisector[0]  # reduce to a columns property
         
     | 
| 
       1248 
1307 
     | 
    
         | 
| 
       1249 
1308 
     | 
    
         
             
                # note: following is a grid cells property, not a gcs property
         
     | 
| 
      
 1309 
     | 
    
         
            +
                shadow = None
         
     | 
| 
       1250 
1310 
     | 
    
         
             
                if return_shadow:
         
     | 
| 
       1251 
1311 
     | 
    
         
             
                    log.debug("preparing cells shadow")
         
     | 
| 
       1252 
1312 
     | 
    
         
             
                    shadow = shadow_from_face_indices(tuple(grid.extent_kji), k_faces_kji0)
         
     | 
| 
         @@ -1259,7 +1319,7 @@ def find_faces_to_represent_surface_regular_optimised(grid, 
     | 
|
| 
       1259 
1319 
     | 
    
         
             
                # if returning properties, construct dictionary
         
     | 
| 
       1260 
1320 
     | 
    
         
             
                if return_properties:
         
     | 
| 
       1261 
1321 
     | 
    
         
             
                    props_dict = {}
         
     | 
| 
       1262 
     | 
    
         
            -
                    if  
     | 
| 
      
 1322 
     | 
    
         
            +
                    if 'triangle' in return_properties:
         
     | 
| 
       1263 
1323 
     | 
    
         
             
                        props_dict["triangle"] = all_tris
         
     | 
| 
       1264 
1324 
     | 
    
         
             
                    if return_depths:
         
     | 
| 
       1265 
1325 
     | 
    
         
             
                        props_dict["depth"] = all_depths
         
     | 
| 
         @@ -1361,8 +1421,9 @@ def bisector_from_faces(  # type: ignore 
     | 
|
| 
       1361 
1421 
     | 
    
         
             
                    - the face sets must form a single 'sealed' cut of the grid (eg. not waving in and out of the grid)
         
     | 
| 
       1362 
1422 
     | 
    
         
             
                    - any 'boxed in' parts of the grid (completely enclosed by bisecting faces) will be consistently
         
     | 
| 
       1363 
1423 
     | 
    
         
             
                      assigned to either the True or False part
         
     | 
| 
       1364 
     | 
    
         
            -
                    - this function is DEPRECATED,  
     | 
| 
      
 1424 
     | 
    
         
            +
                    - this function is DEPRECATED, use newer indices based approach instead: bisector_from_face_indices()
         
     | 
| 
       1365 
1425 
     | 
    
         
             
                """
         
     | 
| 
      
 1426 
     | 
    
         
            +
                warnings.warn('DEPRECATED: grid_surface.bisector_from_faces() function; use bisector_from_face_indices() instead')
         
     | 
| 
       1366 
1427 
     | 
    
         
             
                assert len(grid_extent_kji) == 3
         
     | 
| 
       1367 
1428 
     | 
    
         | 
| 
       1368 
1429 
     | 
    
         
             
                # find the surface boundary (includes a buffer slice where surface does not reach edge of grid)
         
     | 
| 
         @@ -1405,10 +1466,13 @@ def bisector_from_faces(  # type: ignore 
     | 
|
| 
       1405 
1466 
     | 
    
         
             
                # check all array elements are not the same
         
     | 
| 
       1406 
1467 
     | 
    
         
             
                true_count = np.count_nonzero(array)
         
     | 
| 
       1407 
1468 
     | 
    
         
             
                cell_count = array.size
         
     | 
| 
       1408 
     | 
    
         
            -
                 
     | 
| 
       1409 
     | 
    
         
            -
             
     | 
| 
       1410 
     | 
    
         
            -
             
     | 
| 
       1411 
     | 
    
         
            -
                 
     | 
| 
      
 1469 
     | 
    
         
            +
                if 0 < true_count < cell_count:
         
     | 
| 
      
 1470 
     | 
    
         
            +
                    # negate the array if it minimises the mean k and determine if the surface is a curtain
         
     | 
| 
      
 1471 
     | 
    
         
            +
                    is_curtain = _shallow_or_curtain(array, true_count, raw_bisector)
         
     | 
| 
      
 1472 
     | 
    
         
            +
                else:
         
     | 
| 
      
 1473 
     | 
    
         
            +
                    assert raw_bisector, 'face set for surface is leaky or empty (surface does not intersect grid)'
         
     | 
| 
      
 1474 
     | 
    
         
            +
                    log.error('face set for surface is leaky or empty (surface does not intersect grid)')
         
     | 
| 
      
 1475 
     | 
    
         
            +
                    is_curtain = False
         
     | 
| 
       1412 
1476 
     | 
    
         | 
| 
       1413 
1477 
     | 
    
         
             
                return array, is_curtain
         
     | 
| 
       1414 
1478 
     | 
    
         | 
| 
         @@ -1479,10 +1543,13 @@ def bisector_from_face_indices(  # type: ignore 
     | 
|
| 
       1479 
1543 
     | 
    
         
             
                # check all array elements are not the same
         
     | 
| 
       1480 
1544 
     | 
    
         
             
                true_count = np.count_nonzero(array)
         
     | 
| 
       1481 
1545 
     | 
    
         
             
                cell_count = array.size
         
     | 
| 
       1482 
     | 
    
         
            -
                 
     | 
| 
       1483 
     | 
    
         
            -
             
     | 
| 
       1484 
     | 
    
         
            -
             
     | 
| 
       1485 
     | 
    
         
            -
                 
     | 
| 
      
 1546 
     | 
    
         
            +
                if 0 < true_count < cell_count:
         
     | 
| 
      
 1547 
     | 
    
         
            +
                    # negate the array if it minimises the mean k and determine if the surface is a curtain
         
     | 
| 
      
 1548 
     | 
    
         
            +
                    is_curtain = _shallow_or_curtain(array, true_count, raw_bisector)
         
     | 
| 
      
 1549 
     | 
    
         
            +
                else:
         
     | 
| 
      
 1550 
     | 
    
         
            +
                    assert raw_bisector, 'face set for surface is leaky or empty (surface does not intersect grid)'
         
     | 
| 
      
 1551 
     | 
    
         
            +
                    log.error('face set for surface is leaky or empty (surface does not intersect grid)')
         
     | 
| 
      
 1552 
     | 
    
         
            +
                    is_curtain = False
         
     | 
| 
       1486 
1553 
     | 
    
         | 
| 
       1487 
1554 
     | 
    
         
             
                return array, is_curtain
         
     | 
| 
       1488 
1555 
     | 
    
         | 
| 
         @@ -1569,12 +1636,14 @@ def packed_bisector_from_face_indices(  # type: ignore 
     | 
|
| 
       1569 
1636 
     | 
    
         
             
                else:
         
     | 
| 
       1570 
1637 
     | 
    
         
             
                    true_count = _bitwise_count_njit(array)  # note: will usually include some padding bits, so not so true!
         
     | 
| 
       1571 
1638 
     | 
    
         
             
                cell_count = np.prod(grid_extent_kji)
         
     | 
| 
       1572 
     | 
    
         
            -
                 
     | 
| 
       1573 
     | 
    
         
            -
             
     | 
| 
       1574 
     | 
    
         
            -
             
     | 
| 
       1575 
     | 
    
         
            -
             
     | 
| 
       1576 
     | 
    
         
            -
                 
     | 
| 
       1577 
     | 
    
         
            -
             
     | 
| 
      
 1639 
     | 
    
         
            +
                if 0 < true_count < cell_count:
         
     | 
| 
      
 1640 
     | 
    
         
            +
                    # negate the array if it minimises the mean k and determine if the surface is a curtain
         
     | 
| 
      
 1641 
     | 
    
         
            +
                    # TODO: switch to _packed_shallow_or_curtain_temp_bitwise_count() when numba supports np.bitwise_count()
         
     | 
| 
      
 1642 
     | 
    
         
            +
                    is_curtain = _packed_shallow_or_curtain_temp_bitwise_count(array, true_count, raw_bisector)
         
     | 
| 
      
 1643 
     | 
    
         
            +
                else:
         
     | 
| 
      
 1644 
     | 
    
         
            +
                    assert raw_bisector, 'face set for surface is leaky or empty (surface does not intersect grid)'
         
     | 
| 
      
 1645 
     | 
    
         
            +
                    log.error('face set for surface is leaky or empty (surface does not intersect grid)')
         
     | 
| 
      
 1646 
     | 
    
         
            +
                    is_curtain = False
         
     | 
| 
       1578 
1647 
     | 
    
         | 
| 
       1579 
1648 
     | 
    
         
             
                return array, is_curtain
         
     | 
| 
       1580 
1649 
     | 
    
         | 
| 
         @@ -2224,12 +2293,12 @@ def get_boundary_from_indices(  # type: ignore 
     | 
|
| 
       2224 
2293 
     | 
    
         
             
                    k_faces_kji0: Union[np.ndarray, None], j_faces_kji0: Union[np.ndarray, None],
         
     | 
| 
       2225 
2294 
     | 
    
         
             
                    i_faces_kji0: Union[np.ndarray, None], grid_extent_kji: Tuple[int, int, int]) -> np.ndarray:
         
     | 
| 
       2226 
2295 
     | 
    
         
             
                """Return python protocol box containing indices"""
         
     | 
| 
       2227 
     | 
    
         
            -
                k_min_kji0 = None if k_faces_kji0 is None else np.min(k_faces_kji0, axis = 0)
         
     | 
| 
       2228 
     | 
    
         
            -
                k_max_kji0 = None if k_faces_kji0 is None else np.max(k_faces_kji0, axis = 0)
         
     | 
| 
       2229 
     | 
    
         
            -
                j_min_kji0 = None if j_faces_kji0 is None else np.min(j_faces_kji0, axis = 0)
         
     | 
| 
       2230 
     | 
    
         
            -
                j_max_kji0 = None if j_faces_kji0 is None else np.max(j_faces_kji0, axis = 0)
         
     | 
| 
       2231 
     | 
    
         
            -
                i_min_kji0 = None if i_faces_kji0 is None else np.min(i_faces_kji0, axis = 0)
         
     | 
| 
       2232 
     | 
    
         
            -
                i_max_kji0 = None if i_faces_kji0 is None else np.max(i_faces_kji0, axis = 0)
         
     | 
| 
      
 2296 
     | 
    
         
            +
                k_min_kji0 = None if (k_faces_kji0 is None or k_faces_kji0.size == 0) else np.min(k_faces_kji0, axis = 0)
         
     | 
| 
      
 2297 
     | 
    
         
            +
                k_max_kji0 = None if (k_faces_kji0 is None or k_faces_kji0.size == 0) else np.max(k_faces_kji0, axis = 0)
         
     | 
| 
      
 2298 
     | 
    
         
            +
                j_min_kji0 = None if (j_faces_kji0 is None or j_faces_kji0.size == 0) else np.min(j_faces_kji0, axis = 0)
         
     | 
| 
      
 2299 
     | 
    
         
            +
                j_max_kji0 = None if (j_faces_kji0 is None or j_faces_kji0.size == 0) else np.max(j_faces_kji0, axis = 0)
         
     | 
| 
      
 2300 
     | 
    
         
            +
                i_min_kji0 = None if (i_faces_kji0 is None or i_faces_kji0.size == 0) else np.min(i_faces_kji0, axis = 0)
         
     | 
| 
      
 2301 
     | 
    
         
            +
                i_max_kji0 = None if (i_faces_kji0 is None or i_faces_kji0.size == 0) else np.max(i_faces_kji0, axis = 0)
         
     | 
| 
       2233 
2302 
     | 
    
         
             
                box = np.empty((2, 3), dtype = np.int32)
         
     | 
| 
       2234 
2303 
     | 
    
         
             
                box[0, :] = grid_extent_kji
         
     | 
| 
       2235 
2304 
     | 
    
         
             
                box[1, :] = -1
         
     | 
    
        resqpy/lines/_polyline.py
    CHANGED
    
    | 
         @@ -25,25 +25,22 @@ class Polyline(rql_c._BasePolyline): 
     | 
|
| 
       25 
25 
     | 
    
         | 
| 
       26 
26 
     | 
    
         
             
                resqml_type = 'PolylineRepresentation'
         
     | 
| 
       27 
27 
     | 
    
         | 
| 
       28 
     | 
    
         
            -
                def __init__(
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
                        originator = None,
         
     | 
| 
       39 
     | 
    
         
            -
                        extra_metadata = None):
         
     | 
| 
      
 28 
     | 
    
         
            +
                def __init__(self,
         
     | 
| 
      
 29 
     | 
    
         
            +
                             parent_model,
         
     | 
| 
      
 30 
     | 
    
         
            +
                             uuid = None,
         
     | 
| 
      
 31 
     | 
    
         
            +
                             set_coord = None,
         
     | 
| 
      
 32 
     | 
    
         
            +
                             set_crs = None,
         
     | 
| 
      
 33 
     | 
    
         
            +
                             is_closed = None,
         
     | 
| 
      
 34 
     | 
    
         
            +
                             title = None,
         
     | 
| 
      
 35 
     | 
    
         
            +
                             rep_int_root = None,
         
     | 
| 
      
 36 
     | 
    
         
            +
                             originator = None,
         
     | 
| 
      
 37 
     | 
    
         
            +
                             extra_metadata = None):
         
     | 
| 
       40 
38 
     | 
    
         
             
                    """Initialises a new polyline object.
         
     | 
| 
       41 
39 
     | 
    
         | 
| 
       42 
40 
     | 
    
         
             
                    arguments:
         
     | 
| 
       43 
41 
     | 
    
         
             
                        parent_model (model.Model object): the model which the new PolylineRepresentation belongs to
         
     | 
| 
       44 
42 
     | 
    
         
             
                        uuid (uuid.UUID, optional): the uuid of an existing RESQML PolylineRepresentation from which
         
     | 
| 
       45 
43 
     | 
    
         
             
                            to initialise the resqpy Polyline
         
     | 
| 
       46 
     | 
    
         
            -
                        set_bool (boolean, optional): DEPRECATED: synonym for is_closed argument
         
     | 
| 
       47 
44 
     | 
    
         
             
                        set_coord (numpy float array, optional): an ordered set of xyz values used to define a new polyline;
         
     | 
| 
       48 
45 
     | 
    
         
             
                            last dimension of array must have extent 3; ignored if uuid is not None
         
     | 
| 
       49 
46 
     | 
    
         
             
                        set_crs (uuid.UUID, optional): the uuid of a crs to be used when initialising from coordinates;
         
     | 
| 
         @@ -65,10 +62,6 @@ class Polyline(rql_c._BasePolyline): 
     | 
|
| 
       65 
62 
     | 
    
         
             
                    """
         
     | 
| 
       66 
63 
     | 
    
         | 
| 
       67 
64 
     | 
    
         
             
                    self.model = parent_model
         
     | 
| 
       68 
     | 
    
         
            -
                    if set_bool is not None:
         
     | 
| 
       69 
     | 
    
         
            -
                        warnings.warn('DEPRECATED: use is_closed argument instead of set_bool, in Polyline initialisation')
         
     | 
| 
       70 
     | 
    
         
            -
                        if is_closed is None:
         
     | 
| 
       71 
     | 
    
         
            -
                            is_closed = set_bool
         
     | 
| 
       72 
65 
     | 
    
         
             
                    self.isclosed = is_closed
         
     | 
| 
       73 
66 
     | 
    
         
             
                    self.nodepatch = None
         
     | 
| 
       74 
67 
     | 
    
         
             
                    self.crs_uuid = set_crs
         
     | 
| 
         @@ -466,22 +459,20 @@ class Polyline(rql_c._BasePolyline): 
     | 
|
| 
       466 
459 
     | 
    
         
             
                    if cache and self.centre is not None:
         
     | 
| 
       467 
460 
     | 
    
         
             
                        return self.centre
         
     | 
| 
       468 
461 
     | 
    
         
             
                    assert mode in ['weighted', 'sampled']
         
     | 
| 
       469 
     | 
    
         
            -
                    if mode  
     | 
| 
       470 
     | 
    
         
            -
                         
     | 
| 
       471 
     | 
    
         
            -
             
     | 
| 
       472 
     | 
    
         
            -
                     
     | 
| 
       473 
     | 
    
         
            -
             
     | 
| 
       474 
     | 
    
         
            -
                        seg_count  
     | 
| 
       475 
     | 
    
         
            -
             
     | 
| 
       476 
     | 
    
         
            -
             
     | 
| 
       477 
     | 
    
         
            -
             
     | 
| 
       478 
     | 
    
         
            -
             
     | 
| 
       479 
     | 
    
         
            -
                         
     | 
| 
       480 
     | 
    
         
            -
                         
     | 
| 
       481 
     | 
    
         
            -
             
     | 
| 
       482 
     | 
    
         
            -
             
     | 
| 
       483 
     | 
    
         
            -
                            sum += (p1 + p2) * vu.naive_length(p2 - p1)
         
     | 
| 
       484 
     | 
    
         
            -
                        centre = sum / (2.0 * self.full_length(in_xy = in_xy))
         
     | 
| 
      
 462 
     | 
    
         
            +
                    if mode != 'weighted':  # ignore any other mode, ie. sampled
         
     | 
| 
      
 463 
     | 
    
         
            +
                        warnings.warn('DEPRECATED: weighted mode is only mode now supported for Polyline.balanced_centre()')
         
     | 
| 
      
 464 
     | 
    
         
            +
                    sum = np.zeros(3)
         
     | 
| 
      
 465 
     | 
    
         
            +
                    seg_count = len(self.coordinates) - 1
         
     | 
| 
      
 466 
     | 
    
         
            +
                    if self.isclosed:
         
     | 
| 
      
 467 
     | 
    
         
            +
                        seg_count += 1
         
     | 
| 
      
 468 
     | 
    
         
            +
                    d = 2 if in_xy else 3
         
     | 
| 
      
 469 
     | 
    
         
            +
                    p1 = np.zeros(3)
         
     | 
| 
      
 470 
     | 
    
         
            +
                    p2 = np.zeros(3)
         
     | 
| 
      
 471 
     | 
    
         
            +
                    for seg_index in range(seg_count):
         
     | 
| 
      
 472 
     | 
    
         
            +
                        successor = (seg_index + 1) % len(self.coordinates)
         
     | 
| 
      
 473 
     | 
    
         
            +
                        p1[:d], p2[:d] = self.coordinates[seg_index, :d], self.coordinates[successor, :d]
         
     | 
| 
      
 474 
     | 
    
         
            +
                        sum += (p1 + p2) * vu.naive_length(p2 - p1)
         
     | 
| 
      
 475 
     | 
    
         
            +
                    centre = sum / (2.0 * self.full_length(in_xy = in_xy))
         
     | 
| 
       485 
476 
     | 
    
         
             
                    if cache:
         
     | 
| 
       486 
477 
     | 
    
         
             
                        self.centre = centre
         
     | 
| 
       487 
478 
     | 
    
         
             
                    return centre
         
     | 
    
        resqpy/model/_model.py
    CHANGED
    
    | 
         @@ -1340,7 +1340,8 @@ class Model(): 
     | 
|
| 
       1340 
1340 
     | 
    
         
             
                       an hdf5 file name is cached once determined for a given ext uuid; to clear the cache,
         
     | 
| 
       1341 
1341 
     | 
    
         
             
                       call the h5_clear_filename_cache() method
         
     | 
| 
       1342 
1342 
     | 
    
         
             
                    """
         
     | 
| 
       1343 
     | 
    
         
            -
             
     | 
| 
      
 1343 
     | 
    
         
            +
                    if isinstance(override, bool):
         
     | 
| 
      
 1344 
     | 
    
         
            +
                        warnings.warn('DEPRECATED: boolean override argument to Model.h5_file_name(); use string instead')
         
     | 
| 
       1344 
1345 
     | 
    
         
             
                    return m_h._h5_file_name(self, uuid = uuid, override = override, file_must_exist = file_must_exist)
         
     | 
| 
       1345 
1346 
     | 
    
         | 
| 
       1346 
1347 
     | 
    
         
             
                def h5_access(self, uuid = None, mode = 'r', override = 'default', file_path = None):
         
     | 
| 
         @@ -1366,7 +1367,8 @@ class Model(): 
     | 
|
| 
       1366 
1367 
     | 
    
         
             
                       an exception will be raised if the hdf5 file cannot be opened; note that sometimes another
         
     | 
| 
       1367 
1368 
     | 
    
         
             
                       piece of code accessing the file might cause a 'resource unavailable' exception
         
     | 
| 
       1368 
1369 
     | 
    
         
             
                    """
         
     | 
| 
       1369 
     | 
    
         
            -
             
     | 
| 
      
 1370 
     | 
    
         
            +
                    if isinstance(override, bool):
         
     | 
| 
      
 1371 
     | 
    
         
            +
                        warnings.warn('DEPRECATED: boolean override argument to Model.h5_access(); use string instead')
         
     | 
| 
       1370 
1372 
     | 
    
         
             
                    return m_h._h5_access(self, uuid = uuid, mode = mode, override = override, file_path = file_path)
         
     | 
| 
       1371 
1373 
     | 
    
         | 
| 
       1372 
1374 
     | 
    
         
             
                def h5_release(self):
         
     | 
| 
         @@ -2098,6 +2100,11 @@ class Model(): 
     | 
|
| 
       2098 
2100 
     | 
    
         
             
                    if other_model is self:
         
     | 
| 
       2099 
2101 
     | 
    
         
             
                        return part
         
     | 
| 
       2100 
2102 
     | 
    
         
             
                    assert part is not None
         
     | 
| 
      
 2103 
     | 
    
         
            +
                    # check whether already existing in this model
         
     | 
| 
      
 2104 
     | 
    
         
            +
                    if part in self.parts_forest.keys():
         
     | 
| 
      
 2105 
     | 
    
         
            +
                        return part
         
     | 
| 
      
 2106 
     | 
    
         
            +
                    if m_c._type_of_part(other_model, part) == 'obj_EpcExternalPartReference':
         
     | 
| 
      
 2107 
     | 
    
         
            +
                        return None
         
     | 
| 
       2101 
2108 
     | 
    
         
             
                    if realization is not None:
         
     | 
| 
       2102 
2109 
     | 
    
         
             
                        assert isinstance(realization, int) and realization >= 0
         
     | 
| 
       2103 
2110 
     | 
    
         
             
                    if force:
         
     | 
| 
         @@ -2108,13 +2115,6 @@ class Model(): 
     | 
|
| 
       2108 
2115 
     | 
    
         
             
                        self_h5_file_name = self.h5_file_name(file_must_exist = False)
         
     | 
| 
       2109 
2116 
     | 
    
         
             
                    hdf5_copy_needed = not os.path.samefile(self_h5_file_name, other_h5_file_name)
         
     | 
| 
       2110 
2117 
     | 
    
         | 
| 
       2111 
     | 
    
         
            -
                    # check whether already existing in this model
         
     | 
| 
       2112 
     | 
    
         
            -
                    if part in self.parts_forest.keys():
         
     | 
| 
       2113 
     | 
    
         
            -
                        return part
         
     | 
| 
       2114 
     | 
    
         
            -
             
     | 
| 
       2115 
     | 
    
         
            -
                    if m_c._type_of_part(other_model, part) == 'obj_EpcExternalPartReference':
         
     | 
| 
       2116 
     | 
    
         
            -
                        return None
         
     | 
| 
       2117 
     | 
    
         
            -
             
     | 
| 
       2118 
2118 
     | 
    
         
             
                    return m_f._copy_part_from_other_model(self,
         
     | 
| 
       2119 
2119 
     | 
    
         
             
                                                           other_model,
         
     | 
| 
       2120 
2120 
     | 
    
         
             
                                                           part,
         
     |