surface_psd — ROUGHNESS measure op

• Datenarten: depth → pairs

• Aufruf: import fullseye as fs; fs.ledger.surface_psd(z, dx, kind='areal', dy=None) (die Implementierung direkt: import roughness; roughness.surface_psd(z, dx, kind='areal', dy=None); aus dem Register: opsroughness.get("surface_psd"))

• Rückgabewert über das Register: fullseye.ledger.surface_psd(...) liefert nur den Wert des deklarierten Out-Typs pairs (die zugrunde liegende Funktion gibt zusätzlich Hilfsinformationen zurück). Wird das Verworfene gebraucht, nutze fullseye.ledger.surface_psd.raw(...) oder rufe roughness.surface_psd direkt auf.

• Rückgabe der Funktion: (q, C) -> (N,2)

Verwendung

Leistungsdichtespektrum des Höhenfelds. Gibt (q, C) zurück. Die Konventionen werden über Argumente explizit angegeben.

Argumente

z Höhenfeld (der Mittelwert wird intern abgezogen; der DC-Bin wird nicht zurückgegeben).

dx, dy Abtastabstand. dy=None bedeutet quadratische Pixel.

kind "areal" ... Ringmittel der 2-D-PSD C_2D(q).

"radial" ... 1-D-Radial-PSD C_1D(q) = 2π q C_2D(q).

Konventionen (ohne sie hier aufzuschreiben ist das Ergebnis ohne Kalibrierung nicht lesbar ―― das bestehende radial_power_spectrum hat sie nicht im Docstring)

• q ist in cycles / length (nicht die Kreisfrequenz 2π/λ). q = 1/λ.

• C_2D(q) = dx dy |F|² / (ny nx). Die Normierung folgt Parseval: ∫ C_2D d²q = <h²> und ∫ C_1D dq = <h²>.

• Die Steigung für eine selbstaffine Fläche H ist -2(H+1) bei der Flächen-PSD und -2H-1 bei der Radial-PSD (sie unterscheiden sich um genau 1).

★ Gemessen —— H wird unter beiden Konventionen ohne Kalibrierung zurückgewonnen

H wurde mit surface_synth_psd vorgegeben, über q ∈ [2/λ_hi, 0.4/dx] doppelt-logarithmisch

eine Gerade angepasst und H zurückgewonnen (512², Band 2-64 µm):

vorgeg. H Steigung Flächen-PSD zurückgew. H Steigung radial zurückgew. H Steigungsdiff.

0.30 -2.600 0.300 -1.600 0.300 1.0000

0.50 -3.000 0.500 -2.000 0.500 1.0000

0.80 -3.600 0.800 -2.600 0.800 1.0000

0.95 -3.901 0.950 -2.901 0.950 1.0000

Der Fehler liegt in allen 4 Fällen innerhalb ±0.0003, die Steigungsdifferenz der beiden Konventionen ist für jedes H

exakt 1.0000. Ohne Kalibrierung lesbar.

★ Hier hat die Nachmessung des PoC die Schlussfolgerung geändert. Der PoC fand mit dem bestehenden

radial_power_spectrum einen gleichförmigen systematischen Fehler von -0.013 (1.6 % von H) und

schloss auf "systematischen Fehler durch Diskretisierung des Ringmittels". Die gleiche Gegenprobe mit dieser

Implementierung lässt den Fehler verschwinden. Die Ursachenisolierung ergab: es ist der Unterschied, ob als repräsentatives q eines Rings der Bin-Index i·Δq oder der Mittelwert von q im Ring verwendet wird

—— mit dem Bin-Index entsteht eine negative Abweichung von -0.0007 bis -0.0010 (gemessen, gleiche Fläche, gleiches

Anpassungsband). Die Richtung entspricht der Beobachtung im PoC, die Größe ist aber 1/15, daher

stammt der Rest der -0.013 nicht aus der Diskretisierung des Ringmittels, sondern aus anderen Implementierungsunterschieden jener Funktion.

Diese Funktion gibt den Mittelwert von q im Ring zurück.

★ Falle —— Ringe jenseits von Nyquist bestehen "nur aus Ecken"

Das maximale |q| eines quadratischen Gitters ist √2/(2 dx), aber Ringe mit q > 1/(2 dx)

enthalten nur die vier Ecken der Frequenzebene. Gemessen (512²): von allen 362 Bins sind die obersten

107 Bins (29.6 %) jenseits von Nyquist. Wie weit die Punktzahl im Ring hinter dem Idealwert 2πq/Δq zurückbleibt,

fällt schon unterhalb von Nyquist bis auf minimal das 0.838-fache

(Diskretisierung des Gitters), jenseits von Nyquist aber bis auf 0.

Für die Anpassung der Steigung nichts jenseits von Nyquist verwenden.

★ Wie weit man der Parseval-Gegenprobe trauen darf (gemessen, 512², Sq²=6.400e-03)

• Σ C_2D Δqx Δqy über das volle 2-D-Gitter ergibt +0.0000 % (exakt).

• Trapezintegration der zurückgegebenen Radial-PSD ergibt -0.55 %. Dieser Anteil geht verloren, sobald ringweise gemittelt und auf 1-D zusammengedrückt wird —— das Ringmittel ist eine Zusammenfassung und nicht umkehrbar. Wo Genauigkeit über 0.5 % hinaus nötig ist, die 2-D- C_2D selbst integrieren.

• Bei dieser Fläche liegt die obere Bandgrenze bei Nyquist, daher bleibt es bei Abschneiden an Nyquist bei -0.55 % unverändert (die Ecken haben keinen Inhalt). Bei Flächen mit Inhalt in den Ecken (Band jenseits von Nyquist) fehlt beim Abschneiden etwas.

fail-closed

• Nicht 2-D / kleiner als 8x8 / enthält NaN oder Inf / dx, dy nicht positiv.

• kind ist weder "areal" noch "radial".

Ausführlicher Anwendungsleitfaden

• Leitfaden zur Familie surface_roughness

Referenzen (Beispieldaten, Literatur)

• Katalog der Beispieldaten (Download-URLs / Lizenzen) — 2-D nutzt skimage.data (BSD/Public Domain) plus synthetische Bilder, 3-D nennt Download-URLs echter Datenquellen (Stanford, PDS, …).

• Herkunft und Literatur der Operatoren — die Quellen der Forschung/Verfahren, auf denen diese Operatorfamilie beruht.

• Der kanonische Algorithmus (Autor, Jahr) und seine Anwendungen stehen im Familienleitfaden oben.

Ausführbare Beispiele (verifizierte Samples, die diesen Operator wirklich aufrufen)

• poc_surface_roughness — py -3.11 examples/poc_surface_roughness.py

Typkompatible Folge-Operatoren (nehmen pairs als Eingabe)

—

Gleiche Kategorie (measure)

surface_params · profile_params


*Provenance: roughness.py — ROUGHNESS Operator-Registry. Diese Notiz wird von tools/opdocs.py md erzeugt (nicht von Hand bearbeiten).*

© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.