convertTrajectory enhancements for inverse minimum curvature
Implement inverse minimum curvature for inputKind "dX_dY_dZ"
. Please first read the document and follow the equations in tab Min.Curv in the spreadsheet.
This enhancement will "invert" the input dx,dy,dz to output MD,INC,AZI at the stations. It will then use these to compute the trajectory.
- The dX and dY are normally GN referenced and true to scale, and hence the output AZI is also GN referenced. But if they would be TN, then the output would be AZI_TN.
- The implementation can also take as input "X_Y_Z" data, because for each station the difference with the previous is used, i.e., dX[5]-dX[4] = X[5]-X[4] (at least when ignoring point scale factor corrections and varying convergence which are not inverted).
- The purpose is for cases where the INC and AZI survey observables are lost, but an application needs it to load. Another case is inertial surveys, if they need to be loaded as if they are MWD surveys.
- This should not be an elaborate API because this should normally not happen, and if it does, the trajectory does not need to be perfectly reconstructed to the millimeter.
- This function can be used iteratively, i.e., to get "normal output" one can call convertTrajectory with
inputKind "dX_dY_dZ"
to get MD, INC and AZI, then use that withinputKind "MD_Incl_Azi"
, which response will be as normal with all output fields.
-
Add an options and handle InputKind
"dX_dY_dZ". Implement the formulas. -
Pass test: by roundtrip. See below for test case. First create an input survey with MD,INC,AZI. Then compute the trajectory using AzimuthalEquidistant (forward min. curvature). - Then run the new implementation with MD_X_Y_Z as input and compute the AZI and INC at the stations. The results should match the original input (except AZI is undetermined for INC=0).
- Then compute the dX,dY,dZ at each station and use that as input for the new implementation with "MD_dX_dY_dZ".
-
Document in swagger. - "inputKind": The kind of input; one of MD_Incl_Azim (default), MD_X_Y_Z, MD_dX_dY_dZ, X_Y_Z, dX_dY_dZ. MD stands for measured depth; MD_X_Y_Z/X_Y_Z stand for absolute coordinates in the reference CRS, MD_dX_dY_dZ/dX_dY_dZ stand for deviations relative to the reference point.
- This needs to include also "MD_Incl" - to be checked but it should in v4 already.
- Add an explanation at the end: "For survey MD, Incl, Azi input, minimum curvature is used to calculate the local deviations and absolute coordinates. For MD_dX,dY,dZ, the inverse minimum curvature is first applied to compute Inc and Azi, which then are used as input to compute the trajectory."
- "inputKind": The kind of input; one of MD_Incl_Azim (default), MD_X_Y_Z, MD_dX_dY_dZ, X_Y_Z, dX_dY_dZ. MD stands for measured depth; MD_X_Y_Z/X_Y_Z stand for absolute coordinates in the reference CRS, MD_dX_dY_dZ/dX_dY_dZ stand for deviations relative to the reference point.
-
Document in tutorial with an example. -
Bert to check tutorial and swagger. We need to add other things too that may not be there, like: - overview of input and output units.
- interpolate option.
- GNL method.
Basic data flow/algorithm steps (this text ought to be copied to a comment block in the code base at start of new function)
- Given an original request with
InputKind
"dX_dY_dZ" and values for dx,dy,dz inputStations, units given by unitXY and unitZ, as well as all other input parameters such as CRS, AZIREF, method and interpolate, - First compute MD, INC and AZI using the inverse min. curvature equations.
- This only requires the InputStation to invert as per doc and spreadsheet (i.e., agnostic to CRS, AZIREF, and method etc.)
- dx,dy,dz should be normalized to SI (to meter) temporarily to compute INC and AZI. The MDs might have to be denormalized (or copied from original) for next step.
- Create a dummy request with
InputKind
"MD_Incl_Azim" and values for md,inc,azi inputStations (as computed in step 2).
- unitXY : should be removed from the dummy if trajectoryCRS is projected.
- unitMD : (is an optional parameter defaulting to unitZ) - MDs should be converted to unitZ unless unitMD is given by user in request, then convert MDs to that unit.
- Note, if in step 1 the dx,dy were TN then the computed AZI is TN referenced.
- Run convertTrajectory with the dummy request. This will output the "normal" response incl. path, AZI_TN, AZI_GN, etc. in response.stations. It would even interpolate if user had that in the original request.
"dX_dY_dZ" Request input parsing/exception handling
For step 1/2 (compute INC and AZI using inverse min curvature):
- "inputStations".[i]: required
- "dx": required
- "dy": required
- "dz": required
- (md, inc and azi should not be present on input for this method so check for that and return bad request with a message if they are on input)
- "unitXY": required (for the input dx,dy)
- "unitZ": required (for the input dz)
- "unitMD": optional (for the output MDs; defaults to unitZ if i recall correctly- do the same as normal parsing)
For step 3/4 (dummy call after INC and AZI are computed):
- "trajectoryCRS": required (for dummy call in step 3; at that point unitxy comes from projCRS as normal).
- "referencePoint": required
- "azimuthReference": required
- "method": required
- "interpolate": optional (not expected).
Example input request
{
"trajectoryCRS": "osdu:reference-data--CoordinateReferenceSystem:BoundProjected:EPSG::23032_EPSG::1612:",
"azimuthReference": "GN",
"unitXY": "osdu:reference-data--UnitOfMeasure:m:",
"unitZ": "osdu:reference-data--UnitOfMeasure:m:",
"unitMD": "osdu:reference-data--UnitOfMeasure:ft:",
"referencePoint": {
"x": 400000,
"y": 6500000,
"z": 100
},
"inputKind": "dX_dY_dZ",
"inputStations": [
{ "dx": 0, "dy": 0, "dz": 0 },
{ "dx": 0.00, "dy": 0, "dz": 3137.0 },
{ "dx": 0.04, "dy": -0.09, "dz": 3150 },
{ "dx": 0.10, "dy": -0.34, "dz": 3175 },
{ "dx": -0.56, "dy": -0.42, "dz": 3199.99 },
{ "dx": -2.76, "dy": -0.33, "dz": 3224.88 },
{ "dx": -6.31, "dy": -0.41, "dz": 3249.63 },
{ "dx": -10.31, "dy": -0.73, "dz": 3274.31 },
{ "dx": -14.30, "dy": -1.05, "dz": 3298.98 }
],
"method": "AzimuthalEquidistant"
"interpolate": false,
}
Step 3/4 dummy request
The dx,dy,dz above should after inverse min curvature lead to a dummy request using the computed MD,INC,AZI (ROUND To 3DP) as follows:
{
"trajectoryCRS": "osdu:reference-data--CoordinateReferenceSystem:BoundProjected:EPSG::23032_EPSG::1612:",
"azimuthReference": "GN",
"unitXY": "osdu:reference-data--UnitOfMeasure:m:",
"unitZ": "osdu:reference-data--UnitOfMeasure:m:",
"unitMD": "osdu:reference-data--UnitOfMeasure:ft:",
"referencePoint": {
"x": 400000,
"y": 6500000,
"z": 100
},
"inputKind": "MD_Incl_Azim",
"inputStations": [
{ "md": 0, "inclination": 0, "azimuth": 0 }, // round these all to 3 dp
{ "md": 10291.995, "inclination": 0, "azimuth": 55.47 }, // round these all to 3 dp
{ "md": 10334.646, "inclination": 0.83, "azimuth": 155.47 }, // ..
{ "md": 10416.667, "inclination": 0.43, "azimuth": 188.78 },
{ "md": 10498.688, "inclination": 2.98, "azimuth": 271.4 },
{ "md": 10580.709, "inclination": 7.12, "azimuth": 272.82 },
{ "md": 10662.730, "inclination": 9.23, "azimuth": 265.43 },
{ "md": 10744.751, "inclination": 9.23, "azimuth": 265.43 },
{ "md": 10826.772, "inclination": 9.23, "azimuth": 265.43 }
],
"method": "AzimuthalEquidistant"
"interpolate": false,
}
Where I converted MD in meters to ft as follows:
m | ft |
---|---|
0 | 0 |
3137 | 10291.99475 |
3150 | 10334.64567 |
3175 | 10416.66667 |
3200 | 10498.68766 |
3225 | 10580.70866 |
3250 | 10662.72966 |
3275 | 10744.75066 |
3300 | 10826.77165 |
Step 3/4 dummy response
(as normal).
- But in OperationsApplied make sure to put in pertinent remarks.
Math and test data are described in section 2.4 of "OSDU_wellbore_calculations.docx" which is linked in the [CRS Convert tutorial] (https://community.opengroup.org/osdu/platform/system/reference/crs-conversion-service/-/blob/master/docs/v3/tutorial/CRS_Convert_Service_howto.md#5-computing-a-wellbore-trajectory-from-directional-survey-data).