19
19
HLA_to_NEV ,
20
20
NEV_to_HLA ,
21
21
get_xyz ,
22
- radius_from_dls
22
+ radius_from_dls ,
23
+ get_arc
23
24
)
24
25
from .error import ErrorModel , ERROR_MODELS
25
26
from .node import Node
@@ -256,69 +257,69 @@ def __init__(
256
257
257
258
Parameters
258
259
----------
259
- md: (,n) list or array of floats
260
- List or array of well bore measured depths.
261
- inc: (,n) list or array of floats
262
- List or array of well bore survey inclinations
263
- azi: (,n) list or array of floats
264
- List or array of well bore survey azimuths
265
- n: (,n) list or array of floats (default: None)
266
- List or array of well bore northings
267
- e: (,n) list or array of floats (default: None)
268
- List or array of well bore eastings
269
- tvd: (,n) list or array of floats (default: None)
270
- List or array of local well bore z coordinates, i.e. depth
271
- and usually relative to surface or mean sea level.
272
- x: (,n) list or array of floats (default: None)
273
- List or array of local well bore x coordinates, which is
274
- usually aligned to the east direction.
275
- y: (,n) list or array of floats (default: None)
276
- List or array of local well bore y coordinates, which is
277
- usually aligned to the north direction.
278
- z: (,n) list or array of floats (default: None)
279
- List or array of well bore true vertical depths relative
280
- to the well surface datum (usually the drill floor
281
- elevation DFE, so not always identical to tvd).
282
- vec: (n,3) list or array of (,3) floats (default: None)
283
- List or array of well bore unit vectors that describe the
284
- inclination and azimuth of the well relative to (x,y,z)
285
- coordinates.
286
- header: SurveyHeader object (default: None)
287
- A SurveyHeader object with information about the well location
288
- and survey data. If left default then a SurveyHeader will be
289
- generated with the default properties assigned, but these may
290
- not be relevant and may result in incorrect data.
291
- radius: float or (,n) list or array of floats (default: None)
292
- If a single float is specified, this value will be
293
- assigned to the entire well bore. If a list or array of
294
- floats is provided, these are the radii of the well bore.
295
- If None, a well bore radius of 12" or approximately 0.3 m
296
- is applied.
297
- cov_nev: (n,3,3) list or array of floats (default: None)
298
- List or array of covariance matrices in the (n,e,v)
299
- coordinate system.
300
- cov_hla: (n,3,3) list or array of floats (default: None)
301
- List or array of covariance matrices in the (h,l,a)
302
- well bore coordinate system (high side, lateral, along
303
- hole).
304
- error_model: str (default: None)
305
- If specified, this model is used to calculate the
306
- covariance matrices if they are not present. Currently,
307
- only the "ISCWSA_MWD" model is provided.
308
- start_xyz: (,3) list or array of floats (default: [0,0,0])
309
- The start position of the well bore in (x,y,z) coordinates.
310
- start_nev: (,3) list or array of floats (default: [0,0,0])
311
- The start position of the well bore in (n,e,v) coordinates.
312
- start_cov_nev: (,3,3) list or array of floats (default: None)
313
- The covariance matrix for the start position of the well
314
- bore in (n,e,v) coordinates.
315
- deg: boolean (default: True)
316
- Indicates whether the provided angles are in degrees
317
- (True), else radians (False).
318
- unit: str (default: 'meters')
319
- Indicates whether the provided lengths and distances are
320
- in 'meters' or 'feet', which impacts the calculation of
321
- the dls (dog leg severity).
260
+ md: (,n) list or array of floats
261
+ List or array of well bore measured depths.
262
+ inc: (,n) list or array of floats
263
+ List or array of well bore survey inclinations
264
+ azi: (,n) list or array of floats
265
+ List or array of well bore survey azimuths
266
+ n: (,n) list or array of floats (default: None)
267
+ List or array of well bore northings
268
+ e: (,n) list or array of floats (default: None)
269
+ List or array of well bore eastings
270
+ tvd: (,n) list or array of floats (default: None)
271
+ List or array of local well bore z coordinates, i.e. depth
272
+ and usually relative to surface or mean sea level.
273
+ x: (,n) list or array of floats (default: None)
274
+ List or array of local well bore x coordinates, which is
275
+ usually aligned to the east direction.
276
+ y: (,n) list or array of floats (default: None)
277
+ List or array of local well bore y coordinates, which is
278
+ usually aligned to the north direction.
279
+ z: (,n) list or array of floats (default: None)
280
+ List or array of well bore true vertical depths relative
281
+ to the well surface datum (usually the drill floor
282
+ elevation DFE, so not always identical to tvd).
283
+ vec: (n,3) list or array of (,3) floats (default: None)
284
+ List or array of well bore unit vectors that describe the
285
+ inclination and azimuth of the well relative to (x,y,z)
286
+ coordinates.
287
+ header: SurveyHeader object (default: None)
288
+ A SurveyHeader object with information about the well location
289
+ and survey data. If left default then a SurveyHeader will be
290
+ generated with the default properties assigned, but these may
291
+ not be relevant and may result in incorrect data.
292
+ radius: float or (,n) list or array of floats (default: None)
293
+ If a single float is specified, this value will be
294
+ assigned to the entire well bore. If a list or array of
295
+ floats is provided, these are the radii of the well bore.
296
+ If None, a well bore radius of 12" or approximately 0.3 m
297
+ is applied.
298
+ cov_nev: (n,3,3) list or array of floats (default: None)
299
+ List or array of covariance matrices in the (n,e,v)
300
+ coordinate system.
301
+ cov_hla: (n,3,3) list or array of floats (default: None)
302
+ List or array of covariance matrices in the (h,l,a)
303
+ well bore coordinate system (high side, lateral, along
304
+ hole).
305
+ error_model: str (default: None)
306
+ If specified, this model is used to calculate the
307
+ covariance matrices if they are not present. Currently,
308
+ only the "ISCWSA_MWD" model is provided.
309
+ start_xyz: (,3) list or array of floats (default: [0,0,0])
310
+ The start position of the well bore in (x,y,z) coordinates.
311
+ start_nev: (,3) list or array of floats (default: [0,0,0])
312
+ The start position of the well bore in (n,e,v) coordinates.
313
+ start_cov_nev: (,3,3) list or array of floats (default: None)
314
+ The covariance matrix for the start position of the well
315
+ bore in (n,e,v) coordinates.
316
+ deg: boolean (default: True)
317
+ Indicates whether the provided angles are in degrees
318
+ (True), else radians (False).
319
+ unit: str (default: 'meters')
320
+ Indicates whether the provided lengths and distances are
321
+ in 'meters' or 'feet', which impacts the calculation of
322
+ the dls (dog leg severity).
322
323
323
324
Returns
324
325
-------
@@ -877,10 +878,11 @@ def set_vertical_section(self, vertical_section_azimuth, deg=True):
877
878
)
878
879
879
880
def modified_tortuosity_index (
880
- self , rtol = 0.01 , dls_tol = None , data = False , ** kwargs
881
+ self , rtol = 0.01 , dls_tol = None , step = 1.0 , dls_noise = 1.0 , data = False ,
882
+ ** kwargs
881
883
):
882
884
"""
883
- Convenient method for calculating the Tortuosity Index (TI) using a
885
+ Convenience method for calculating the Tortuosity Index (TI) using a
884
886
modified version of the method described in the International
885
887
Association of Directional Drilling presentation
886
888
(https://www.iadd-intl.org/media/files/files/47d68cb4/iadd-luncheon-february-22-2018-v2.pdf)
@@ -895,15 +897,37 @@ def modified_tortuosity_index(
895
897
dls_tol: float or None
896
898
Indicates whether or not to check for dls continuity within the
897
899
defined dls tolerance.
898
- data: float
900
+ step: float or None
901
+ The step length in meters used for interpolating the survey prior
902
+ to calculating trajectory with the maximum curvature method. If
903
+ None or dls_noise is None then no interpolation is done.
904
+ dls_noise: float or None
905
+ The incremental Dog Leg Severity to be added when using the
906
+ maximum curvature method. If None then no pre-processing will be
907
+ done and minimum curvature is assumed.
908
+ data: bool
899
909
If true returns a dictionary of properties.
900
910
901
911
Returns
912
+ -------
902
913
ti: (n,1) array or dict
903
914
Array of tortuosity index or a dict of results where:
915
+
916
+ References
917
+ ----------
918
+ Further details regarding the maximum curvature method can be read
919
+ [here](https://jonnymaserati.github.io/2022/06/19/modified-tortuosity-index-survey-frequency.html)
904
920
"""
921
+ # Check whether to pre-process the survey to apply maximum curvature.
922
+ if bool (dls_noise ):
923
+ survey = self .interpolate_survey (step = step )
924
+ survey = survey .maximum_curvature (dls_noise = dls_noise )
925
+
926
+ else :
927
+ survey = self
928
+
905
929
return modified_tortuosity_index (
906
- self , rtol = rtol , dls_tol = dls_tol , data = data , ** kwargs
930
+ survey , rtol = rtol , dls_tol = dls_tol , data = data , ** kwargs
907
931
)
908
932
909
933
def tortuosity_index (self , rtol = 0.01 , dls_tol = None , data = False , ** kwargs ):
@@ -957,6 +981,80 @@ def directional_difficulty_index(self, **kwargs):
957
981
958
982
return directional_difficulty_index (self , ** kwargs )
959
983
984
+ def maximum_curvature (self , dls_noise = 1.0 ):
985
+ """
986
+ Create a well trajectory using the Maximum Curvature method.
987
+
988
+ Parameters
989
+ ----------
990
+ survey: welleng.survey.Survey object
991
+ dls_noise: float
992
+ The additional Dog Leg Severity (DLS) in deg/30m used to calculate
993
+ the curvature for the initial section of the survey interval.
994
+
995
+ Returns
996
+ -------
997
+ survey_new: welleng.Survey.survey object
998
+ A revised survey object calculated using the Minimum Curvature
999
+ method with updated survey positions and additional mid-point
1000
+ stations.
1001
+ """
1002
+
1003
+ dls_effective = self .dls + dls_noise
1004
+ radius_effective = radius_from_dls (dls_effective )
1005
+
1006
+ dogleg1 = (
1007
+ (self .delta_md / radius_effective ) / 2
1008
+ )
1009
+
1010
+ radius_effective = np .where (
1011
+ dogleg1 > np .pi ,
1012
+ self .delta_md * 4 / (2 * np .pi ),
1013
+ radius_effective
1014
+ )
1015
+
1016
+ arc1 = [
1017
+ get_arc (dogleg , _radius_effective , toolface , vec = vec )
1018
+ for dogleg , _radius_effective , toolface , vec in zip (
1019
+ dogleg1 [1 :], radius_effective [1 :], self .toolface [:- 1 ],
1020
+ self .vec_nev [:- 1 ]
1021
+ )
1022
+ ]
1023
+
1024
+ _survey_new = np .array ([
1025
+ [row [- 1 ], * np .degrees (get_angles (row [1 ], nev = True ))[0 ]]
1026
+ for row in arc1
1027
+ ])
1028
+ _survey_new [:, 0 ] += self .md [:- 1 ]
1029
+
1030
+ survey_new = np .zeros (shape = (len (_survey_new ) * 2 + 1 , 3 ))
1031
+ survey_new [:- 1 ] = np .stack (
1032
+ (self .survey_deg [:- 1 ].T , _survey_new .T ),
1033
+ axis = 1
1034
+ ).T .reshape (- 1 , 3 )
1035
+ survey_new [- 1 ] = self .survey_deg [- 1 ]
1036
+
1037
+ # Update the new survey header as the new azimuth reference is 'grid'.
1038
+ sh = self .header
1039
+ sh .azi_reference = 'grid'
1040
+
1041
+ # Create a new Survey instance
1042
+ survey = Survey (
1043
+ md = survey_new [:, 0 ],
1044
+ inc = survey_new [:, 1 ],
1045
+ azi = survey_new [:, 2 ],
1046
+ header = sh ,
1047
+ start_xyz = self .start_xyz ,
1048
+ start_nev = self .start_nev
1049
+ )
1050
+
1051
+ # Update the interpolated property to keep track of the original survey
1052
+ # stations.
1053
+ survey .interpolated = np .full_like (survey .md , True )
1054
+ survey .interpolated [::2 ] = self .interpolated
1055
+
1056
+ return survey
1057
+
960
1058
961
1059
def modified_tortuosity_index (
962
1060
survey , rtol = 0.01 , dls_tol = None , data = False , ** kwargs
@@ -1014,7 +1112,7 @@ def modified_tortuosity_index(
1014
1112
'continuous' : continuous , 'starts' : starts , 'mds' : mds ,
1015
1113
'locs' : locs , 'n_sections' : n_sections ,
1016
1114
'n_sections_arr' : n_sections_arr , 'l_cs' : l_cs , 'l_xs' : l_xs ,
1017
- 'mti' : mti
1115
+ 'mti' : mti , 'survey' : survey
1018
1116
}
1019
1117
1020
1118
return mti
0 commit comments