# Implementation-preservation audit The frozen scientific implementation remains under `radial_letter_v0_1_release/`; RadialPaths does not edit or call its publication renderers. This audit records the exact behavior preserved by the package. ## Geometry provenance Canonical source: `radial_letter_v0_1_release/analysis/v06_survey_native_benchmark/scripts/prepare_v06_benchmark.py`. | Quantity | Frozen implementation | Source | |---|---|---| | Support-constrained distance | `MCP_Geometric(np.where(support, 1.0, np.inf), fully_connected=True).find_costs(...)`; values outside support become `NaN` | `distance_from_sources`, lines 44–48 | | Per-centre distances | One graph-distance solve per supplied integer `(row, column)` centre | `coordinate_fields`, lines 51–54 | | Assignment `a(x)` | `np.argmin` over finite per-centre distances; exact ties go to the first supplied centre | lines 55–57 | | Regions `B_k` | `support & (basin == k)` | lines 66–67 | | Chosen-centre distance `d_k` | Gather the distance corresponding to the assigned centre | line 58 | | Boundary | In-support pixels adjacent in the 3×3 neighborhood to any excluded pixel | line 59 | | Boundary distance `b` | Same support-constrained graph solver with all boundary pixels as sources | lines 60–61 | | `rho_D` | `dcore / (dcore + dboundary)` where the denominator is positive | lines 62–63 | | `L_k` | Maximum assigned-centre distance over `B_k` | lines 65–69 | | `rho_X` | `dcore / L_k` within `B_k` | line 70 | | Observational coordinate storage | `rho_D` and `rho_X` are written as float32 before figure/profile use | lines 133–134 | `fully_connected=True` means an 8-neighbour pixel graph. Unit in-support costs give axial steps cost 1 and diagonal steps cost `sqrt(2)` through `MCP_Geometric`. Internal excluded holes are therefore barriers to traversal and also contribute boundary-source pixels through the same 3×3 adjacency. RadialPaths preserves these operations in `src/radialpaths/geometry.py`. It adds input validation for a non-empty, connected, two-dimensional support and for supplied centres inside that support. Those checks reject inputs outside the paper's assumptions; they do not alter valid-case numerical results. The frozen implementation computes distances and extents in float64. Its observational preparation then serializes the normalized coordinate fields as float32 before the R profile estimator reads them. That storage step is needed for exact reproduction of bin membership at coordinate values lying on bin edges; it is not part of the mathematical definition. ## Public precision and paper reproduction The continuous mathematical definitions do not require float32 normalized coordinates. The public `build_geometry` therefore returns float64 distances, extents, `rho_D`, and `rho_X`. Exact distance ties remain assigned to the first supplied centre, as in the validated implementation. Reordering the centre list can consequently reassign tie pixels and can alter region-normalized `rho_X` values when the reassignment changes a region extent. `rho_D` and the minimum centre-distance field are unchanged by a pure centre permutation. The observational preparation for Figures 4--5 serialized `rho_D` and `rho_X` as float32 FITS arrays. That implementation detail is retained only by `radialpaths.reproduction.build_paper_geometry`. The frozen regression tests call that explicit compatibility path. They do not set the public numerical default. ## Profile provenance Canonical source: `radial_letter_v0_1_release/mnras_submission/scripts/make_jades_figure.R`, function `binned_profile`, lines 189–204. The synchronized renderer at `analysis/figure_visual_system/render_jades_figures.R:156–173` is equivalent. For each centre-associated region independently: 1. use 30 equal coordinate bins on `[0, 1]`; 2. select `rho >= lower` and `rho < upper`; 3. include `rho == 1` in the last bin; 4. exclude non-finite tracer and coordinate pixels; 5. omit bins with fewer than six pixels; 6. report the unweighted median and the 16th and 84th percentiles. RadialPaths preserves this estimator as the default in `src/radialpaths/profiles.py`. It does not reproduce the later figure-only normalization by image peak or display floor, because those are plotting operations rather than the profile estimator. ## Regression fixture `tests/data/reference_geometry_profile.npz` is generated by `tools/generate_regression_fixture.py` directly from the frozen `coordinate_fields` function and an explicit Python transcription of the published R binning loop. The fixture contains a connected, non-convex, two-centre support with an internal hole, a deterministic tracer, and all expected geometry/profile arrays. `tests/data/regression_manifest.json` records generator/source hashes and library versions. The regression test requires exact basin/boundary agreement and floating-point agreement at `rtol=1e-13`, `atol=1e-13` for finite geometry and profile values. ## End-to-end observational cross-check The packaged implementation was also run directly on the two frozen Figure 4–5 supports and supplied centres. Against the stored FITS products for both GZMERGER09 and GZMERGER29: - centre-assignment arrays agree exactly; - float32 `rho_D` arrays agree exactly, including `NaN` locations; - float32 `rho_X` arrays agree exactly, including `NaN` locations; - all 30-bin per-centre pixel-count arrays agree exactly; - all populated unweighted-median values agree exactly (maximum absolute difference 0.0). The explicit float32 coordinate finalization is part of that end-to-end match. Without it, the transient float64 coordinate fields differ from the stored products by only about `3e-8`, but a small number of `rho_D` values cross exact bin edges. Preserving the serialization behavior prevents that downstream change. The frozen preprocessing fixture also stores the candidate peak values used during the paper audit. Current SciPy releases reproduce their ordering, positions, masks, selected centres, geometry, and profiles, but can differ in the stored peak values by a few units in the last floating-point place. The unchanged exact-value test is therefore run in the recorded validation environment in `requirements/paper-reproduction.txt`. This lock applies only to paper reproduction; the public API retains its broader declared dependency ranges.