Skip to content

Commit

Permalink
Merge pull request #177 from jonnymaserati/enhancements/minor_updates
Browse files Browse the repository at this point in the history
Minor enhancements and a couple of handy utils.
  • Loading branch information
jonnymaserati committed Jan 28, 2024
2 parents 37c9e7e + 90e15a7 commit 19c8004
Show file tree
Hide file tree
Showing 13 changed files with 616 additions and 631 deletions.
130 changes: 61 additions & 69 deletions tests/test_clearance_iscwsa.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import unittest
from welleng.survey import Survey, make_survey_header
from welleng.clearance import IscwsaClearance
import numpy as np
Expand All @@ -7,7 +6,7 @@
"""
Test that the ISCWSA clearance model is working within a defined tolerance,
testing against the ISCWSA standard set of wellpaths for evaluating clearance
scenarios using the MWD Rev4 error model.
scenarios using the MWD Rev4 error model.
"""

# Read well and validation data
Expand Down Expand Up @@ -57,74 +56,67 @@ def generate_surveys(self, data=data):
return surveys


class TestClearanceIscwsa(unittest.TestCase):
def test_minimize_sf(self, data=data):
surveys = generate_surveys(data)
reference = surveys["Reference well"]
offset = surveys["09 - well"]

result = IscwsaClearance(reference, offset, minimize_sf=False)
result_min = IscwsaClearance(reference, offset, minimize_sf=True)

idx = np.where(result_min.ref.interpolated == False)

# Check that interpolated survey is not corrupted
for attr in [
'azi_grid_rad', 'azi_mag_rad', 'azi_true_rad', 'cov_hla', 'cov_nev',
'pos_nev', 'pos_xyz', 'md', 'radius'
]:
assert np.allclose(
getattr(result.ref, attr), getattr(result_min.ref, attr)[idx]
)

pass

for attr in [
'Rr', 'calc_hole', 'distance_cc', 'eou_boundary',
'eou_separation', 'hoz_bearing', 'idx', 'masd', 'off_cov_hla',
'off_cov_nev', 'off_delta_hlas', 'off_delta_nevs', 'off_pcr',
'ref_cov_hla', 'ref_cov_nev', 'ref_delta_hlas', 'ref_delta_nevs',
'ref_nevs', 'ref_pcr', 'sf', 'wellbore_separation'
]:
# `toolface_bearing` and `trav_cyl_azi_deg` are a bit unstable when
# well paths are parallel.

assert np.allclose(
getattr(result, attr), getattr(result_min, attr)[idx],
rtol=1e-01, atol=1e-02
)

pass

def test_clearance_iscwsa(self, data=data, rtol=1e-02, atol=1e-03):
surveys = generate_surveys(data)
reference = surveys["Reference well"]

# Perform clearance checks for each survey
for well in surveys:
if well != "09 - well":
continue
if well == "Reference well":
continue
else:
offset = surveys[well]
# skip well 10
if well in ["10 - well"]:
continue
else:
for b in [False, True]:
result = IscwsaClearance(reference, offset, minimize_sf=b)
assert np.allclose(
result.sf[np.where(result.ref.interpolated == False)],
np.array(data["wells"][well]["SF"]),
rtol=rtol, atol=atol
)
def test_minimize_sf(data=data):
surveys = generate_surveys(data)
reference = surveys["Reference well"]
offset = surveys["09 - well"]

result = IscwsaClearance(reference, offset, minimize_sf=False)
result_min = IscwsaClearance(reference, offset, minimize_sf=True)

idx = np.where(result_min.ref.interpolated == False) # noqa E712

# Check that interpolated survey is not corrupted
for attr in [
'azi_grid_rad', 'azi_mag_rad', 'azi_true_rad', 'cov_hla', 'cov_nev',
'pos_nev', 'pos_xyz', 'md', 'radius'
]:
assert np.allclose(
getattr(result.ref, attr), getattr(result_min.ref, attr)[idx]
)

pass

for attr in [
'Rr', 'calc_hole', 'distance_cc', 'eou_boundary',
'eou_separation', 'hoz_bearing', 'idx', 'masd', 'off_cov_hla',
'off_cov_nev', 'off_delta_hlas', 'off_delta_nevs', 'off_pcr',
'ref_cov_hla', 'ref_cov_nev', 'ref_delta_hlas', 'ref_delta_nevs',
'ref_nevs', 'ref_pcr', 'sf', 'wellbore_separation'
]:
# `toolface_bearing` and `trav_cyl_azi_deg` are a bit unstable when
# well paths are parallel.

assert np.allclose(
getattr(result, attr), getattr(result_min, attr)[idx],
rtol=1e-01, atol=1e-02
)

pass


# make above test runnanble separately
if __name__ == '__main__':
unittest.main()
# test_minimize_sf(data=data)
# test_clearance_iscwsa(data=data)
def test_clearance_iscwsa(data=data, rtol=1e-02, atol=1e-03):
surveys = generate_surveys(data)
reference = surveys["Reference well"]

# Perform clearance checks for each survey
for well in surveys:
if well != "09 - well":
continue
if well == "Reference well":
continue
else:
offset = surveys[well]
# skip well 10
if well in ["10 - well"]:
continue
else:
for b in [False, True]:
result = IscwsaClearance(reference, offset, minimize_sf=b)
assert np.allclose(
result.sf[np.where(result.ref.interpolated == False)], # noqa E712
np.array(data["wells"][well]["SF"]),
rtol=rtol, atol=atol
)

pass
240 changes: 107 additions & 133 deletions tests/test_connector.py
Original file line number Diff line number Diff line change
@@ -1,139 +1,113 @@
import inspect
import sys
import unittest

import numpy as np

from welleng.connector import Connector
from welleng.survey import Survey, from_connections


class ConnectorTest(unittest.TestCase):
def test_md_hold(self):
# test hold with only md provided
c = Connector(
vec1=[0, 0, 1],
md2=500,
)
assert (
c.inc_target == c.inc1
and c.azi_target == c.azi1
and c.pos_target[2] == c.md_target
), "Failed c1"
assert c.method == 'hold', "Unexpected method"

assert isinstance(from_connections(c), Survey)

def test_md_and_vec(self):
# test with md2 and vec2 provided (minimum curvature)
c = Connector(
vec1=[0, 0, 1],
md2=1000,
vec2=[0, 1, 0]
)
assert c.method == 'min_curve'

def test_pos(self):
# test with pos2 provided (minimum distance)
c = Connector(
vec1=[0, 0, 1],
pos2=[100, 100, 1000],
)
assert c.md_target > c.pos1[2], "Failed c3"

def test_pos_and_dls(self):
# test with pos2 needing more aggressive dls (minimum curvature)
c = Connector(
vec1=[0, 0, 1],
pos2=[200, 400, 200]
)
assert c.method == 'min_curve_to_target'

def test_pos_and_vec(self):
# test with pos2 and vec2 provided
vec1 = [-1, -1, 1]
vec2 = [1, -1, 0]
c = Connector(
pos1=[0., 0., 0],
vec1=vec1 / np.linalg.norm(vec1),
pos2=[0., 1000., 500.],
vec2=vec2 / np.linalg.norm(vec2),
)
assert c.method == 'curve_hold_curve'

# test if interpolator and survey functions are working
assert isinstance(from_connections(c, step=30), Survey)

def test_pos_inc_azi(self):
# test with pos2, inc1 and azi1 provided
c = Connector(
pos1=[0., 0., 0],
inc1=0.,
azi1=90,
pos2=[1000., 1000., 1000.],
vec2=[0., 0., 1.],
)
assert c.method == 'curve_hold_curve'

def test_dls2(self):
# test with different dls for second curve section
c = Connector(
pos1=[0., 0., 0],
vec1=[0., 0., 1.],
pos2=[0., 100., 1000.],
vec2=[0., 0., 1.],
dls_design2=5
)
assert c.radius_design2 < c.radius_design

def test_radius_critical(self):
# test with dls_critical requirement (actual dls < dls_design)
c = Connector(
pos1=[0., 0., 0],
vec1=[0., 0., 1.],
pos2=[0., 100., 100.],
vec2=[0., 0., 1.],
)
assert c.radius_critical < c.radius_design

def test_min_curve(self):
# test min_curve (inc2 provided)
c = Connector(
pos1=[0., 0., 0],
vec1=[0., 0., 1.],
inc2=30,
)
assert c.method == 'min_curve'

def test_radius_critical_with_min_curve(self):
# test min_curve with md less than required radius
c = Connector(
pos1=[0., 0., 0],
inc1=0,
azi1=0,
md2=500,
inc2=90,
azi2=0,
)
assert c.radius_critical < c.radius_design
# def one_function_to_run_them_all():
# """
# Function to gather the test functions so that they can be tested by
# running this module.

# https://stackoverflow.com/questions/18907712/python-get-list-of-all-
# functions-in-current-module-inspecting-current-module
# """
# test_functions = [
# obj for name, obj in inspect.getmembers(sys.modules[__name__])
# if (inspect.isfunction(obj)
# and name.startswith('test')
# and name != 'all')
# ]

# [f() for f in test_functions]


if __name__ == '__main__':
unittest.main()
# one_function_to_run_them_all()
def test_md_hold():
# test hold with only md provided
c = Connector(
vec1=[0, 0, 1],
md2=500,
)
assert (
c.inc_target == c.inc1
and c.azi_target == c.azi1
and c.pos_target[2] == c.md_target
), "Failed c1"
assert c.method == 'hold', "Unexpected method"

assert isinstance(from_connections(c), Survey)

def test_md_and_vec():
# test with md2 and vec2 provided (minimum curvature)
c = Connector(
vec1=[0, 0, 1],
md2=1000,
vec2=[0, 1, 0]
)
assert c.method == 'min_curve'

def test_pos():
# test with pos2 provided (minimum distance)
c = Connector(
vec1=[0, 0, 1],
pos2=[100, 100, 1000],
)
assert c.md_target > c.pos1[2], "Failed c3"

def test_pos_and_dls():
# test with pos2 needing more aggressive dls (minimum curvature)
c = Connector(
vec1=[0, 0, 1],
pos2=[200, 400, 200]
)
assert c.method == 'min_curve_to_target'

def test_pos_and_vec():
# test with pos2 and vec2 provided
vec1 = [-1, -1, 1]
vec2 = [1, -1, 0]
c = Connector(
pos1=[0., 0., 0],
vec1=vec1 / np.linalg.norm(vec1),
pos2=[0., 1000., 500.],
vec2=vec2 / np.linalg.norm(vec2),
)
assert c.method == 'curve_hold_curve'

# test if interpolator and survey functions are working
assert isinstance(from_connections(c, step=30), Survey)

def test_pos_inc_azi():
# test with pos2, inc1 and azi1 provided
c = Connector(
pos1=[0., 0., 0],
inc1=0.,
azi1=90,
pos2=[1000., 1000., 1000.],
vec2=[0., 0., 1.],
)
assert c.method == 'curve_hold_curve'

def test_dls2():
# test with different dls for second curve section
c = Connector(
pos1=[0., 0., 0],
vec1=[0., 0., 1.],
pos2=[0., 100., 1000.],
vec2=[0., 0., 1.],
dls_design2=5
)
assert c.radius_design2 < c.radius_design

def test_radius_critical():
# test with dls_critical requirement (actual dls < dls_design)
c = Connector(
pos1=[0., 0., 0],
vec1=[0., 0., 1.],
pos2=[0., 100., 100.],
vec2=[0., 0., 1.],
)
assert c.radius_critical < c.radius_design

def test_min_curve():
# test min_curve (inc2 provided)
c = Connector(
pos1=[0., 0., 0],
vec1=[0., 0., 1.],
inc2=30,
)
assert c.method == 'min_curve'

def test_radius_critical_with_min_curve():
# test min_curve with md less than required radius
c = Connector(
pos1=[0., 0., 0],
inc1=0,
azi1=0,
md2=500,
inc2=90,
azi2=0,
)
assert c.radius_critical < c.radius_design
Loading

0 comments on commit 19c8004

Please sign in to comment.