surface_psd — ROUGHNESS measure op

• Data kinds: depth → pairs

• Call: import fullseye as fs; fs.ledger.surface_psd(z, dx, kind='areal', dy=None) (implementation को सीधे call करना हो तो import roughness; roughness.surface_psd(z, dx, kind='areal', dy=None), registry से लेना हो तो opsroughness.get("surface_psd"))

• Ledger के ज़रिए return value: fullseye.ledger.surface_psd(...) केवल घोषित out type pairs का value लौटाता है (मूल function सहायक जानकारी भी लौटाता है)। जो हिस्सा छोड़ दिया गया है उसकी ज़रूरत हो तो fullseye.ledger.surface_psd.raw(...) का उपयोग करें, या roughness.surface_psd को सीधे call करें।

• मूल function का return: (q, C) -> (N,2)

उपयोग

height field का power spectral density। (q, C) लौटाता है। परिपाटी argument से स्पष्ट की जाती है।

Arguments

z Height field (mean अंदर घटाया जाता है; DC bin नहीं लौटाया जाता)।

dx, dy Sample spacing। dy=None का अर्थ square pixels।

kind "areal" ... 2-D PSD C_2D(q) का ring average।

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

Conventions (इन्हें लिखे बिना इसे calibration के बिना पढ़ा नहीं जा सकता ―― मौजूदा radial_power_spectrum के docstring में ये नहीं हैं)

• q cycles / length में है (angular frequency 2π/λ नहीं)। q = 1/λ।

• C_2D(q) = dx dy |F|² / (ny nx)। Normalisation Parseval से मेल खाता है: ∫ C_2D d²q = <h²> और ∫ C_1D dq = <h²>।

• Self-affine surface H के लिए slope areal PSD में -2(H+1) और radial PSD में -2H-1 है (ठीक 1 का अंतर)।

★ Measured —— किसी भी convention में H calibration के बिना वापस मिलता है

surface_synth_psd से H डाला गया, q ∈ [2/λ_hi, 0.4/dx] पर log-log में सीधी रेखा fit की गई,

और H वापस निकाला गया (512², band 2-64 µm):

injected H areal PSD slope recovered H radial slope recovered H slope diff

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

सभी 4 स्थितियों में error ±0.0003 के अंदर है, और दोनों conventions के slope का अंतर

हर H के लिए ठीक 1.0000 है। Calibration के बिना पढ़ने लायक।

★ यहीं PoC को दोबारा मापने पर निष्कर्ष बदला। PoC ने मौजूदा

radial_power_spectrum से -0.013 (H का 1.6 %) का एक समान systematic error पाया था और

निष्कर्ष निकाला था कि यह "ring average के discretisation से systematic error" है। इसी implementation से

वही cross-check करने पर error गायब हो जाता है। कारण अलग करने पर पता चला कि यह ring के प्रतिनिधि q के रूप में bin index i·Δq या ring के अंदर q का mean इस्तेमाल करने का अंतर था

—— bin index से -0.0007 से -0.0010 का ऋणात्मक offset आता है (measured, समान surface, समान

fitting band)। दिशा PoC के observation से मेल खाती है लेकिन आकार 1/15 है, इसलिए

-0.013 का बाकी हिस्सा ring-average discretisation से नहीं बल्कि उस function के दूसरे implementation अंतरों से आता है।

यह function ring के अंदर q का mean लौटाता है।

★ गड्ढा —— Nyquist से आगे के rings "केवल corners" से बने होते हैं

Square grid का अधिकतम |q| √2/(2 dx) है, लेकिन q > 1/(2 dx) वाले rings

में frequency plane के केवल चार corners होते हैं। Measured (512²): सभी 362 bins में से ऊपर के

107 bins (29.6 %) Nyquist से आगे हैं। Ring में point count आदर्श 2πq/Δq से कितना कम पड़ता है,

यह Nyquist से नीचे भी कम से कम 0.838x तक गिरता है

(grid discretisation), लेकिन Nyquist से आगे 0 तक गिर जाता है।

Slope fit के लिए Nyquist से आगे के bins इस्तेमाल न करें।

★ Parseval cross-check पर कितना भरोसा किया जा सकता है (measured, 512², Sq²=6.400e-03)

• पूरे 2-D grid पर Σ C_2D Δqx Δqy लेने से +0.0000 % मिलता है (exact)।

• लौटाए गए radial PSD का trapezoidal integration -0.55 % देता है। यह मात्रा उसी क्षण खो जाती है जब data को हर ring पर औसत करके 1-D में समेटा जाता है —— ring average एक सारांश है और invertible नहीं है। 0.5 % से बेहतर accuracy चाहने वाले इस्तेमाल के लिए, 2-D C_2D को खुद integrate करें।

• इस surface का band Nyquist पर ख़त्म होता है, इसलिए Nyquist पर truncate करने से यह -0.55 % पर ही बना रहता है (corners में कोई content नहीं)। जिन surfaces के corners में content है (Nyquist से आगे का band), उनमें truncation से वह खो जाता है।

fail-closed

• 2-D नहीं / 8x8 से छोटा / NaN या Inf शामिल / dx, dy धनात्मक नहीं।

• kind "areal" या "radial" के अलावा।

उपयोग की विस्तृत guide

• surface_roughness family guide

संदर्भ (sample data, साहित्य)

• Sample data catalog (DL URL / license) — 2-D के लिए skimage.data (BSD/public) + synthetic, 3-D के लिए real data sources (Stanford/PDS आदि) के DL URL।

• Operators का स्रोत और संदर्भ — इस op family के मूल research/methods के स्रोत।

• Algorithm का मानक स्रोत (लेखक, वर्ष) और उपयोग ऊपर की family usage guide में दिए गए हैं।

चलाए जा सकने वाले उदाहरण (verified samples जो सच में यह op call करते हैं)

• poc_surface_roughness — py -3.11 examples/poc_surface_roughness.py

वे अगले ops जिनसे type जुड़ता है (pairs को input के रूप में लेते हैं)

—

इसी category के (measure)

surface_params · profile_params


*Provenance: roughness.py — ROUGHNESS operator registry. यह per-op note tools/opdocs.py md से अपने-आप generate होता है (हाथ से edit न करें)।*

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