"""Faithful sparse-jaw diffusion experiment for Claim 5. The paper does not identify or release the jaw volume shown in Figure 1. This module therefore uses the independently published OpenMandible cortical-bone model. The source is commit- and hash-pinned, and the substitution is recorded as a limitation instead of being presented as the authors' original scan. """ from __future__ import annotations import hashlib import math import time import urllib.request from collections import deque from typing import Callable import numpy as np from scipy.ndimage import gaussian_filter from scipy.sparse.linalg import LinearOperator, eigsh from armadillo import USER_AGENT, _normalize_to_unit_ball, _sample_surface def _download(spec: dict) -> tuple[bytes, dict]: request = urllib.request.Request( spec["url"], headers={"User-Agent": USER_AGENT} ) with urllib.request.urlopen(request, timeout=180) as response: payload = response.read() observed = hashlib.sha256(payload).hexdigest() if observed != spec["sha256"]: raise RuntimeError( "OpenMandible hash mismatch: " f"expected {spec['sha256']}, got {observed}" ) return payload, { "dataset": spec["dataset"], "dataset_paper_doi": spec["dataset_paper_doi"], "repository": spec["repository"], "commit": spec["commit"], "url": spec["url"], "sha256": observed, "bytes": len(payload), "retrieval_user_agent": USER_AGENT, } def _parse_ascii_stl(payload: bytes) -> tuple[np.ndarray, np.ndarray, dict]: coordinates: list[list[float]] = [] for raw_line in payload.splitlines(): fields = raw_line.split() if fields and fields[0] == b"vertex": if len(fields) != 4: raise RuntimeError("malformed OpenMandible STL vertex") coordinates.append( [float(fields[1]), float(fields[2]), float(fields[3])] ) vertices = np.asarray(coordinates, dtype=np.float64) if vertices.shape[0] == 0 or vertices.shape[0] % 3: raise RuntimeError("OpenMandible STL is not an all-triangle mesh") faces = np.arange(vertices.shape[0], dtype=np.int64).reshape(-1, 3) triangles = vertices[faces] doubled_area = np.linalg.norm( np.cross( triangles[:, 1] - triangles[:, 0], triangles[:, 2] - triangles[:, 0], ), axis=1, ) if np.any(doubled_area <= 0.0): raise RuntimeError("OpenMandible STL contains degenerate triangles") return vertices, faces, { "format": "ASCII STL", "triangle_count": int(faces.shape[0]), "vertex_records": int(vertices.shape[0]), "all_triangles": True, "degenerate_triangles": 0, } def _sparse_surface_voxels( vertices: np.ndarray, faces: np.ndarray, edge: float, sample_count: int, seed: int, ) -> tuple[np.ndarray, np.ndarray, dict]: samples, sampling = _sample_surface( vertices, faces, sample_count, seed ) grid_size = int(round(2.0 / edge)) indices = np.floor((samples + 1.0) / edge).astype(np.int64) indices = np.clip(indices, 0, grid_size - 1) indices = np.unique(indices, axis=0) centers = -1.0 + edge * (indices.astype(np.float64) + 0.5) return indices, centers, { **sampling, "representation": "sparse regular-grid surface voxels", "grid_shape": [grid_size, grid_size, grid_size], "voxel_edge": float(edge), "nonempty_voxels": int(indices.shape[0]), "occupancy_fraction": float(indices.shape[0] / grid_size**3), "index_extent": ( indices.max(axis=0) - indices.min(axis=0) + 1 ).tolist(), } def _largest_component_fraction(indices: np.ndarray) -> float: lookup = {tuple(int(value) for value in row) for row in indices} remaining = set(lookup) largest = 0 offsets = ( (1, 0, 0), (-1, 0, 0), (0, 1, 0), (0, -1, 0), (0, 0, 1), (0, 0, -1), ) while remaining: root = remaining.pop() queue: deque[tuple[int, int, int]] = deque([root]) size = 0 while queue: current = queue.popleft() size += 1 for offset in offsets: neighbor = ( current[0] + offset[0], current[1] + offset[1], current[2] + offset[2], ) if neighbor in remaining: remaining.remove(neighbor) queue.append(neighbor) largest = max(largest, size) return float(largest / max(indices.shape[0], 1)) def _voxel_gaussian_operator( indices: np.ndarray, grid_size: int, sigma_grid: float, truncate: float, ) -> Callable[[np.ndarray], np.ndarray]: workspace = np.zeros( (grid_size, grid_size, grid_size), dtype=np.float64 ) def matvec(vector: np.ndarray) -> np.ndarray: workspace.fill(0.0) workspace[indices[:, 0], indices[:, 1], indices[:, 2]] = vector convolved = gaussian_filter( workspace, sigma=sigma_grid, mode="constant", cval=0.0, truncate=truncate, ) return convolved[ indices[:, 0], indices[:, 1], indices[:, 2] ] return matvec def _sinkhorn( kernel_matvec: Callable[[np.ndarray], np.ndarray], weights: np.ndarray, ) -> tuple[np.ndarray, list[float], int, float]: scaling = np.ones(weights.shape[0], dtype=np.float64) curve: list[float] = [] threshold_iteration = -1 residual_max = math.inf for iteration in range(1, 301): kernel_scaled = kernel_matvec(weights * scaling) row_values = scaling * kernel_scaled mean_error = float(np.sum(weights * np.abs(row_values - 1.0))) curve.append(mean_error) if threshold_iteration < 0 and mean_error < 1e-3: threshold_iteration = iteration residual_max = float(np.max(np.abs(row_values - 1.0))) if residual_max < 1e-12: return scaling, curve, threshold_iteration, residual_max scaling = np.sqrt( scaling / np.maximum(kernel_scaled, 1e-300) ) raise RuntimeError( f"OpenMandible Sinkhorn did not converge: {residual_max}" ) def _record_diffusion( indices: np.ndarray, centers: np.ndarray, weights: np.ndarray, kernel_matvec: Callable[[np.ndarray], np.ndarray], scaling: np.ndarray, steps: list[int], normalization: str, ) -> dict: def apply(signal: np.ndarray) -> np.ndarray: return scaling * kernel_matvec(weights * scaling * signal) row_values = apply(np.ones(weights.shape[0], dtype=np.float64)) source_index = int(np.argmin(centers[:, 0])) source = centers[source_index] signal = np.zeros(weights.shape[0], dtype=np.float64) signal[source_index] = 1.0 / weights[source_index] snapshots: list[dict] = [] maximum_step = max(steps) for step in range(maximum_step + 1): if step in steps: next_signal = apply(signal) constant = float(np.sum(weights * signal)) centered_signal = signal - constant q_roughness = float( np.sum(weights * signal * (signal - next_signal)) ) weighted_l2_from_constant = float( np.sum(weights * centered_signal**2) ) spatial_second_moment = float( np.sum( weights * np.maximum(signal, 0.0) * np.sum((centers - source) ** 2, axis=1) ) ) snapshots.append( { "step": step, "mass": constant, "minimum": float(signal.min()), "maximum": float(signal.max()), "q_roughness": q_roughness, "weighted_l2_from_constant": ( weighted_l2_from_constant ), "spatial_second_moment": spatial_second_moment, "signal": signal.tolist(), } ) if step < maximum_step: signal = apply(signal) diagonal = np.sqrt(weights) * scaling symmetric_operator = LinearOperator( (weights.shape[0], weights.shape[0]), matvec=lambda vector: diagonal * kernel_matvec(diagonal * vector), rmatvec=lambda vector: diagonal * kernel_matvec(diagonal * vector), dtype=np.float64, ) largest = eigsh( symmetric_operator, k=6, which="LA", return_eigenvectors=False, tol=2e-9, maxiter=1_000, ) smallest = eigsh( symmetric_operator, k=3, which="SA", return_eigenvectors=False, tol=2e-9, maxiter=1_000, ) return { "normalization": normalization, "source_index": source_index, "source_voxel_index": indices[source_index].tolist(), "row_residual_max": float(np.max(np.abs(row_values - 1.0))), "constant_preservation_max_error": float( np.max(np.abs(row_values - 1.0)) ), "largest_symmetric_eigenvalues": np.sort(largest)[::-1].tolist(), "smallest_symmetric_eigenvalues": np.sort(smallest).tolist(), "snapshots": snapshots, } def run_claim5_jaw(config: dict, spectral_result: dict) -> tuple[dict, dict]: spec = config["claim5_jaw"] start = time.perf_counter() payload, source = _download(spec) vertices, faces, mesh = _parse_ascii_stl(payload) vertices, normalization = _normalize_to_unit_ball(vertices) indices, centers, voxelization = _sparse_surface_voxels( vertices, faces, float(spec["voxel_edge"]), int(spec["surface_sample_count"]), int(spec["seed"]), ) voxelization["largest_6_connected_component_fraction"] = ( _largest_component_fraction(indices) ) grid_size = int(round(2.0 / float(spec["voxel_edge"]))) sigma_grid = float(spec["kernel_sigma"]) / float(spec["voxel_edge"]) truncate = float(spec["gaussian_truncate_sigma"]) kernel_matvec = _voxel_gaussian_operator( indices, grid_size, sigma_grid, truncate ) weights = np.full(indices.shape[0], 1.0 / indices.shape[0]) scaling, curve, threshold_iteration, residual = _sinkhorn( kernel_matvec, weights ) steps = [int(value) for value in spec["diffusion_steps"]] sinkhorn_record = _record_diffusion( indices, centers, weights, kernel_matvec, scaling, steps, "symmetric Sinkhorn", ) sinkhorn_record.update( { "sinkhorn_curve": curve, "sinkhorn_iterations": len(curve), "sinkhorn_iterations_to_1e-3": threshold_iteration, "sinkhorn_residual_max": residual, } ) raw_record = _record_diffusion( indices, centers, weights, kernel_matvec, np.ones_like(weights), steps, "raw unnormalized Gaussian", ) modalities = spectral_result["modalities"] cross_modalities = { "point_cloud": modalities["point_5000"], "covariance_aware_gmm": modalities["gmm_500"], "sparse_armadillo_voxels": modalities["surface_voxels"], } common = { "claim_id": 5, "source_statement": ( "The method is demonstrated on point clouds, sparse voxel " "grids (jaw bone geometry), and Gaussian mixture models with " "covariance-aware kernels, showing Laplacian-like smoothing." ), "paper_source_anchor": "Figure 1, Figure 3, Sections 5-6, Eq.6", "jaw_source": source, "jaw_source_substitution": ( "OpenMandible cortical bone replaces the paper's unidentified " "and unreleased jaw scan; it is not claimed to be the same scan." ), "mesh": mesh, "normalization": normalization, "voxelization": voxelization, "voxel_indices": indices.tolist(), "weights": weights.tolist(), "kernel": { "type": "matrix-free separable Gaussian convolution", "physical_sigma": float(spec["kernel_sigma"]), "sigma_grid_cells": sigma_grid, "truncate_sigma": truncate, "maximum_omitted_axis_weight": float( math.exp(-0.5 * truncate**2) ), }, "cross_modalities": cross_modalities, "runtime_seconds": time.perf_counter() - start, "seed": int(spec["seed"]), } actual = { **common, "scaling": scaling.tolist(), "diffusion": sinkhorn_record, } negative = { **common, "scaling": np.ones_like(weights).tolist(), "diffusion": raw_record, "negative_control": ( "omit Sinkhorn scaling while retaining the same jaw, voxels, " "kernel, weights, source signal, and evaluation checks" ), } return actual, negative