geoml.transform

What distance means before a kernel sees it: the ranges, the anisotropy ellipsoid, and the projections. Chained transforms compose, so a periodic direction and an anisotropic one can sit in the same model.

Isotropic and anisotropic

class geoml.transform.Identity[source]

Bases: _Transform

The identity transformation.

Hands the coordinates on as they are, so distances are measured in the data’s own units. What an input uses when it is given no transform.

class geoml.transform.Isotropic(r=1.0)[source]

Bases: _Transform

Isotropic range

__init__(r=1.0)[source]

Initializer for Isotropic.

Parameters:

r (double) – The range, in [0.1, 10000]. The input the transform is given replaces these bounds with ones read off its inducing points’ extent.

set_limits(data)[source]
class geoml.transform.Anisotropy2D(maxrange=1.0, minrange_fct=1, azimuth=0)[source]

Bases: _Ellipsoidal

Anisotropy in two dimensions

__init__(maxrange=1.0, minrange_fct=1, azimuth=0)[source]

Builds an anisotropy matrix, to be multiplied by a coordinate matrix from the right.

Parameters:
  • azimuth (double) – Defined clockwise from north, and is aligned with maxrange.

  • maxrange (double) – The maximum range, in [0.1, 10000]. The input the transform is given replaces these bounds with ones read off its inducing points’ extent.

  • minrange_fct (double) – The minimum range as a multiple of maxrange, in [0.05, 1].

refresh()[source]
set_limits(data)[source]
class geoml.transform.Anisotropy2DMath(range_x=1.0, range_y=1.0, theta=0)[source]

Bases: _Ellipsoidal

Anisotropy in two dimensions

__init__(range_x=1.0, range_y=1.0, theta=0)[source]

Anisotropy matrix in mathematical parametrization.

Parameters:
  • range_x (double) – The ellipsoid semi-length in each direction. Must be positive.

  • range_y (double) – The ellipsoid semi-length in each direction. Must be positive.

  • theta (double) – The rotation angle in degrees.

refresh()[source]
set_limits(data)[source]
class geoml.transform.Anisotropy2DDynamic(n_directions=9)[source]

Bases: _Ellipsoidal

An anisotropy in two dimensions, learnt as a blend of fixed directions.

Holds n_directions ellipses at evenly spaced angles, their ranges trained and their angles fixed, and trains a weight for each; the ellipse used is their weighted sum. Where Anisotropy2D trains one angle, which gradient descent can leave stuck in a local optimum, this spreads the choice over the fixed angles.

Parameters:

n_directions (int) – How many fixed directions to blend.

refresh()[source]
set_limits(data)[source]
class geoml.transform.Anisotropy3D(maxrange=1.0, midrange_fct=1, minrange_fct=1, azimuth=0, dip=0, rake=0)[source]

Bases: _Ellipsoidal

Anisotropy in two dimensions

__init__(maxrange=1.0, midrange_fct=1, minrange_fct=1, azimuth=0, dip=0, rake=0)[source]

Builds an anisotropy matrix, to be multiplied by a coordinate matrix from the right.

Parameters:
  • maxrange (double) – The maximum range, in [0.1, 10000]. The input the transform is given replaces these bounds with ones read off its inducing points’ extent.

  • midrange_fct (double) – The middle range as a multiple of maxrange, in [0.05, 1].

  • minrange_fct (double) – The minimum range as a multiple of midrange, in [0.01, 1].

  • azimuth (double) – Defined clockwise from north, and is aligned with maxrange.

  • dip (double) – Dip angle, from 0 to 90 degrees.

  • rake (double) – Rake angle, from -90 to 90 degrees.

refresh()[source]
set_limits(data)[source]
class geoml.transform.Anisotropy3DMath(range_x=1.0, range_y=1.0, range_z=1.0, theta_x=0, theta_y=0, theta_z=0)[source]

Bases: _Ellipsoidal

Anisotropy in two dimensions

__init__(range_x=1.0, range_y=1.0, range_z=1.0, theta_x=0, theta_y=0, theta_z=0)[source]

Anisotropy matrix in mathematical parametrization.

Parameters:
  • range_x (double) – The ellipsoid semi-length in each direction. Must be positive.

  • range_y (double) – The ellipsoid semi-length in each direction. Must be positive.

  • range_z (double) – The ellipsoid semi-length in each direction. Must be positive.

  • theta_x (double) – The rotation angles in degrees.

  • theta_y (double) – The rotation angles in degrees.

  • theta_z (double) – The rotation angles in degrees.

refresh()[source]
set_limits(data)[source]
class geoml.transform.Anisotropy3DDynamic(n_directions_per_axis=3)[source]

Bases: _Ellipsoidal

An anisotropy in three dimensions, learnt as a blend of fixed orientations.

Holds one ellipsoid per combination of n_directions_per_axis fixed angles about each axis, their ranges trained and their angles fixed, and trains a weight for each; the ellipsoid used is their weighted sum. The three-dimensional form of Anisotropy2DDynamic, with its cube of orientations.

Parameters:

n_directions_per_axis – How many fixed angles to take about each axis.

refresh()[source]
set_limits(data)[source]
class geoml.transform.ProjectionTo1D(n_dim)[source]

Bases: _Transform

Projection of high-dimensional data to a line.

__init__(n_dim)[source]

Initializer for ProjectionTo1D.

Parameters:

n_dim (int) – The number of dimensions. May be greater than 3 when used in conjunction with a space-expanding transform.

class geoml.transform.AnisotropyARD(n_dim)[source]

Bases: _Transform

Automatic Relevance Detection

__init__(n_dim)[source]

Initializer for Isotropic.

Parameters:

n_dim (int) – The number of dimensions.

set_limits(data)[source]
class geoml.transform.ChainedTransform(*transforms)[source]

Bases: _Transform

Chained transform.

This object allows multiple transforms to be called sequentially. Useful for complex transformations.

__init__(*transforms)[source]

Chained transform.

Parameters:

transforms – Transformes to chain.

property linear

Whether the transform is affine, its Jacobian constant.

set_limits(data)[source]
class geoml.transform.SelectVariables(index)[source]

Bases: _Transform

Variable selection.

Returns the specified columns of the input, discarding the others.

__init__(index)[source]

Variable selection.

Parameters:

index (list) – Indices of variables to select.

class geoml.transform.NormalizeWithBoundingBox(box)[source]

Bases: _Transform

Normalization with a bounding box.

Uses a BoundingBox object as guide to normalize the data. All columns will be contained in the [-3, 3] interval.

__init__(box)[source]

Normalization with a bounding box.

Parameters:

box – The bounding box to use as reference for normalization.

class geoml.transform.Periodic[source]

Bases: _Transform

Periodic transform.

Returns sines and cosines doubling the number of columns in the data. The periods can be specified by chaining an Anisotropy* transform with this one.

class geoml.transform.Concatenate(*transforms)[source]

Bases: ChainedTransform

Concatenation of transforms.

Consolidates a list of inputs into a single one.

set_limits(data)[source]
class geoml.transform.RandomProjections(n_dim, n_directions, seed=1234)[source]

Bases: _Transform

The coordinates projected onto fixed directions.

One output per direction: evenly spaced angles in two dimensions, random unit vectors in more, drawn from seed. Nothing is trained. A way to hand a kernel several one-dimensional views of the same space.

Parameters:
  • n_dim – The width of the coordinates taken in, at least 2.

  • n_directions – How many directions to project onto; the width given out.

  • seed – Seeds the directions in three dimensions and more.

class geoml.transform.BellFault2D(start, end)[source]

Bases: _Transform

Fault simulation.

__init__(start, end)[source]

Fault simulation.

Creates a discontinuity in space, returning an additional coordinate that can be used to artificially repel points on opposite sides of a line.

Parameters:
  • start (array-like) – Starting point of fault.

  • end (array-like) – Endpoint of fault.

static kernelize(x)[source]
class geoml.transform.ImplicitFault(points, normals=None, basis='cubic', reach=None, mode='step', k=12)[source]

Bases: _ImplicitSurface

A fault fitted from its observations, as one extra coordinate that repels points across it.

BellFault2D for any surface and any dimension: the field is fitted to the fault’s points and normals, and the coordinate returned is amp * sign(s) * g(|s|) * taper, opposite in sign on the two sides, so a kernel reading it beside the spatial coordinates sees points across the fault as far apart. mode=”step” is the fault-block indicator, ±amp on the two sides; mode=”decay” fades with distance from the fault over range as BellFault2D does. The jump is the point: a smooth ramp, however narrow, is what the kernel already sees in the coordinates. It is the kernel-space form of the fault drift of the potential-field method (Calcagno et al. 2008; de la Varga et al. 2019), not a new idea; it needs no fault topology, several of them simply concatenate. amp and range train.

Parameters:
  • points – The fault observations, (n, d).

  • normals – The gradient constraints, as HermiteRBF takes them: aligned with the points with NaN rows where there is none, a (locations, vectors) pair, or None to derive one per point toward the surface’s concavity (geoml.math.geometry.point_normals). One is enough.

  • basis – As in HermiteRBF.

  • reach – How far past the observations the feature persists; a quarter of their extent by default.

  • mode – “step” or “decay”.

  • k – Neighbours used to derive the normals.

Notes

Use it in a Concatenate beside the spatial transform, with the input node’s center=False (the default), since the surface is fitted in the coordinates the observations came in.

References

Calcagno, P., Chilès, J. P., Courrioux, G. and Guillen, A. (2008). Geological modelling from field data and geological knowledge, Part I. Physics of the Earth and Planetary Interiors 171, 147-157.

de la Varga, M., Schaaf, A. and Wellmann, F. (2019). GemPy 1.0: open-source stochastic geological modeling and inversion. Geoscientific Model Development 12, 1-32.

class geoml.transform.FaultDisplacement(points, normals=None, throw=0.0, strike_slip=0.0, basis='cubic', reach=None, width=None, drag=False, profile=None, flow_steps=4, k=12)[source]

Bases: _ImplicitSurface

A fault fitted from its observations, as the displacement that restores its hanging wall.

Returns x - H(s) * taper * slip: the side the normals point to, where the field is positive, is moved back by the slip, over the fault’s extent, so a sequence displaced by the fault becomes continuous again in the transformed coordinates and one kernel can read across it. H is a smooth step of width width about the surface. The slip is said in the fault’s own frame (Laurent et al. 2013): a throw along the up-dip direction and, in three dimensions, a strike_slip along the strike, both read at the point’s foot on the surface, so everything on one normal line slides together along the fault and the slip stays tangent, since a component along the normal is not what a fault does and is not identified by the data either. In two dimensions the fault has one tangent, the normal turned a quarter turn, and throw is along it. On a curved fault the restoration is not rigid – a hanging wall sliding on a curved surface bends – and it is exact on a plane. Both train; their sign says which way the hanging wall goes, so the normals’ orientation only fixes the convention. A translation, as the vector fields of Laurent et al. (2013) and Georgsen et al. (2012) reduce to over one envelope; the restoration ordering of several faults is FaultNetwork’s.

The move itself is fault-parallel flow: each point follows the level set of the field through it, by flow_steps midpoint steps, so material slides along a curved fault rather than stepping straight off it; flow_steps=0 is the straight step along the frame at the foot. With profile=”bell” the throw varies along the fault as displacement profiles do, largest at the centre and zero at the tip lines, over trainable extents along the fault’s mean axes.

Training note: the throw moves slowly at the default learning rate; the phased pattern, set_learning_rate(0.1) for a few hundred iterations, recovered a 20 m throw to within a metre on a synthetic layer with a continuous variable, where the default schedule left it at a tenth. With a categorical likelihood, or with several faults, it did not move off zero at all: throw_from_markers reads it off one horizon seen on both walls, models.search_throw chooses it among candidates on the bound, and set_width anneals the step from wide, where the bound is smooth in the throw, to sharp.

Parameters:
  • points – As in ImplicitFault.

  • normals – As in ImplicitFault.

  • basis – As in ImplicitFault.

  • reach – As in ImplicitFault.

  • k – As in ImplicitFault.

  • throw – The initial throw along the up-dip direction; zero by default.

  • strike_slip – The initial slip along the strike, three dimensions only; zero by default.

  • width – The step’s half-width about the surface; a hundredth of the observations’ extent by default.

  • drag – Whether the width trains, as the width of a drag zone.

  • profile – None for one throw over the fault, “bell” for a profile.

  • flow_steps – Midpoint steps of the fault-parallel flow; zero for the straight step.

References

Laurent, G., Caumon, G., Bouziat, A. and Jessell, M. (2013). A parametric method to model 3D displacements around faults with volumetric vector fields. Tectonophysics 590, 83-93.

Georgsen, F., Røe, P., Syversveen, A. R. and Lia, O. (2012). Fault displacement modelling using 3D vector fields. Computational Geosciences 16, 247-259.

property width

The step’s half-width about the surface.

set_width(width)[source]

Sets the step’s half-width, for annealing it between training phases: wide, the bound is smooth in the throw and gradient descent finds it from afar; narrow, the fault is sharp.

throw_from_markers(hanging, footwall, iterations=3)[source]

Sets the throw from one horizon seen on both walls.

What a geologist measures: the same marker on the hanging wall and on the footwall, offset by the fault. The footwall markers are fitted as an implicit surface; the throw is the one whose restoration brings the hanging-wall markers onto that surface, by a few Gauss-Newton steps on the surface’s field. Needs no bound, so it serves as the start search_throw and training refine, and it reads the profile’s peak when there is one.

Parameters:
  • hanging – Marker points on the side the restoration moves, (m, d).

  • footwall – Marker points on the other side, (n, d).

  • iterations – Gauss-Newton steps.

Returns:

float – The throw set.

class geoml.transform.FaultNetwork(faults, abutting=())[source]

Bases: _Transform

Several faults restored in age order, youngest first.

The youngest fault is undone with its surface as observed. Each older fault’s observations are then moved by the restorations of the younger faults that cut it, so its pieces become one surface again, and its field is refitted on those restored positions before its own slip is undone – inside the graph, since the slips train. This is the ordering of LoopStructural (Grose et al. 2021) and of the series of the potential-field method (Calcagno et al. 2008). A fault that stops against an older one, declared in abutting, neither displaces that fault’s observations nor acts beyond its surface: its displacement is confined to the declared side of the older fault as observed.

Parameters:
  • faults – FaultDisplacement objects, youngest first.

  • abutting – Triples (younger, older, side) of fault positions and +1 or -1: the younger fault stops against the older one and acts only on the older field’s positive or negative side.

References

Grose, L., Ailleres, L., Laurent, G. and Jessell, M. (2021). LoopStructural 1.0: time-aware geological modelling. Geoscientific Model Development 14, 3915-3937.

Calcagno, P., Chilès, J. P., Courrioux, G. and Guillen, A. (2008). Geological modelling from field data and geological knowledge, Part I. Physics of the Earth and Planetary Interiors 171, 147-157.

class geoml.transform.ImplicitFaultBlocks(faults, abutting=())[source]

Bases: _Transform

Several repulsions with their terminations: the fault-block partition as one extra coordinate per fault.

The repulsion’s twin of FaultNetwork, for ImplicitFault objects. A fault that ends on another is its zero set trimmed to one side of the other’s field, {s = 0} ∩ {side * s_j >= 0}, and its coordinate is the trimmed sign, amp * sign(s) * H(side * s_j) * taper, a product of steps – identically zero beyond the bounding fault instead of fading over a reach, so no coordinate jumps where no fault exists and two points in different fault blocks differ in at least one coordinate. In decay mode the distance to the trimmed surface, sqrt(s^2 + sum max(0, -side * s_j)^2), does the trimming smoothly. A chain of terminations composes as the product of its steps. Nothing is restored, so every field is read as observed, and the faults need no age order. The one artefact is at a junction: crossing the bounding fault next to the one that ends on it costs the ending fault’s amplitude on top of the bounding fault’s, since that coordinate drops to zero there.

Parameters:
  • faults – ImplicitFault objects, in any order.

  • abutting – Triples (stopping, bounding, side) of fault positions and +1 or -1: the first fault exists only on that side of the second’s field.

Angles given rather than fitted

The Math and Dynamic variants take the ellipsoid’s orientation from somewhere other than training — a structural measurement, or another node.

class geoml.transform.Anisotropy2DMath(range_x=1.0, range_y=1.0, theta=0)[source]

Bases: _Ellipsoidal

Anisotropy in two dimensions

__init__(range_x=1.0, range_y=1.0, theta=0)[source]

Anisotropy matrix in mathematical parametrization.

Parameters:
  • range_x (double) – The ellipsoid semi-length in each direction. Must be positive.

  • range_y (double) – The ellipsoid semi-length in each direction. Must be positive.

  • theta (double) – The rotation angle in degrees.

refresh()[source]
set_limits(data)[source]
class geoml.transform.Anisotropy2DDynamic(n_directions=9)[source]

Bases: _Ellipsoidal

An anisotropy in two dimensions, learnt as a blend of fixed directions.

Holds n_directions ellipses at evenly spaced angles, their ranges trained and their angles fixed, and trains a weight for each; the ellipse used is their weighted sum. Where Anisotropy2D trains one angle, which gradient descent can leave stuck in a local optimum, this spreads the choice over the fixed angles.

Parameters:

n_directions (int) – How many fixed directions to blend.

refresh()[source]
set_limits(data)[source]
class geoml.transform.Anisotropy3DMath(range_x=1.0, range_y=1.0, range_z=1.0, theta_x=0, theta_y=0, theta_z=0)[source]

Bases: _Ellipsoidal

Anisotropy in two dimensions

__init__(range_x=1.0, range_y=1.0, range_z=1.0, theta_x=0, theta_y=0, theta_z=0)[source]

Anisotropy matrix in mathematical parametrization.

Parameters:
  • range_x (double) – The ellipsoid semi-length in each direction. Must be positive.

  • range_y (double) – The ellipsoid semi-length in each direction. Must be positive.

  • range_z (double) – The ellipsoid semi-length in each direction. Must be positive.

  • theta_x (double) – The rotation angles in degrees.

  • theta_y (double) – The rotation angles in degrees.

  • theta_z (double) – The rotation angles in degrees.

refresh()[source]
set_limits(data)[source]
class geoml.transform.Anisotropy3DDynamic(n_directions_per_axis=3)[source]

Bases: _Ellipsoidal

An anisotropy in three dimensions, learnt as a blend of fixed orientations.

Holds one ellipsoid per combination of n_directions_per_axis fixed angles about each axis, their ranges trained and their angles fixed, and trains a weight for each; the ellipsoid used is their weighted sum. The three-dimensional form of Anisotropy2DDynamic, with its cube of orientations.

Parameters:

n_directions_per_axis – How many fixed angles to take about each axis.

refresh()[source]
set_limits(data)[source]

Composing and reshaping

class geoml.transform.ChainedTransform(*transforms)[source]

Bases: _Transform

Chained transform.

This object allows multiple transforms to be called sequentially. Useful for complex transformations.

__init__(*transforms)[source]

Chained transform.

Parameters:

transforms – Transformes to chain.

property linear

Whether the transform is affine, its Jacobian constant.

set_limits(data)[source]
class geoml.transform.Concatenate(*transforms)[source]

Bases: ChainedTransform

Concatenation of transforms.

Consolidates a list of inputs into a single one.

set_limits(data)[source]
class geoml.transform.SelectVariables(index)[source]

Bases: _Transform

Variable selection.

Returns the specified columns of the input, discarding the others.

__init__(index)[source]

Variable selection.

Parameters:

index (list) – Indices of variables to select.

class geoml.transform.ProjectionTo1D(n_dim)[source]

Bases: _Transform

Projection of high-dimensional data to a line.

__init__(n_dim)[source]

Initializer for ProjectionTo1D.

Parameters:

n_dim (int) – The number of dimensions. May be greater than 3 when used in conjunction with a space-expanding transform.

class geoml.transform.RandomProjections(n_dim, n_directions, seed=1234)[source]

Bases: _Transform

The coordinates projected onto fixed directions.

One output per direction: evenly spaced angles in two dimensions, random unit vectors in more, drawn from seed. Nothing is trained. A way to hand a kernel several one-dimensional views of the same space.

Parameters:
  • n_dim – The width of the coordinates taken in, at least 2.

  • n_directions – How many directions to project onto; the width given out.

  • seed – Seeds the directions in three dimensions and more.

class geoml.transform.NormalizeWithBoundingBox(box)[source]

Bases: _Transform

Normalization with a bounding box.

Uses a BoundingBox object as guide to normalize the data. All columns will be contained in the [-3, 3] interval.

__init__(box)[source]

Normalization with a bounding box.

Parameters:

box – The bounding box to use as reference for normalization.

class geoml.transform.Periodic[source]

Bases: _Transform

Periodic transform.

Returns sines and cosines doubling the number of columns in the data. The periods can be specified by chaining an Anisotropy* transform with this one.

class geoml.transform.BellFault2D(start, end)[source]

Bases: _Transform

Fault simulation.

__init__(start, end)[source]

Fault simulation.

Creates a discontinuity in space, returning an additional coordinate that can be used to artificially repel points on opposite sides of a line.

Parameters:
  • start (array-like) – Starting point of fault.

  • end (array-like) – Endpoint of fault.

static kernelize(x)[source]