Traverse Demo#
Demonstration of Traverse services in Dips Python API.
This script demonstrates ITraverseServices methods including: - AddTraverse: Create a new traverse with discontinuity data - GetTraverseList: List all traverses - DeleteTraverse: Remove a traverse
Code Snippet: TraverseDemo.py#
"""
Demonstration of Traverse services in Dips Python API.
This script demonstrates ITraverseServices methods including:
- AddTraverse: Create a new traverse with discontinuity data
- GetTraverseList: List all traverses
- DeleteTraverse: Remove a traverse
"""
import math
import random
from dips import DipsApp
from dips import DipsAPI_pb2
from dips import BuiltInDataFormatters
import dips.OrientationDataSetVal
import dips.DiscontinuityDataVal
import dips.SurveyDataVal
import dips.TrendPlungeVal
import dips.AngleDataVal
import dips.CustomColumnCollectionVal
import dips.FullDataFormatVal
import dips.CustomRowRawDataVal
# =============================================================================
# TRAVERSE CREATION HELPERS
# =============================================================================
def create_spot_mapping_traverse(model, name: str, num_poles: int):
"""Create a spot mapping traverse with random poles."""
ods = model.GetDefaultOrientationDataSet()
ods.name = name
ods.orientation_data_type = DipsAPI_pb2.eOrientationDataType.SpotMapping
ods.discontinuity_orientation_convention = DipsAPI_pb2.eOrientationConvention.TrendPlungeOrientation
# Set units
ods.traverse_elevation_unit = BuiltInDataFormatters.LengthMeterDataFormatter
ods.traverse_xyz_unit = BuiltInDataFormatters.LengthMeterDataFormatter
ods.discontinuity_xyz_unit = BuiltInDataFormatters.LengthMeterDataFormatter
ods.discontinuity_persistence_unit = BuiltInDataFormatters.LengthMeterDataFormatter
# Generate random poles
for _ in range(num_poles):
discontinuity = dips.DiscontinuityDataVal.DiscontinuityDataVal()
discontinuity.orientation1.angle_radians = math.radians(random.uniform(0, 360))
discontinuity.orientation2.angle_radians = math.radians(random.uniform(0, 90))
discontinuity.quantity = 1.0
ods.discontinuity_list.append(discontinuity)
return ods
def create_linear_scanline_traverse(model, name: str, trend: float, plunge: float, depth: float, num_discontinuities: int):
"""Create a linear scanline traverse."""
ods = model.GetDefaultOrientationDataSet()
ods.name = name
ods.orientation_convention = DipsAPI_pb2.eOrientationConvention.TrendPlungeOrientation
ods.orientation_data_type = DipsAPI_pb2.eOrientationDataType.LinearScanline
ods.discontinuity_orientation_convention = DipsAPI_pb2.eOrientationConvention.TrendPlungeOrientation
# Set traverse orientation
ods.orient1.angle_radians = math.radians(trend)
ods.orient2.angle_radians = math.radians(plunge)
ods.depth = depth
# Set collar location
ods.local_position.x = 0
ods.local_position.y = 0
ods.local_position.z = 0
# Set units
ods.traverse_elevation_unit = BuiltInDataFormatters.LengthMeterDataFormatter
ods.traverse_xyz_unit = BuiltInDataFormatters.LengthMeterDataFormatter
ods.traverse_depth_unit = BuiltInDataFormatters.LengthMeterDataFormatter
ods.discontinuity_distance_unit = BuiltInDataFormatters.LengthMeterDataFormatter
ods.discontinuity_xyz_unit = BuiltInDataFormatters.LengthMeterDataFormatter
ods.discontinuity_persistence_unit = BuiltInDataFormatters.LengthMeterDataFormatter
# Generate discontinuities along the traverse
cumulative_distance = 0.0
for _ in range(num_discontinuities):
discontinuity = dips.DiscontinuityDataVal.DiscontinuityDataVal()
discontinuity.orientation1.angle_radians = math.radians(random.uniform(0, 360))
discontinuity.orientation2.angle_radians = math.radians(random.uniform(0, 90))
discontinuity.quantity = random.uniform(0.5, 2.0)
cumulative_distance += random.uniform(0.5, 3.0)
discontinuity.distance = cumulative_distance
ods.discontinuity_list.append(discontinuity)
return ods
def create_curved_borehole_traverse(model, name: str, collar_trend: float, collar_plunge: float,
depth: float, num_discontinuities: int):
"""Create a curved borehole traverse with survey data.
Survey data defines how the borehole curves along its length.
Each survey point specifies the orientation at a given distance down the hole.
"""
ods = model.GetDefaultOrientationDataSet()
ods.name = name
ods.orientation_convention = DipsAPI_pb2.eOrientationConvention.TrendPlungeOrientation
ods.orientation_data_type = DipsAPI_pb2.eOrientationDataType.CurvedBoreholeOrientedCore
ods.orient1.angle_radians = math.radians(180)
ods.discontinuity_orientation_convention = DipsAPI_pb2.eOrientationConvention.AlphaBetaOrientation
# Set collar location
ods.local_position.x = 0
ods.local_position.y = 0
ods.local_position.z = 0
# Set units
ods.traverse_elevation_unit = BuiltInDataFormatters.LengthMeterDataFormatter
ods.traverse_xyz_unit = BuiltInDataFormatters.LengthMeterDataFormatter
ods.survey_distance_unit = BuiltInDataFormatters.LengthMeterDataFormatter
ods.discontinuity_distance_unit = BuiltInDataFormatters.LengthMeterDataFormatter
ods.discontinuity_xyz_unit = BuiltInDataFormatters.LengthMeterDataFormatter
ods.discontinuity_persistence_unit = BuiltInDataFormatters.LengthMeterDataFormatter
# Create survey data points that define how the borehole curves
# The borehole starts at collar_trend/collar_plunge and gradually changes
num_surveys = 5
survey_interval = depth / num_surveys
current_trend = collar_trend
current_plunge = collar_plunge
for i in range(num_surveys + 1):
survey = dips.SurveyDataVal.SurveyDataVal()
survey.distance = i * survey_interval
survey.orientation = create_trend_plunge(current_trend, current_plunge)
ods.survey_list.append(survey)
# Gradually curve the borehole (simulate deviation)
current_trend += random.uniform(-5, 5) # Small trend deviation
current_plunge += random.uniform(0, 3) # Tends to steepen slightly
current_plunge = min(current_plunge, 90) # Cap at vertical
# Generate discontinuities along the traverse
cumulative_distance = 0.0
for _ in range(num_discontinuities):
discontinuity = dips.DiscontinuityDataVal.DiscontinuityDataVal()
discontinuity.orientation1.angle_radians = math.radians(random.uniform(0, 90))
discontinuity.orientation2.angle_radians = math.radians(random.uniform(0, 360))
discontinuity.quantity = random.uniform(0.5, 2.0)
cumulative_distance += random.uniform(1.0, 5.0)
if cumulative_distance > depth:
cumulative_distance = depth - 0.1
discontinuity.distance = cumulative_distance
ods.discontinuity_list.append(discontinuity)
return ods
def create_trend_plunge(trend_deg: float, plunge_deg: float):
"""Create a TrendPlunge from degrees."""
tp = dips.TrendPlungeVal.TrendPlungeVal()
tp.trend = dips.AngleDataVal.AngleDataVal()
tp.trend.angle_radians = math.radians(trend_deg)
tp.plunge = dips.AngleDataVal.AngleDataVal()
tp.plunge.angle_radians = math.radians(plunge_deg)
return tp
# =============================================================================
# TRAVERSE DEMONSTRATIONS
# =============================================================================
def demonstrate_add_spot_mapping_traverse(model):
"""Demonstrate adding a spot mapping traverse."""
print("\n" + "=" * 60)
print("ADD SPOT MAPPING TRAVERSE")
print("=" * 60)
try:
ods = create_spot_mapping_traverse(model, "Spot Mapping Demo", 20)
result = model.AddTraverse(ods)
print(f" ✓ AddTraverse: '{ods.name}'")
print(f" Type: Spot Mapping")
print(f" Discontinuities: {len(ods.discontinuity_list)}")
return result
except Exception as e:
print(f" ✗ AddTraverse: {e}")
return None
def demonstrate_add_linear_scanline_traverse(model):
"""Demonstrate adding a linear scanline traverse."""
print("\n" + "=" * 60)
print("ADD LINEAR SCANLINE TRAVERSE")
print("=" * 60)
try:
ods = create_linear_scanline_traverse(model, "Linear Scanline Demo", 45, 90, 50.0, 25)
result = model.AddTraverse(ods)
print(f" ✓ AddTraverse: '{ods.name}'")
print(f" Type: Linear Scanline")
print(f" Orientation: Trend=45°, Plunge=90°")
print(f" Depth: 50m")
print(f" Discontinuities: {len(ods.discontinuity_list)}")
return result
except Exception as e:
print(f" ✗ AddTraverse: {e}")
return None
def demonstrate_add_curved_borehole_traverse(model):
"""Demonstrate adding a curved borehole traverse with survey data."""
print("\n" + "=" * 60)
print("ADD CURVED BOREHOLE TRAVERSE (with Survey Data)")
print("=" * 60)
try:
ods = create_curved_borehole_traverse(
model,
name="Curved Borehole Demo",
collar_trend=120,
collar_plunge=70,
depth=100.0,
num_discontinuities=30
)
result = model.AddTraverse(ods)
print(f" ✓ AddTraverse: '{ods.name}'")
print(f" Type: Curved Borehole (Survey Data)")
print(f" Collar Orientation: Trend=120°, Plunge=70°")
print(f" Depth: 100m")
print(f" Survey Points: {len(ods.survey_list)}")
print(f" Discontinuities: {len(ods.discontinuity_list)}")
return result
except Exception as e:
print(f" ✗ AddTraverse: {e}")
return None
def demonstrate_get_traverse_list(model):
"""Demonstrate listing all traverses."""
print("\n" + "=" * 60)
print("GET TRAVERSE LIST")
print("=" * 60)
try:
traverses = model.GetTraverseList()
print(f" ✓ GetTraverseList: {len(traverses)} traverse(s) found")
for i, traverse_ref in enumerate(traverses):
traverse_value = traverse_ref.GetValue()
data_type = DipsAPI_pb2.eOrientationDataType.Name(traverse_value.orientation_data_type)
print(f" [{i+1}] Name: '{traverse_value.name}'")
print(f" Type: {data_type}")
print(f" Discontinuities: {len(traverse_value.discontinuity_list)}")
return traverses
except Exception as e:
print(f" ✗ GetTraverseList: {e}")
return []
def demonstrate_delete_traverse(model, traverse_ref):
"""Demonstrate deleting a traverse."""
print("\n" + "=" * 60)
print("DELETE TRAVERSE")
print("=" * 60)
if traverse_ref is None:
print(" - DeleteTraverse: No traverse to delete")
return
try:
traverse_value = traverse_ref.GetValue()
traverse_name = traverse_value.name
model.DeleteTraverse(traverse_ref)
print(f" ✓ DeleteTraverse: '{traverse_name}'")
except Exception as e:
print(f" ✗ DeleteTraverse: {e}")
def demonstrate_multiple_traverses(model):
"""Demonstrate creating multiple traverses."""
print("\n" + "=" * 60)
print("MULTIPLE TRAVERSE EXAMPLES")
print("=" * 60)
created_traverses = []
# Create spot mapping traverse
try:
ods = create_spot_mapping_traverse(model, "Outcrop Survey", 30)
result = model.AddTraverse(ods)
created_traverses.append(result)
print(f" ✓ Created: 'Outcrop Survey' (Spot Mapping, 30 poles)")
except Exception as e:
print(f" ✗ Failed: {e}")
# Create linear scanline traverses at different orientations
scanlines = [
("Borehole BH-1", 0, 90, 100.0, 40), # Vertical borehole
("Scanline SL-1", 90, 0, 25.0, 15), # Horizontal E-W
("Scanline SL-2", 0, 0, 30.0, 20), # Horizontal N-S
]
for name, trend, plunge, depth, count in scanlines:
try:
ods = create_linear_scanline_traverse(model, name, trend, plunge, depth, count)
result = model.AddTraverse(ods)
created_traverses.append(result)
print(f" ✓ Created: '{name}' (Linear, {count} discontinuities)")
except Exception as e:
print(f" ✗ Failed to create '{name}': {e}")
# Create curved borehole traverses with survey data
curved_boreholes = [
("Curved BH-1", 45, 75, 150.0, 50), # NE-trending, steep
("Curved BH-2", 225, 60, 120.0, 35), # SW-trending, moderately steep
]
for name, trend, plunge, depth, count in curved_boreholes:
try:
ods = create_curved_borehole_traverse(model, name, trend, plunge, depth, count)
result = model.AddTraverse(ods)
created_traverses.append(result)
print(f" ✓ Created: '{name}' (Curved, {len(ods.survey_list)} surveys, {count} discontinuities)")
except Exception as e:
print(f" ✗ Failed to create '{name}': {e}")
return created_traverses
def demonstrate_cleanup(model, traverses_to_delete):
"""Clean up created traverses."""
print("\n" + "=" * 60)
print("CLEANUP")
print("=" * 60)
for traverse_ref in traverses_to_delete:
try:
traverse_value = traverse_ref.GetValue()
model.DeleteTraverse(traverse_ref)
print(f" ✓ Deleted: '{traverse_value.name}'")
except Exception as e:
print(f" ✗ Delete failed: {e}")
# =============================================================================
# MAIN
# =============================================================================
def main():
"""Main demonstration function."""
print("=" * 60)
print("Dips API - Traverse Services Demo")
print("=" * 60)
# Connect to Dips
print("\nConnecting to Dips application...")
try:
app = DipsApp.LaunchApp(62535)
print("✓ Connected to Dips")
except Exception as e:
print(f"✗ Failed to connect: {e}")
print("Make sure Dips is running with scripting enabled on port 62535")
return
model = app.GetModel()
# Show initial state
print("\n" + "-" * 60)
print("INITIAL STATE")
print("-" * 60)
demonstrate_get_traverse_list(model)
# Add spot mapping traverse
spot_traverse = demonstrate_add_spot_mapping_traverse(model)
# Add linear scanline traverse
linear_traverse = demonstrate_add_linear_scanline_traverse(model)
# Add curved borehole traverse with survey data
curved_traverse = demonstrate_add_curved_borehole_traverse(model)
# List traverses again
demonstrate_get_traverse_list(model)
# Delete the traverses
demonstrate_delete_traverse(model, spot_traverse)
demonstrate_delete_traverse(model, linear_traverse)
demonstrate_delete_traverse(model, curved_traverse)
# Create multiple traverses
created_traverses = demonstrate_multiple_traverses(model)
# List all traverses
demonstrate_get_traverse_list(model)
# Cleanup (commented out to keep traverses visible)
# demonstrate_cleanup(model, created_traverses)
# Show final state
print("\n" + "-" * 60)
print("FINAL STATE")
print("-" * 60)
demonstrate_get_traverse_list(model)
# Show the application
app.Show()
# Summary
print("\n" + "=" * 60)
print("DEMONSTRATION COMPLETE")
print("=" * 60)
print("""
Traverse services demonstrated (3 methods):
- AddTraverse: Create a new traverse with discontinuity data
- GetTraverseList: List all traverses in the project
- DeleteTraverse: Remove a traverse from the project
Traverse Types (eOrientationDataType):
- SpotMapping: Scattered point observations
- LinearScanline: Linear measurement line (straight borehole, scanline)
- PlanarMapping: Planar surface mapping
- LinearBoreholeOrientedCore: Straight borehole with oriented core
- LinearBoreholeTeleviewer: Straight borehole with televiewer
- CurvedBoreholeOrientedCore: Curved borehole with oriented core (uses survey data)
- CurvedBoreholeTeleviewer: Curved borehole with televiewer (uses survey data)
- Clinorule: Clinorule measurements
Traverse Properties:
- name: Traverse identifier
- orientation_data_type: Type of traverse
- orientation_convention: How orientations are specified
- discontinuity_list: List of discontinuity measurements
- Various unit settings for measurements
""")
if __name__ == "__main__":
main()