Load SPHARM Coefficients#
ktch can read spherical harmonic coefficients from SPHARM-PDM .coef
files, the output of the ParaToSPHARMMesh step of
SPHARM-PDM.
This guide reads a sample .coef file and reconstructs the 3D shape
encoded by its coefficients.
Read SPHARM-PDM coefficients#
from ktch.datasets import fetch
from ktch.io import read_spharmpdm_coef
coef_path = fetch("danshaku_08_allSegments_SPHARM.coef")
data = read_spharmpdm_coef(coef_path)
print(f"specimen={data.specimen_name}, l_max={data.l_max}, "
f"shape={data.to_numpy().shape}")
specimen=danshaku_08_allSegments_SPHARM, l_max=25, shape=(676, 3)
data.coeffs[l] holds the complex coefficients of degree l with shape
(2*l+1, 3). See Harmonic-based Morphometrics for the convention.
Reconstruct the surface#
Convert the SPHARM-PDM coefficients to the real basis used by
SphericalHarmonicAnalysis, then call
inverse_transform to evaluate the reconstructed surface on a
(theta, phi) grid.
from ktch.harmonic import SphericalHarmonicAnalysis
from ktch.io import spharmpdm_to_sha_coeffs
coeffs = spharmpdm_to_sha_coeffs(data)
sha = SphericalHarmonicAnalysis(n_harmonics=data.l_max)
X_coords = sha.inverse_transform(coeffs)
print(f"surface grid shape: {X_coords.shape}") # (1, n_theta, n_phi, 3)
surface grid shape: (1, 90, 180, 3)
To use a different angular resolution, pass theta_range and
phi_range to inverse_transform.
Plot the 3D shape#
import plotly.graph_objects as go
x, y, z = X_coords[0].T
fig = go.Figure(
data=[
go.Surface(x=x, y=y, z=z, opacity=0.8, showscale=False),
]
)
fig.update_layout(
width=700,
height=700,
autosize=False,
scene=dict(
camera=dict(
up=dict(x=0, y=0, z=1),
eye=dict(x=1.1, y=1.1, z=1.1),
),
aspectmode="data",
),
)
fig.show()
See also
Spherical Harmonic (SPHARM) Analysis to compute SPHARM coefficients from a 3D surface mesh.
Harmonic-based Morphometrics for background on spherical harmonic analysis.