.ipynb

Load NEF Files#

NEF (Normalized Elliptic Fourier) format stores normalized elliptic Fourier descriptors produced by SHAPE software’s Chc2Nef program.

Read NEF coefficients#

import tempfile
import numpy as np
from ktch.io import read_nef, write_nef, NefData

# Create a sample NEF file for demonstration
nef_content = """#CONST 1 1 1 0
#HARMO 3
specimen_001
  1.0 0.0 0.0 0.0
  0.5 0.1 0.2 0.3
  0.1 0.05 0.02 0.01
specimen_002
  1.0 0.0 0.0 0.0
  0.4 0.2 0.1 0.2
  0.08 0.03 0.01 0.02
"""

with tempfile.NamedTemporaryFile(mode='w', suffix='.nef', delete=False) as f:
    f.write(nef_content)
    nef_path = f.name

# Read the NEF file
nef_data = read_nef(nef_path)
print(f"Number of specimens: {len(nef_data)}")
print(f"First specimen: {nef_data[0].specimen_name}")
print(f"Harmonics: {nef_data[0].n_harmonics}")
print(f"Coefficient shape: {nef_data[0].to_numpy().shape}")
Number of specimens: 2
First specimen: specimen_001
Harmonics: 3
Coefficient shape: (3, 4)

Convert to EFA coefficients#

NEF data can be converted to flat coefficient vectors compatible with EllipticFourierAnalysis.inverse_transform():

from ktch.io import nef_to_efa_coeffs

efa_coeffs = nef_to_efa_coeffs(nef_data)
print(f"EFA coefficient shape: {efa_coeffs.shape}")
# Layout: [a_0..a_n, b_0..b_n, c_0..c_n, d_0..d_n]
EFA coefficient shape: (2, 16)

Write NEF coefficients#

from ktch.io import efa_coeffs_to_nef

# Convert back to NefData
nef_list = efa_coeffs_to_nef(efa_coeffs, specimen_names=["sp1", "sp2"])

# Write to file
with tempfile.NamedTemporaryFile(mode='w', suffix='.nef', delete=False) as f:
    output_path = f.name

write_nef(output_path, [n.coeffs for n in nef_list], sample_names=["sp1", "sp2"])

# Verify
result = read_nef(output_path)
print(f"Written and read back: {len(result)} specimens")
Written and read back: 2 specimens

See also