---
# **F5 EXTENSION SPECIFICATION: Procedural Coordinates and Negative IndexDepth**
### Primary example: Spherical Harmonic Surface Representation
---

# 0. Introduction and Scope

This document specifies the **negative IndexDepth** extension to the F5 data model.
It enables the representation of data whose spatial coordinates are themselves derived
from stored coefficients, rather than stored directly. The resolution of the resulting
spatial representation is determined by the reader at runtime, not by the writer at
file creation time.

This extension is **implemented** in the F5 reference library and has been applied to
real scientific data since 1999. The concrete motivating case is the apparent horizon
of merging black holes, represented via real spherical harmonic coefficients from which
the horizon surface shape is reconstructed at any desired resolution.

**Relationship to the core spec:** All rules from F5_Layout.md apply. Negative
IndexDepth is implicit in the core spec's treatment of IndexDepth as an integer
attribute — this document makes it explicit and defines its semantics.

**Relationship to the type extension:** This document introduces application-defined
ChartDomains (SphericalChart2D, PolarChart3D, SphericalHarmonics) following the
conventions of F5_Extension_1_NamedTypes.md. These are illustrative examples of the
pattern, not exhaustive normative definitions.

---

# 1. Background: The Horizon Reconstruction Problem

The apparent horizon of a black hole is a 2D surface embedded in 3D space. For a
nearly spherical surface, the shape is efficiently described by its spherical harmonic
decomposition:

```
r(θ,φ) = Σ_{l=0}^{l_max} Σ_{m=-l}^{l}  a_lm · Y_lm(θ,φ)
```

where Y_lm are the real spherical harmonic basis functions, a_lm are the coefficients,
and r(θ,φ) is the radial distance from the expansion center to the surface at angular
position (θ,φ).

**Storage economy:** For l_max = 7 there are (l_max+1)² = 64 coefficients. These
64 numbers completely determine the surface shape. Storing the surface as an explicit
vertex mesh at 201×201 resolution requires 40,401 coordinate triples — 630 times more
data, at a fixed resolution chosen by the writer.

**The F5 approach:** Store the 64 coefficients. The reader reconstructs the surface
at whatever resolution its visualization algorithm requires. The file does not contain
vertices; it contains the recipe for producing them.

**Historical note:** The example data (mahf_coeff_0.alm, mahf_coeff_1.alm,
mahf_coeff_2.alm, mahf_0.gauss, mahf_area_0.tl) are from the first full 3D numerical
simulation of merging black holes (Cactus code, 1999), produced before F5 existed.
They were read directly into the F5 in-memory fiber bundle model at the time. This
extension specifies their normative F5 HDF5 representation. The three coefficient
files describe three distinct apparent horizons at the same timeslice — two individual
black holes and the common merged horizon — with expansion centers at:

```
Horizon 0 (merged):  xc = 0.000,  yc = 0.000,  zc =  0.000
Horizon 1 (BH 1):    xc = 0.000,  yc = 0.000,  zc = +1.570
Horizon 2 (BH 2):    xc = 0.000,  yc = 0.000,  zc = -1.430
```

The distinct centers make the three horizons structurally separate Grids within the
same timeslice, each with its own local chart transformation rule.

---

# 2. Negative IndexDepth: Definition and Semantics

## 2.1 The IndexDepth integer is unbounded in both directions

The core spec defines IndexDepth as an integer attribute on every Skeleton:
- IndexDepth  0: vertices — the atomic base of spatial discretization
- IndexDepth +n: entities composed from vertices (cells, sets of cells, etc.)

This extension establishes the semantics of negative IndexDepth:
- IndexDepth -1: **generators** — entities from which vertices are derived via a
  known mathematical procedure (expansion coefficients, control points, basis weights)
- IndexDepth -2: **meta-generators** — entities from which generators are themselves
  derived
- IndexDepth -n: n derivation steps prior to vertices

The derivation chain is:

```
IndexDepth -2  →  IndexDepth -1  →  IndexDepth 0  →  IndexDepth 1
(meta-coeff)       (coeff)           (vertices)        (cells)
```

Each arrow represents a **procedural derivation** — a mathematical procedure that
produces the next level from the previous one. The procedure is encoded in the
**chart type** shared between Skeletons within the same Grid.

## 2.2 Reader resolution authority

At positive and zero IndexDepth, the number of elements in a Skeleton's index space
is determined by the stored data. At negative IndexDepth, the number of **output**
elements (vertices at IndexDepth 0) is **not stored** in the file — it is chosen by
the reader at runtime based on its requirements: visualization resolution, numerical
precision, available memory.

This inversion — writer stores compact generators, reader chooses output resolution —
is the defining property of negative IndexDepth.

## 2.3 Skeleton dimensionality at negative IndexDepth

The `F5::SkeletonDimensionality` attribute reflects the mathematical dimensionality of
the index space, not the storage layout. For spherical harmonic coefficients indexed
by (l,m), the index space is 2-dimensional even though coefficients are stored as a
flat 1D array of pairs. `F5::SkeletonDimensionality = 2` is correct for the harmonic
coefficient Skeleton.

---

# 3. ChartDomains Introduced in This Extension

Three ChartDomains are required for the horizon example. All follow the conventions
of F5_Extension_1_NamedTypes.md.

## 3.1 SphericalChart2D — the angular surface

The 2D spherical surface coordinate system (θ,φ). This is the natural coordinate
system for a field defined on a sphere — the domain of the Gaussian curvature and
the sampling grid.

```
/Charts/SphericalChart2D/
    SinglePrecision/
        Point          struct { float theta, phi }
                         Attribute ChartDomain: "SphericalChart2D"
                         Attribute Dimensions:  2
    DoublePrecision/
        Point          struct { double theta, phi }
    Point              soft link -> SinglePrecision/Point
```

Member names: `theta` ∈ [0, π], `phi` ∈ [0, 2π] or subranges according to symmetry.

## 3.2 PolarChart3D — the 3D spherical coordinate system

The 3D polar coordinate system (r, θ, φ). This chart is the intermediate between
the 2D angular surface and Cartesian 3D space. In this extension it appears primarily
as a **transformation rule** — a named intermediate step in the coordinate chain —
rather than as a Representation with stored Positions.

```
/Charts/PolarChart3D/
    SinglePrecision/
        Point          struct { float r, theta, phi }
                         Attribute ChartDomain: "PolarChart3D"
                         Attribute Dimensions:  3
    DoublePrecision/
        Point          struct { double r, theta, phi }
    Point              soft link -> SinglePrecision/Point
```

## 3.3 SphericalHarmonics — the harmonic index space

The discrete index space of spherical harmonic coefficients, parameterized by degree l
and order m. The member names are the coordinate function names of harmonic space.

```
/Charts/SphericalHarmonics/
    SinglePrecision/
        Point          struct { int32 l, int32 m }
                         Attribute ChartDomain: "SphericalHarmonics"
                         Attribute Dimensions:  2
    DoublePrecision/
        Point          struct { int64 l, int64 m }
    Point              soft link -> SinglePrecision/Point
```

`l` = multipole degree (l ≥ 0), `m` = azimuthal order (|m| ≤ l). The (l,m) index
space is 2-dimensional — this is expressed in `Attribute Dimensions: 2` and in the
`F5::SkeletonDimensionality = 2` on the Coefficients Skeleton.

---

# 4. The Coordinate Transformation Chain

A reader that needs Cartesian coordinates for rendering follows this chain:

```
SphericalHarmonics (l,m) index space        [IndexDepth -1, stored]
    ↓  synthesis: r(θ,φ) = Σ a_lm · Y_lm(θ,φ)
SphericalChart2D (θ,φ) → PolarChart3D (r,θ,φ) [IndexDepth 0, angular stored]
    ↓  conversion: x = r sinθ cosφ + xc
                   y = r sinθ sinφ + yc
                   z = r cosθ     + zc
CartesianChart3D (x,y,z)                     [IndexDepth 0, reader-derived]
```

The angular (θ,φ) grid is stored at IndexDepth 0. The radial component r(θ,φ) is
procedurally added by the reader using the harmonic coefficients. The Cartesian
conversion uses the expansion center (xc, yc, zc) stored in the local Grid chart
transformation rule.

The `PolarChart3D` appears in each Grid's Charts group **only as a named transformation
subgroup** within `CartesianChart3D/` — it holds the origin attribute but carries
no Positions dataset. Its presence as a named subgroup is the signal to a reader that
the PolarChart3D → CartesianChart3D transformation is defined for this Grid.

---

# 5. Complete F5 Structure: Single Horizon

The following shows the complete layout for one apparent horizon (Horizon_0).
The structure for Horizon_1 and Horizon_2 is identical except for the origin value.

```
/Charts/
    SphericalChart2D/                    (§3.1)
        DoublePrecision/Point   struct { double theta, phi }
        SinglePrecision/Point   struct { float  theta, phi }
        Point                   soft link -> SinglePrecision/Point

    PolarChart3D/                        (§3.2)
        DoublePrecision/Point   struct { double r, theta, phi }
        SinglePrecision/Point   struct { float  r, theta, phi }
        Point                   soft link -> SinglePrecision/Point

    SphericalHarmonics/                  (§3.3)
        DoublePrecision/Point   struct { int64 l, int64 m }
        SinglePrecision/Point   struct { int32 l, int32 m }
        Point                   soft link -> SinglePrecision/Point

    Cartesian3D/                         (standard, F5_Extension_1_NamedTypes.md)
        ...


/t=000000010.3580200000/

    Horizon_0/                           <- Grid

        Charts/
            SphericalChart2D/
                GlobalChart              -> /Charts/SphericalChart2D/

            CartesianChart3D/
                PolarChart3D/            <- transformation rule: PolarChart3D -> Cartesian
                    Attribute: origin    {0.0, 0.0, 0.0}   (double[3])
                    (no GlobalChart: PolarChart3D appears here only as
                     a named transformation step, not as a standalone chart object)


        Coefficients/                    <- Skeleton, IndexDepth = -1
            Attribute F5::SkeletonDimensionality   2   <- (l,m) is 2D
            Attribute F5::IndexDepth              -1
            Attribute F5::rank                     0

            SphericalHarmonics/          <- Representation in harmonic index space
                Positions                <- type: SphericalHarmonics/DoublePrecision/Point
                                         <- Dataset {64}: { int64 l, int64 m } per coeff
                                         <- stores which (l,m) each entry belongs to;
                                         <- ordering is arbitrary, determined by this array
                a_lm                     <- type: double scalar
                                         <- Dataset {64}: coefficient values
                                         <- indexed identically to Positions


        Points/                          <- Skeleton, IndexDepth = 0
            Attribute F5::SkeletonDimensionality   0
            Attribute F5::IndexDepth               0
            Attribute F5::rank                     0

            SphericalChart2D/            <- Representation in angular (theta,phi) space
                Positions                <- TypeInfo: DirectProduct
                                         <- encodes uniform angular sampling:
                                         <-   theta: UniformSampling [0, pi],  n=201
                                         <-   phi:   UniformSampling [0, 2pi], n=201
                                         <- angular grid ONLY — no r stored here;
                                         <- r is derived procedurally from Coefficients

                GaussianCurvature        <- type: double scalar per point
                                         <- TypeInfo: DirectProduct (same grid)
                                         <- Dataset {201, 201}
                                         <- stored at simulation resolution

                area                     <- type: double
                                         <- H5S_SCALAR HDF5 dataspace
                                         <- TypeInfo: Constant
                                         <- integrated surface area at this timeslice;
                                         <- constant over all surface points —
                                         <- a property of the whole surface, not vertices
```

---

# 6. The Three-Horizon Layout at One Timeslice

The three apparent horizons are three Grids within the same timeslice. Each uses the
same global ChartDomains and the same Skeleton structure. The only differences are
the stored coefficient values, the stored Gaussian curvature, and the expansion center
in the local transformation rule.

```
/t=000000010.3580200000/

    Horizon_0/                           <- merged/common horizon
        Charts/
            SphericalChart2D/
                GlobalChart              -> /Charts/SphericalChart2D/
            CartesianChart3D/
                PolarChart3D/
                    Attribute: origin    {0.000, 0.000,  0.000}
        Coefficients/ ...                <- 64 a_lm for merged horizon
        Points/      ...                 <- GaussianCurvature, area for merged horizon

    Horizon_1/                           <- individual black hole 1
        Charts/
            SphericalChart2D/
                GlobalChart              -> /Charts/SphericalChart2D/
            CartesianChart3D/
                PolarChart3D/
                    Attribute: origin    {0.000, 0.000, +1.570}
        Coefficients/ ...                <- 64 a_lm for BH1
        Points/      ...                 <- GaussianCurvature, area for BH1

    Horizon_2/                           <- individual black hole 2
        Charts/
            SphericalChart2D/
                GlobalChart              -> /Charts/SphericalChart2D/
            CartesianChart3D/
                PolarChart3D/
                    Attribute: origin    {0.000, 0.000, -1.430}
        Coefficients/ ...                <- 64 a_lm for BH2
        Points/      ...                 <- GaussianCurvature, area for BH2
```

---

# 7. The Derivation Link: How a Reader Connects IndexDepth Levels

## 7.1 Discovery algorithm

A reader seeking to reconstruct surface vertices from coefficients within one Grid:

1. Find all Skeletons with IndexDepth < 0 in the Grid
2. For each such Skeleton, examine its Representations
3. A Representation named `SphericalHarmonics` (matching a known ChartDomain)
   signals that this Skeleton carries harmonic coefficients
4. Find the Skeleton at IndexDepth 0 in the same Grid with a `SphericalChart2D`
   Representation — this is the angular sampling target
5. The synthesis formula r(θ,φ) = Σ a_lm · Y_lm(θ,φ) is part of the SphericalHarmonics
   chart type definition — the reader knows it by implementing the chart
6. Read the origin from `Charts/CartesianChart3D/PolarChart3D/origin`
7. For each (θ,φ) point in the SphericalChart2D DirectProduct grid:
   a. Evaluate r(θ,φ) using the stored a_lm and Positions (l,m) pairs
   b. Compute Cartesian (x,y,z) using the origin

## 7.2 Explicit storage of (l,m) pairs

The `Positions` field at IndexDepth -1 stores the (l,m) index of each coefficient
explicitly as a named compound type. This makes the coefficient ordering completely
unambiguous and independent of any conventional triangular ordering rule (l=0,m=0;
l=1,m=-1; l=1,m=0; ...). A reader reads `Positions` to learn which coefficient is
which, then reads `a_lm` for the values. This is consistent with F5's
"information in structure" axiom — ordering is not assumed, it is stated.

## 7.3 Resolution independence

The stored GaussianCurvature at 201×201 was produced at the simulation code's chosen
resolution. A reader choosing a different resolution:
- Evaluates the harmonic synthesis at its chosen (ntheta × nphi) grid
- Resamples GaussianCurvature from 201×201 to the new grid if needed, or
- Uses the stored 201×201 data directly if it matches

This mismatch is not an error. The coefficient representation is the primary, exact
representation; the stored 201×201 grid is a particular pre-computed realization.

---

# 8. IndexDepth -2 and the General Chain

If the spherical harmonic coefficients a_lm are themselves derived from a
higher-level set of meta-parameters (for example, a principal component expansion
a_lm = Σ_n b_n · V_lm_n for some basis V), the chain extends to IndexDepth -2:

```
/t=.../Horizon_0/

    MetaCoefficients/            <- Skeleton, IndexDepth = -2
        Attribute F5::IndexDepth    -2
        SomeBasis/
            Positions            <- indices in meta-coefficient space
            b_n                  <- meta-coefficient values

    Coefficients/                <- Skeleton, IndexDepth = -1
        SomeBasis/               <- relative Representation: Coefficients -> MetaCoeff
            Positions            <- maps each a_lm to its meta-generator indices
        SphericalHarmonics/
            Positions            <- (l,m) pairs
            a_lm                 <- may be stored or marked as procedurally derivable

    Points/ ...                  <- IndexDepth 0, as before
```

The Maximal-Depth Principle (core spec §18.11.1) applies in the negative direction:
if there is any possibility that coefficients may themselves be derived from a
higher-level source, assign IndexDepth -2 (or lower) to the coefficient Skeleton
now, preserving IndexDepth -1 for a potential intermediate level.

---

# 9. Reader Requirements

## 9.1 Minimal conforming reader (SphericalHarmonics not implemented)

- Reads Coefficients Skeleton: finds `a_lm` as an array of 64 doubles
- Reads Positions: finds 64 (l,m) pairs
- Cannot reconstruct surface vertices
- MUST NOT treat the absence of stored vertex coordinates as an error
- SHOULD report that this Grid contains procedural data requiring SphericalHarmonics

## 9.2 Full SphericalHarmonics-aware reader

1. Locates Coefficients Skeleton (IndexDepth -1), SphericalHarmonics Representation
2. Reads Positions (l,m pairs) and a_lm values
3. Locates Points Skeleton (IndexDepth 0), SphericalChart2D Representation
4. Reads DirectProduct parameters: theta range and n, phi range and n
5. Reads origin from `Charts/CartesianChart3D/PolarChart3D/origin`
6. Chooses output resolution (ntheta × nphi)
7. For each (θ,φ) grid point:
   - Evaluates r(θ,φ) = Σ a_lm · Y_lm(θ,φ) using stored (l,m) pairs and a_lm values
   - Computes (x,y,z) = (r sinθ cosφ + xc, r sinθ sinφ + yc, r cosθ + zc)
8. Reads GaussianCurvature and area from SphericalChart2D Representation
9. Area (TypeInfo=Constant) is uniform over all derived vertices

---

# 10. Summary of Normative Elements

| Element | Status |
|---|---|
| Negative IndexDepth values: valid and supported (§2.1) | Normative |
| IndexDepth -n: n derivation steps prior to vertices (§2.1) | Normative |
| Reader resolution authority for IndexDepth < 0 Skeletons (§2.2) | Normative |
| F5::SkeletonDimensionality reflects mathematical dimension, not storage rank (§2.3) | Normative |
| PolarChart3D as transformation-only subgroup with no stored Positions (§4) | Normative pattern |
| Constant fields at IndexDepth 0 with H5S_SCALAR / TypeInfo=Constant (§5) | Normative |
| Explicit (l,m) Positions storage: ordering by stored array, not convention (§7.2) | Normative |
| Minimal reader behaviour for unrecognised procedural charts (§9.1) | Normative |
| SphericalChart2D, PolarChart3D, SphericalHarmonics ChartDomains (§3) | Example; non-normative |

---

# 11. Reader Derivation Strategy

A reader seeking to construct vertex coordinates from generator data scans the Grid's
Skeletons for any with IndexDepth < 0. If vertices at IndexDepth 0 already exist in
the file at a suitable resolution, the reader uses them directly. If vertices are
absent or a different resolution is required, the reader inspects the IndexDepth -1
Skeletons and applies whichever derivation rule it understands and finds
computationally optimal.

Multiple derivation paths may coexist — coefficient synthesis, subsampling from
another Skeleton, coordinate transformation from another Grid. The choice among them
is a reader decision based on computational cost, numerical stability, and available
implementations. F5 does not prescribe a preferred path: the optimal choice is
context-dependent and the reader is best placed to make it. Ambiguity among
derivation paths is acceptable and expected.

Complex harmonic coefficients (when needed) are stored using the existing
TypeInfo=SeparatedCompound mechanism — one field for the real part, one for the
imaginary part, both indexed identically to the Positions (l,m) array. No special
treatment beyond the standard SeparatedCompound case is required.

---

# 12. Literature and Data Provenance

**Example data provenance:**
Files mahf_coeff_0.alm, mahf_coeff_1.alm, mahf_coeff_2.alm, mahf_0.gauss,
mahf_area_0.tl — output of the Cactus computational toolkit (1999), from the first
full 3D numerical simulation of binary black hole merging. These data predate F5 and
were read directly into the F5 in-memory fiber bundle model without HDF5 conversion.

**Apparent horizon finding:**
Thornburg, J.: "A fast apparent-horizon finder for three-dimensional Cartesian grids
in numerical relativity." Classical and Quantum Gravity 21(2), pp. 743-766 (2004).

**Cactus framework:**
Goodale, T., Allen, G., Lanfermann, G., Massó, J., Radke, T., Seidel, E., Shalf, J.:
"The Cactus framework and toolkit: Design and applications." VECPAR 2002, Lecture
Notes in Computer Science, Springer, Berlin (2003).

**F5 data model:**
Benger, W.: "Visualization of General Relativistic Tensor Fields via a Fiber Bundle
Data Model." PhD thesis, FU Berlin / ZIB, 2004.
https://www.fiberbundle.net/papers/TensorFieldViz.pdf

---

## Usage Restriction

This specification and all documents in the F5 specification series are published for
academic and personal use. Use of this specification, or any implementation derived
from it, by employees of military or defense-related organizations, or within
facilities producing weapons or conducting research on weapon design, or for any other
military purpose, is explicitly prohibited and contrary to the intent of the authors.

This restriction follows the spirit and terms of the light++ license under which the
original F5 reference implementation was published. The rationale is stated there
directly: software is technology, technology conveys power, and the inventor bears
responsibility for deciding to whom that power is granted. This specification was
developed to advance scientific understanding — not to enable harm.

See: https://www.fiberbundle.net/doc/copyright.html

---

# **End of Document**

---
