Skip to content

Commit

Permalink
Merge pull request #187 from jonnymaserati/enhancement/survey_scale_f…
Browse files Browse the repository at this point in the history
…actor

Included grid_scale_factor in survey.SurveyHeader, which is used to c…
  • Loading branch information
jonnymaserati committed Jul 7, 2024
2 parents 001d679 + b0c1cf0 commit f49a4fd
Showing 1 changed file with 178 additions and 160 deletions.
338 changes: 178 additions & 160 deletions welleng/survey.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,71 +255,6 @@ def transform_coordinates(


class SurveyHeader:
"""
A class for storing header information about a well.
Parameters
----------
name: string (default: None)
The assigned name of the well bore.
longitude: float (default: None)
The longitude of the surface location of the well. If left
default (None) then it will be assigned to Grenwich, the
undisputed center of the universe.
latitude: float (default: None)
The latitude of the surface location of the well. If left
default (None) then it will be assigned to Grenwich, the
undisputed center of the universe.
altitude: float (default: None)
The altitude of the surface location. If left defaults (None)
then it will be assigned to 0.
survey_date: YYYY-mm-dd (default: None)
The date on which the survey data was recorded. If left
default then the current date is assigned.
G: float (default: 9.80665)
The gravitational field strength in m/s^2.
b_total: float (default: None)
The gravitation field strength in nT. If left default, then
the value is calculated from the longitude, latitude, altitude
and survey_data properties using the magnetic_field_calculator.
earth_rate: float (default: 0.26249751949994715)
The rate of rotation of the earth in radians per hour.
noise_reduction_factor: float (default: 1.0)
A fiddle factor for random gyro noise.
dip: float (default: None)
The dip (inclination) of the magnetic field relative to the
earth's horizontal. If left default, then the value is
calculated using the magnetic_field_calculator. The unit (deg
of rad) is determined by the deg property.
declination: float (default: None)
The angle between true north and magnetic north at the well
location. If left default, then the value is calculated
using the magnetic_field_calculator.
convergence: float (default: 0)
The angle of convergence between the projection meridian and
the line from true north through the location of the well.
azi_reference: string (default: 'true')
The reference system for the azimuth angles in the survey data,
either "true", "magnetic" or "grid". Note that survey
calculations are performed in the "grid" reference and
converted to and from the other systems.
vertical_inc_limit: float (default 0.0001)
For survey inclination angles less than the vertical_inc_limit
(in degrees), calculations are approximated to avoid
singularities and errors.
deg: bool (default: True)
Indicates whether the survey angles are measured in degrees
(True) or radians (False).
depth_unit: string (default: "meters")
The unit of depth for the survey data, either "meters" or
"feet".
surface_unit: string (default: "feet")
The unit of distance for the survey data, either "meters" or
"feet".
vertical_section_azimuth: float (default: 0.0)
The azimuth along which to determine the vertical section data
for the well trajectory.
"""
def __init__(
self,
name: str = None,
Expand All @@ -344,8 +279,76 @@ def __init__(
'declination': 0.,
},
vertical_section_azimuth=0,
grid_scale_factor: float = 1.0
# **kwargs
):
"""A class for storing header information about a well.
Parameters
----------
name: string (default: None)
The assigned name of the well bore.
longitude: float (default: None)
The longitude of the surface location of the well. If left
default (None) then it will be assigned to Grenwich, the
undisputed center of the universe.
latitude: float (default: None)
The latitude of the surface location of the well. If left
default (None) then it will be assigned to Grenwich, the
undisputed center of the universe.
altitude: float (default: None)
The altitude of the surface location. If left defaults (None)
then it will be assigned to 0.
survey_date: YYYY-mm-dd (default: None)
The date on which the survey data was recorded. If left
default then the current date is assigned.
G: float (default: 9.80665)
The gravitational field strength in m/s^2.
b_total: float (default: None)
The gravitation field strength in nT. If left default, then
the value is calculated from the longitude, latitude, altitude
and survey_data properties using the magnetic_field_calculator.
earth_rate: float (default: 0.26249751949994715)
The rate of rotation of the earth in radians per hour.
noise_reduction_factor: float (default: 1.0)
A fiddle factor for random gyro noise.
dip: float (default: None)
The dip (inclination) of the magnetic field relative to the
earth's horizontal. If left default, then the value is
calculated using the magnetic_field_calculator. The unit (deg
of rad) is determined by the deg property.
declination: float (default: None)
The angle between true north and magnetic north at the well
location. If left default, then the value is calculated
using the magnetic_field_calculator.
convergence: float (default: 0)
The angle of convergence between the projection meridian and
the line from true north through the location of the well.
azi_reference: string (default: 'true')
The reference system for the azimuth angles in the survey data,
either "true", "magnetic" or "grid". Note that survey
calculations are performed in the "grid" reference and
converted to and from the other systems.
vertical_inc_limit: float (default 0.0001)
For survey inclination angles less than the vertical_inc_limit
(in degrees), calculations are approximated to avoid
singularities and errors.
deg: bool (default: True)
Indicates whether the survey angles are measured in degrees
(True) or radians (False).
depth_unit: string (default: "meters")
The unit of depth for the survey data, either "meters" or
"feet".
surface_unit: string (default: "feet")
The unit of distance for the survey data, either "meters" or
"feet".
vertical_section_azimuth: float (default: 0.0)
The azimuth along which to determine the vertical section data
for the well trajectory.
grid_scale_factor: float (default: 1.0)
Scale factor applied during when determining the grid coordinates
from the provided survey data.
"""
if latitude is not None:
assert 90 >= latitude >= -90, "latitude out of bounds"
if longitude is not None:
Expand All @@ -364,6 +367,7 @@ def __init__(
self.convergence = convergence
self.declination = declination
self.vertical_inc_limit = vertical_inc_limit
self.grid_scale_factor = grid_scale_factor

self.depth_unit = get_unit(depth_unit)
self.surface_unit = get_unit(surface_unit)
Expand All @@ -378,6 +382,20 @@ def _get_mag_data(self, deg):
"""
Initiates b_total if provided, else calculates a value.
"""
result = {
'field-value': {
'total-intensity': {
'value': self.mag_defaults.get('b_total')
},
'inclination': {
'value': self.mag_defaults.get('dip')
},
'declination': {
'value': self.mag_defaults.get('declination')
}
}
}

if MAG_CALC:
calculator = MagneticFieldCalculator()
try:
Expand All @@ -388,26 +406,16 @@ def _get_mag_data(self, deg):
date=self.survey_date
)
except:
result = calculator.calculate(
latitude=self.latitude,
longitude=self.longitude,
altitude=self.altitude,
date=self._get_date(date=None)
)
else:
result = {
'field-value': {
'total-intensity': {
'value': self.mag_defaults.get('b_total')
},
'inclination': {
'value': self.mag_defaults.get('dip')
},
'declination': {
'value': self.mag_defaults.get('declination')
}
}
}
try:
result = calculator.calculate(
latitude=self.latitude,
longitude=self.longitude,
altitude=self.altitude,
date=self._get_date(date=None)
)
except: # prevents crashing if there's no connection to the internet - need to have a log that captures when this occurs.
# TODO: log when no internet connection prvents updating the result var
pass

if self.b_total is None:
self.b_total = result['field-value']['total-intensity']['value']
Expand Down Expand Up @@ -448,80 +456,6 @@ def _validate_date(self, date):


class Survey:
"""
Initialize a `welleng.Survey` object. Calculations are performed in the
azi_reference "grid" domain.
Parameters
----------
md: (,n) list or array of floats
List or array of well bore measured depths.
inc: (,n) list or array of floats
List or array of well bore survey inclinations
azi: (,n) list or array of floats
List or array of well bore survey azimuths
n: (,n) list or array of floats (default: None)
List or array of well bore northings
e: (,n) list or array of floats (default: None)
List or array of well bore eastings
tvd: (,n) list or array of floats (default: None)
List or array of local well bore z coordinates, i.e. depth
and usually relative to surface or mean sea level.
x: (,n) list or array of floats (default: None)
List or array of local well bore x coordinates, which is
usually aligned to the east direction.
y: (,n) list or array of floats (default: None)
List or array of local well bore y coordinates, which is
usually aligned to the north direction.
z: (,n) list or array of floats (default: None)
List or array of well bore true vertical depths relative
to the well surface datum (usually the drill floor
elevation DFE, so not always identical to tvd).
vec: (n,3) list or array of (,3) floats (default: None)
List or array of well bore unit vectors that describe the
inclination and azimuth of the well relative to (x,y,z)
coordinates.
header: SurveyHeader object (default: None)
A SurveyHeader object with information about the well location
and survey data. If left default then a SurveyHeader will be
generated with the default properties assigned, but these may
not be relevant and may result in incorrect data.
radius: float or (,n) list or array of floats (default: None)
If a single float is specified, this value will be
assigned to the entire well bore. If a list or array of
floats is provided, these are the radii of the well bore.
If None, a well bore radius of 12" or approximately 0.3 m
is applied.
cov_nev: (n,3,3) list or array of floats (default: None)
List or array of covariance matrices in the (n,e,v)
coordinate system.
cov_hla: (n,3,3) list or array of floats (default: None)
List or array of covariance matrices in the (h,l,a)
well bore coordinate system (high side, lateral, along
hole).
error_model: str (default: None)
If specified, this model is used to calculate the
covariance matrices if they are not present. Currently,
only the "ISCWSA_MWD" model is provided.
start_xyz: (,3) list or array of floats (default: [0,0,0])
The start position of the well bore in (x,y,z) coordinates.
start_nev: (,3) list or array of floats (default: [0,0,0])
The start position of the well bore in (n,e,v) coordinates.
start_cov_nev: (,3,3) list or array of floats (default: None)
The covariance matrix for the start position of the well
bore in (n,e,v) coordinates.
deg: boolean (default: True)
Indicates whether the provided angles are in degrees
(True), else radians (False).
unit: str (default: 'meters')
Indicates whether the provided lengths and distances are
in 'meters' or 'feet', which impacts the calculation of
the dls (dog leg severity).
Returns
-------
A welleng.survey.Survey object.
"""
def __init__(
self,
md,
Expand All @@ -547,6 +481,79 @@ def __init__(
unit="meters",
**kwargs
):
"""Initialize a `welleng.Survey` object. Calculations are performed in the
azi_reference "grid" domain.
Parameters
----------
md: (,n) list or array of floats
List or array of well bore measured depths.
inc: (,n) list or array of floats
List or array of well bore survey inclinations
azi: (,n) list or array of floats
List or array of well bore survey azimuths
n: (,n) list or array of floats (default: None)
List or array of well bore northings
e: (,n) list or array of floats (default: None)
List or array of well bore eastings
tvd: (,n) list or array of floats (default: None)
List or array of local well bore z coordinates, i.e. depth
and usually relative to surface or mean sea level.
x: (,n) list or array of floats (default: None)
List or array of local well bore x coordinates, which is
usually aligned to the east direction.
y: (,n) list or array of floats (default: None)
List or array of local well bore y coordinates, which is
usually aligned to the north direction.
z: (,n) list or array of floats (default: None)
List or array of well bore true vertical depths relative
to the well surface datum (usually the drill floor
elevation DFE, so not always identical to tvd).
vec: (n,3) list or array of (,3) floats (default: None)
List or array of well bore unit vectors that describe the
inclination and azimuth of the well relative to (x,y,z)
coordinates.
header: SurveyHeader object (default: None)
A SurveyHeader object with information about the well location
and survey data. If left default then a SurveyHeader will be
generated with the default properties assigned, but these may
not be relevant and may result in incorrect data.
radius: float or (,n) list or array of floats (default: None)
If a single float is specified, this value will be
assigned to the entire well bore. If a list or array of
floats is provided, these are the radii of the well bore.
If None, a well bore radius of 12" or approximately 0.3 m
is applied.
cov_nev: (n,3,3) list or array of floats (default: None)
List or array of covariance matrices in the (n,e,v)
coordinate system.
cov_hla: (n,3,3) list or array of floats (default: None)
List or array of covariance matrices in the (h,l,a)
well bore coordinate system (high side, lateral, along
hole).
error_model: str (default: None)
If specified, this model is used to calculate the
covariance matrices if they are not present. Currently,
only the "ISCWSA_MWD" model is provided.
start_xyz: (,3) list or array of floats (default: [0,0,0])
The start position of the well bore in (x,y,z) coordinates.
start_nev: (,3) list or array of floats (default: [0,0,0])
The start position of the well bore in (n,e,v) coordinates.
start_cov_nev: (,3,3) list or array of floats (default: None)
The covariance matrix for the start position of the well
bore in (n,e,v) coordinates.
deg: boolean (default: True)
Indicates whether the provided angles are in degrees
(True), else radians (False).
unit: str (default: 'meters')
Indicates whether the provided lengths and distances are
in 'meters' or 'feet', which impacts the calculation of
the dls (dog leg severity).
Returns
-------
A welleng.survey.Survey object.
"""
if header is None:
self.header = SurveyHeader()
else:
Expand Down Expand Up @@ -716,7 +723,18 @@ def _min_curve(self, vec):
self.delta_md = mc.delta_md
self.dls = mc.dls
self.pos_xyz = mc.poss
self.pos_nev = get_nev(self.pos_xyz) + self.start_nev
self.pos_nev = (
get_nev(self.pos_xyz)
* np.full_like(
self.pos_xyz,
np.array([
self.header.grid_scale_factor,
self.header.grid_scale_factor,
1
])
)
+ self.start_nev
)

if self.x is None:
# self.x, self.y, self.z = (mc.poss + self.start_xyz).T
Expand Down

0 comments on commit f49a4fd

Please sign in to comment.