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" के अलावा।
• surface_roughness family guide
• 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 में दिए गए हैं।
• poc_surface_roughness — py -3.11 examples/poc_surface_roughness.py
pairs को input के रूप में लेते हैं)—
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.