# rft1d.geom¶

Geometry module

This module contains functions for computing various geomtric characteristics of 1D fields and upcrossings.

## Basic geometry functions:¶

### bwlabel¶

rft1d.geom.bwlabel(b, merge_wrapped=False)

Label clusters in a binary field b. This function yields the same output as scipy.ndimage.measurements.label but is much faster for 1D fields. If merge_wrapped

Parameters:

b — a binary field

merge_wrapped — if True, boundary upcrossings will be merged into a single cluster.

Returns:

L — labeled upcrossings (array of integers)

n — number of upcrossings

Example:
>>> y = rft1d.random.randn1d(1, 101, 10.0)
>>> b = y > 2.0
>>> L,n = rft1d.geom.bwlabel(b)

### estimate_fwhm¶

rft1d.geom.estimate_fwhm(R)

Estimate field smoothness (FWHM) from a set of random fields or a set of residuals.

Parameters:

R — a set of random fields, or a set of residuals

Returns:

FWHM — the estimated FWHM

Example:
>>> FWHM = 12.5
>>> y = rft1d.random.randn1d(8, 101, FWHM)
>>> w = rft1d.geom.estimate_fwhm(y) #should be close to 12.5

Note

The estimated FWHM will differ from the specified FWHM (just like sample means differ from the population mean). This function implements an unbiased estimate of the FWHM, so the average of many FWHM estimates is expected to converge to the specified value.

## Field geometry (resel counts)¶

### resel_counts¶

rft1d.geom.resel_counts(R, fwhm=1, element_based=False)

Resolution element (resel) counts.

This function assembles resel counts, either from a set of residuals or from a binary mask. If using a binary mask, True represents regions which are masked out.

Parameters:

R — a set of random fields, a set of residuals, or a binary field mask

fwhm — the true or estimated FWHM

element_based — element-based sampling (default: node-based sampling)

Returns:

resels — (r0, r1): 0D and 1D resel counts, respectively

Note:

The resel counts define the field on which the random process occurs. The first count (r0) is the Hadwiger characteristic, which specifies the number of unbroken field segments. An unbroken field has r0 = 1. The second count (r1) is the field size divided by the FWHM.

Important:

All RFT expectations stem directly from these resel counts.

Important cases:
1. Node-based sampling (default), unbroken field with Q nodes — the field size is (Q-1) and resels = [1, (Q-1)/FWHM]

2. Element-based sampling, unbroken field, Q elements — the field size is Q and resels = [1, Q/FWHM]

3. Node-based sampling (default), broken field with S segements and Q nodes — the field size is (Q-S) and resels = [S, (Q-S)/FWHM]

4. Element-based sampling, broken field with S segements and Q elements — the field size is Q and resels = [S, Q/FWHM]

Examples (unbroken field):
>>> import numpy as np
>>> b = np.zeros(101) #no masked regions
>>> resels = rft1d.geom.resel_counts(b, fwhm=10.0) #yields(1,10)
>>> resels = rft1d.geom.resel_counts(b, fwhm=10.0, element_based=True) #yields(1,10.1)
Examples (broken field):
>>> b = np.zeros(101)
>>> b[25:55] = 1
>>> resels = rft1d.geom.resel_counts(b, fwhm=10.0) #yields(2,6.9)
>>> resels = rft1d.geom.resel_counts(b, fwhm=10.0, element_based=True) #yields(2,7.1)

### resel conversion functions¶

rft1d.geom.resels2fwhm(resels, nNodes, element_based=False)

Get the FWHM from resel counts based on the number of field nodes.

Parameters:

resels — resel counts

nNodes — number of field nodes (in broken fields: number of unbroken nodes)

element_based — element-based sampling (default: node-based sampling)

Returns:

fwhm — field FWHM

Example:
>>> resels = (1, 10.0)
>>> w = rft1d.geom.resels2fwhm(resels, 101) #yields 10.0
>>> resels = (2, 6.9)
>>> w = rft1d.geom.resels2fwhm(resels, 71) #yields 10.0
Note:

See rft1d.geom.resel_counts for details regarding the keyword “element_based”** and node-based vs. element-based sampling.

Get the FWHM from resel counts based on a binary field mask

Parameters:

resels — resel counts

element_based — element-based sampling (default: node-based sampling)

Returns:

fwhm — field FWHM

Example:
>>> resels = (2, 6.9)
>>> b = np.zeros(101)
>>> b[25:55] = 1
>>> w = rft1d.geom.resels2fwhm_masked(resels, b) #yields 10.0
Note:

See rft1d.geom.resel_counts for details regarding the keyword “element_based”** and node-based vs. element-based sampling.

rft1d.geom.resels2nelements(resels, fwhm)

Get the field size from resel counts based on the FWHM (element-based sampling).

Example:
>>> resels = (1, 10.0)
>>> nNodes = rft1d.geom.resels2nelements(resels, 10.0) #yields 100
>>> resels = (2, 6.9)
>>> nNodes = rft1d.geom.resels2nelements(resels, 10.0) #yields 69
Note:

See rft1d.geom.resel_counts for details regarding node-based vs. element-based sampling.

rft1d.geom.resels2nnodes(resels, fwhm)

Get the number of field nodes from resel counts based on the FWHM

Parameters:

resels — resel counts

fwhm — actual or estimated FWHM*element_based* — element-based sampling (default: node-based sampling)

Returns:

nNodes — number of field nodes

Example:
>>> resels = (1, 10.0)
>>> nNodes = rft1d.geom.resels2nnodes(resels, 10.0) #yields 101
>>> resels = (2, 6.9)
>>> nNodes = rft1d.geom.resels2nnodes(resels, 10.0) #yields 71
Note:

See rft1d.geom.resel_counts for details regarding node-based vs. element-based sampling.

rft1d.geom.resels2fieldsize(resels, fwhm, element_based=False)

Get the field size from resel counts based on the FWHM. Equivalent to rft1d.geom.resels2nnodes minus the number of unbroken field segments.

Example:
>>> resels = (1, 10.0)
>>> nNodes = rft1d.geom.resels2fieldsize(resels, 10.0) #yields 100
>>> resels = (2, 6.9)
>>> nNodes = rft1d.geom.resels2fieldsize(resels, 10.0) #yields 69
Note:

See rft1d.geom.resel_counts for details regarding the keyword “element_based”** and node-based vs. element-based sampling.

## Upcrossing metric calculations¶

### rft1d.geom.ClusterMetricCalculator¶

class rft1d.geom.ClusterMetricCalculator

A class for computing various geometric characteristics of the excursion set including number of upcrossings, upcrossing (cluster) extents, etc.

Parameters:

None

Returns:

calc — a ClusterMetricCalculator instance

Example:
>>> y = rft1d.random.randn1d(1, 101, 15.0)
>>> calc = rft1d.geom.ClusterMetricCalculator()
>>> k = calc.cluster_extents(y, 0.5) #cluster extents when thresholded at 0.5
cluster_extents(y, u, interp=True, wrap=False)

Upcrossing extents (units: nodes).

Parameters:

y — a 1D field

u — threshold height

interp — interpolate to threshold u

wrap — wrap upcrossings from the end to the start of the field

Returns:

k — list of upcrossing extents, or [0] if no upcrossings

Example:
>>> k = calc.cluster_extents(y, 0.0) #cluster extents when thresholded at 0.0

Danger

Setting interp to False is faster, but it will cause disagreements between node-based and element-based sampling. If the upcrossing is large this difference is negligible, but for small upcrossing there may be strange results (e.g. upcrossing with an extent of zero). Recommendation: always interpolate.

cluster_minima(y, u, interp=True)

Minimum field height inside each upcrossing.

Parameters:

y — a 1D field

u — threshold height

interp — interpolate to threshold u

Returns:

zmin — list of upcrossing minima; [0] if no upcrossings

Example:
>>> k = calc.cluster_minima(y, 0.0)

Warning

If interp is True, the minima are all u.

Danger

If u is zero and interp is True the user may be unable to distinguish between two cases: (i) no upcrossings and (ii) one upcrossing with a minimum of zero. Most thresholds we’re interested in are much higher than zero, so this buggy behavior is not deemed serious. To check the number of upcrossings use the nMaxima method.

max_cluster_extent(y, u, interp=True, wrap=False)

Maximum upcrossing extent

Parameters:

y — a 1D field

u — threshold height

interp — interpolate to threshold u

wrap — wrap upcrossings from the end to the start of the field

Returns:

kmax — maximum upcrossing extent (unit: nodes)

Example:
>>> k = calc.max_cluster_extent(y, 0.2)

Danger

Setting interp to False is faster, but it will cause disagreements between node-based and element-based sampling. If the upcrossing is large this difference is negligible, but for small upcrossing there may be strange results (e.g. upcrossing with an extent of zero). Recommendation: always interpolate.

mean_cluster_extent(y, u, interp=True, wrap=False)

Mean upcrossing extent

Parameters:

y — a 1D field

u — threshold height

interp — interpolate to threshold u

wrap — wrap upcrossings from the end to the start of the field

Returns:

kmean — mean upcrossing extent (unit: nodes)

Example:
>>> k = calc.mean_cluster_extent(y, 0.5)

Danger

Setting interp to False is faster, but it will cause disagreements between node-based and element-based sampling. If the upcrossing is large this difference is negligible, but for small upcrossing there may be strange results (e.g. upcrossing with an extent of zero). Recommendation: always interpolate.

nMaxima(y, u)

Number of maxima. Equivalent to nUpcrossings.

nSuprathresholdNodes(y, u)

Number of nodes in the excursion set.

Parameters:

y — a 1D field

u — threshold height

Returns:

nNodes — number of nodes which survive the threshold u

Example:
>>> nNodes = calc.nSuprathresholdNodes(y, 0.5)

Warning

This returns simply the number of nodes, which is not equivelent to extent. To compute the total extent you must subtract the number of upcrossings from this value. Otherwise use rft1d.geom.nSuprathresholdResels or rft1d.geom.total_excursion_set_extent.

nSuprathresholdResels(y, u, fwhm=1.0, interp=True)

Number of resels in the excursion set.

Parameters:

y — a 1D field

u — threshold height

fwhm — actual or estimated FWHM

interp — interpolate to threshold u

Returns:

nResels — number of resels which survive the threshold u

Example:
>>> nResels = calc.nSuprathresholdResels(y, 0.5)

Warning

This is a length measure, so is similar to (nSuprathresholdNodes minus nUpcrossings) divided by the FWHM, with the exception that extents can be interpolated to u.

Danger

Setting interp to False is faster, but it will cause disagreements between node-based and element-based sampling. If the upcrossing is large this difference is negligible, but for small upcrossing there may be strange results (e.g. upcrossing with an extent of zero). Recommendation: always interpolate.

nUpcrossings(y, u)

Number of upcrossings.

Parameters:

y — a 1D field

u — threshold height

Returns:

c — number of upcrossings

Example:
>>> c = calc.nUpcrossings(y, 0.5)
nUpcrossingsByExtent(y, u, k, interp=True, wrap=False)

Number of upcrossings at threshold extent k.

Parameters:

y — a 1D field

u — threshold height

k — cluster extent threshold (unit: nodes)

interp — interpolate to threshold u

wrap — wrap upcrossings from the end to the start of the field

Returns:

c — number of upcrossings whose extents equal or exceed k

Example:
>>> c = calc.nUpcrossingsByExtent(y, 3.5, 5.0)

Danger

Setting interp to False is faster, but it will cause disagreements between node-based and element-based sampling. If the upcrossing is large this difference is negligible, but for small upcrossing there may be strange results (e.g. upcrossing with an extent of zero). Recommendation: always interpolate.

total_excursion_set_extent(y, u, interp=True)

Total extent of the excursion set.

Parameters:

y — a 1D field

u — threshold height

fwhm — actual or estimated FWHM

interp — interpolate to threshold u

Returns:

k — total extent of the excursion set u

Example:
>>> nResels = calc.total_excursion_set_extent(y, 0.5)
Note:

This is a length measure, so is similar to nSuprathresholdNodes minus nUpcrossings, with the exception that extents can be interpolated to u.

Danger

Setting interp to False is faster, but it will cause disagreements between node-based and element-based sampling. If the upcrossing is large this difference is negligible, but for small upcrossing there may be strange results (e.g. upcrossing with an extent of zero). Recommendation: always interpolate.