Add a borehole grid: vertical profiles at a set of sites - #5
Open
lispandfound wants to merge 1 commit into
Open
lispandfound wants to merge 1 commit into
lispandfound wants to merge 1 commit into
Conversation
lispandfound
added this pull request to stack #6
September 10, 2026 06:56
Benchmark for b144bfcClick to view benchmark
|
lispandfound
force-pushed
the
borehole-grid
branch
from
September 10, 2026 07:04
028902e to
9248b91
Compare
Benchmark for 60572e7Click to view benchmark
|
lispandfound
force-pushed
the
borehole-grid
branch
from
September 10, 2026 07:10
9248b91 to
094414a
Compare
Benchmark for bd31a03Click to view benchmark
|
Comparing a velocity model against a borehole log, or handing a 1-D profile to a site-response code, only needs one column of samples per station. The existing grids all fill a rotated box, so getting there has meant generating a whole volume and slicing it, or hand-rolling a Grid outside the config system entirely (which the README talked people through). `grid.type = "borehole"` extracts one column per site, running from the topography down to a fixed depth at a fixed vertical resolution, so profiles from different sites line up sample for sample. The grid is shaped `(len(sites), 1, nk)`: the singleton `j` axis keeps the `(i, j, k)` contract every layer relies on, so the whole layer chain — coastline, offshore, Ely, clamp, query — works unchanged. Sites come from an inline list, or from a CSV or Parquet file. They are given in a global CRS (WGS84 by default, `sites_crs` to override) and mapped into the grid CRS. Longitude and latitude place a site and the config reserves nothing else. Every other key in a `[[grid.sites]]` block, and every other column of a site file, becomes a coordinate on the `i` axis under the name the caller gave it, so a station code, a network or a driller's reference reaches the output. A label keeps the type it was written with. Mashumaro folds the extra keys in a `__pre_deserialize__` hook, so the longitude and latitude validators still run and a config file needn't spell the mapping out. `keep_extra_columns = false` drops the labels and keeps only the spatial coordinates. Two things that has to guard. A coordinate shadows a variable or attribute of the same name, so a label called `name` would turn `grid.name` from the grid's name into a DataArray. `RESERVED_COORDINATES` is derived from `GridSchema`'s own fields, plus the logical index, the coastline coordinate and the components that share that index, so it keeps up if the schema changes. Sites also have to agree on which labels they carry, since a missing key is nearly always a typo and the alternative is a column of nulls. A borehole grid is a bag of independent columns, so there is nothing for a model origin to be the origin of. `Model` therefore splits: `Projection` holds the CRS and its cached transformers, and `Model` extends it with the origin and azimuth the extent-based grids lay themselves out against. A borehole config takes `[grid.projection]` and no origin at all; the Grid attributes that record one are derived from the sites. `examples/borehole.toml` runs four profiles over the `just synthetic` dataset, two of them inside a basin, and the tests build their columns on the synthetic topography so the expected elevations follow from closed form. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
lispandfound
force-pushed
the
borehole-grid
branch
from
September 10, 2026 10:36
094414a to
a483fd5
Compare
lispandfound
removed this pull request from stack #6
September 10, 2026 10:39
lispandfound
added this pull request to stack #9
September 10, 2026 10:39
Benchmark for d405d59Click to view benchmark
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Comparing a velocity model against a borehole log, or handing a 1-D profile to
a site-response code, only needs one column of samples per station. The
existing grids all fill a rotated box, so getting there has meant generating a
whole volume and slicing it, or hand-rolling a Grid outside the config system
entirely (which the README talked people through).
grid.type = "borehole"extracts one column per site, running from thetopography down to a fixed depth at a fixed vertical resolution, so profiles
from different sites line up sample for sample. The grid is shaped
(len(sites), 1, nk): the singletonjaxis keeps the(i, j, k)contractevery layer relies on, so the whole layer chain — coastline, offshore, Ely,
clamp, query — works unchanged.
No model origin
A borehole grid is a bag of independent columns, so there is nothing for a
model origin to be the origin of.
Modeltherefore splits:Projectionholdsthe CRS and its cached transformers, and
Modelextends it with the originand azimuth the extent-based grids lay themselves out against. A borehole
config takes
[grid.projection]and no origin at all; the Grid attributesthat record one are derived from the sites.
Longitude and latitude place a site; nothing else is reserved
Sites come from an inline list, or from a CSV or Parquet file, in a global CRS
(WGS84 by default,
sites_crsto override).Every other key in a
[[grid.sites]]block, and every other column of a sitefile, becomes a coordinate on the
iaxis under the name the caller gave it,so a station code, a network or a driller's reference reaches the output:
A label keeps the type it was written with, so a numeric column arrives
numeric. Mashumaro folds the extra keys in a
__pre_deserialize__hook, sothe longitude and latitude validators still run and a config file needn't
spell the
labelsmapping out.keep_extra_columns = falsedrops the labelsand keeps only the spatial coordinates.
Two things that has to guard.
A label can't shadow a grid name. A coordinate shadows a variable or
attribute of the same name, so a label called
namewould turngrid.namefrom the grid's name into a
DataArrayand break{grid.name: grid}in thebuilder. I confirmed that before relying on it:
RESERVED_COORDINATESinnzcvm.grids.gridis derived fromGridSchema'sown fields, plus the logical index, the coastline coordinate and the
components that share that index, so it keeps up if the schema changes.
Sites have to agree on their labels. A missing key is nearly always a
typo, and the alternative is a column of nulls.
keep_extra_columns = falseskips both checks, since there is nothing left to collide or disagree.
Testing
Vs down each 600 m column of
examples/borehole.toml, sampled every 100 m:gullybasinterracebasinGULL stays in the basin's 1-D profile the whole way down; TERR breaks out of
its shallower basin into the tomography at 500 m; RIDG starts on the Ely taper
and drops straight into tomography; SEAB follows the offshore profile.
tests/test_borehole.pycovers theProjection/Modelsplit, site loadingfrom inline lists, CSV and Parquet, the labels (inline keys, file columns, a
numeric label, the opt-out, and both error paths), the grid geometry against
the analytic topography, and a round trip through
map_blocksand the Zarrwriter to confirm the labels survive.
🤖 Generated with Claude Code
Stack created with GitHub Stacks CLI • Give Feedback 💬