Skip to content
This repository was archived by the owner on Sep 21, 2026. It is now read-only.

fix: InterpolatedStructure contact/dip selection and StructuralPoint strike wraparound - #248

Closed
lachlangrose wants to merge 1 commit into
masterfrom
fix/interpolated-structure-and-strike-wraparound
Closed

lachlangrose wants to merge 1 commit into
masterfrom
fix/interpolated-structure-and-strike-wraparound

Conversation

@lachlangrose

Copy link
Copy Markdown
Member

Summary

Three correctness bugs in the two most-used thickness calculators (InterpolatedStructure is the project default; StructuralPoint is the other user-facing option):

  • InterpolatedStructure picked the wrong basal contact segment. shapely.shortest_line(point, top_contact_geometry) broadcasts across the list of top-contact geometries and returns one candidate line per list entry; the code always took short_line[0]. Whenever a basal contact is split into more than one feature (common across faults or map-sheet edges), the thickness estimate silently used an arbitrary segment instead of the nearest one. Now the candidate with the minimum length is selected.
  • InterpolatedStructure sampled dip from the wrong unit. The measured line spans stratigraphic_order[i + 1] (the unit whose thickness is being computed), but dip was pulled from interpolated points in stratigraphic_order[i] (the overlying unit). Dip is now sampled from the unit actually being measured.
  • StructuralPoint rejected valid strike matches near due north. The strike-allowance check compared strike1/strike2 against a plain numeric range (strike - allowance, strike + allowance). Strike is a compass bearing that wraps at 360°, so e.g. a measured strike of 5° and a contact strike of 350° (15° apart) failed the check even though they're well within the 30° default tolerance. Replaced with an angular-difference comparison that handles wraparound.

Test plan

  • pytest tests/thickness — all 3 existing suites (InterpolatedStructure, StructuralPoint, ThicknessCalculatorAlpha) pass unchanged
  • pytest tests/project/test_thickness_calculations.py passes unchanged

…alPoint strike wraparound

InterpolatedStructure:
- shapely.shortest_line(point, top_contact_geometry) broadcasts over the
  list of top-contact geometries and returns one line per entry. The code
  took short_line[0] unconditionally, so whenever a basal contact was split
  into more than one feature (common across faults or map-sheet edges) the
  thickness estimate used an arbitrary segment instead of the nearest one.
  Now the candidate with the smallest length is selected explicitly.
- Dip was sampled from stratigraphic_order[i] (the overlying unit) while the
  measured line spans stratigraphic_order[i + 1] (the unit whose thickness
  is being computed). Dip is now sampled from the same unit being measured.

StructuralPoint:
- The strike-allowance check compared strike1/strike2 against a plain
  numeric range (strike - allowance, strike + allowance). Strike is a
  compass bearing that wraps at 360 degrees, so measurements near due
  north (e.g. strike=5, contact strike=350) were incorrectly rejected even
  though they are well within tolerance. Replaced with an angular
  difference check that handles the wraparound correctly.
@lachlangrose

Copy link
Copy Markdown
Member Author

Closing — map2loop now lives in packages/map2loop of Loop3D/LoopStructural, and this repository is being archived. Ported to Loop3D/LoopStructural#327

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant