synth op• Data kinds: कोई नहीं → depth (केवल arguments से तय होने वाला op — यह कोई image या data input नहीं लेता)
• Call: import fullseye as fs; fs.ledger.surface_synth_psd(n, dx, hurst, lambda_lo, lambda_hi, sq, seed=0) (implementation को सीधे call करना हो तो import roughness; roughness.surface_synth_psd(n, dx, hurst, lambda_lo, lambda_hi, sq, seed=0), registry से लेना हो तो opsroughness.get("surface_synth_psd"))
• Ledger के ज़रिए return value: fullseye.ledger.surface_synth_psd(...) केवल घोषित out type depth का value लौटाता है (मूल function सहायक जानकारी भी लौटाता है)। जो हिस्सा छोड़ दिया गया है उसकी ज़रूरत हो तो fullseye.ledger.surface_synth_psd.raw(...) का उपयोग करें, या roughness.surface_synth_psd को सीधे call करें।
• मूल function का return: (z, sq_analytic)
दिए गए PSD से height field synthesize करता है। (z, sq_analytic) लौटाता है।
Band lambda_lo <= λ <= lambda_hi के हर mode पर amplitude A(q) ∝ q^-(H+1) (= areal PSD C(q) ∝ q^-2(H+1), self-affine) रखता है और केवल phases को random करता है। पूरे को sq पर normalize करके लौटाता है।
Arguments
n grid का आकार। पूर्णांक देने पर n x n; (ny, nx) भी स्वीकार है।
dx sampling interval (square pixels)।
hurst Hurst exponent H (0 < H < 1)। बड़ा मान = ज़्यादा smooth।
lambda_lo band के छोटे सिरे की wavelength।
lambda_hi band के लंबे सिरे की wavelength।
sq लक्ष्य Sq (band के अंदर rms height)।
seed phases के लिए random seed।
★ Analytic Sq को साथ में लौटाना ही मुख्य बात है
चूँकि amplitudes तय हैं और केवल phases बदलते हैं, Parseval से
<h²> = (1/(ny nx))² Σ_k A_k² phases कैसे भी चुने जाएँ तय रहता है।
यानी Sq का ground truth random numbers पर निर्भर नहीं करता। Measured: z.std() और
sq_analytic का relative अंतर, seed, H, band और size बदलने पर भी,
अधिकतम 2.2e-16 है (नीचे की table)। अगर इसे "random numbers बदलकर rms मापो" से तय किया जाए,
तो ground truth खुद हर realization पर बिखरता है और downstream errors के साथ मिल जाता है।
n H λ band sq |std/analytic-1| kurtosis PTV/rms
128 0.30 4-32 0.5000 2.2e-16 3.084 7.97
256 0.50 4-64 0.0800 0.0e+00 3.005 7.85
256 0.80 2-64 0.0800 2.2e-16 2.893 6.92
512 0.80 2-64 0.0800 0.0e+00 3.113 8.25
512 0.95 8-256 2.0000 0.0e+00 2.542 5.69
★ PoC जिस गड्ढे में गिरा था, उसे implementation के अंदर बंद कर दिया गया है
अगर coefficients को Hermitian बनाने के लिए phase को phi = (u - u[-k]) / 2 से antisymmetric बनाया जाए,
तो यह antisymmetric तो बनता है, लेकिन phase अब uniform नहीं रहता
(यह 0 के पास इकट्ठा होने वाला triangular distribution बन जाता है)। तब सभी modes origin पर एक ही phase में जुड़ते हैं
और height field में 1 spike उठ जाता है। समान seed और समान band पर measured
(512², H=0.8, band 2-64):
phase construction PTV/rms kurtosis |std/analytic-1|
antisymmetrized by (u - u[-k])/2 55.00 71.81 0.0e+00
uniform random on one of each pair 8.47 2.95 0.0e+00 ← सही
दोनों analytic Sq से बिल्कुल मेल खाते हैं। इस तरह की खराबी केवल variance देखने पर
दिखती नहीं, इसलिए यह function उसी implementation पर तय है जो हर conjugate pair में से केवल एक के लिए
uniform random numbers लेता है, और tests kurtosis और PTV/rms भी जाँचते हैं। Self-conjugate modes
(k = -k, 4 points) के coefficients real होने चाहिए, इसलिए phase की बजाय
sign ±1 को random किया जाता है (phase को 0 पर तय करने से सभी +A की ओर bias हो जाते)।
fail-closed
• n 8 से कम / dx धनात्मक नहीं / hurst (0, 1) के बाहर।
• lambda_lo >= lambda_hi।
• lambda_lo Nyquist wavelength 2*dx से नीचे (असंभव band)।
• lambda_hi evaluation length से ज़्यादा (1 period भी नहीं समाता)।
• sq धनात्मक नहीं।
• Band में 1 भी mode नहीं आता (grid बहुत मोटा / band बहुत संकरा)।
• 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_polish_wipe_measure — py -3.11 examples/poc_polish_wipe_measure.py
• poc_surface_roughness — py -3.11 examples/poc_surface_roughness.py
depth को input के रूप में लेते हैं)surface_form_remove · surface_filter · surface_params · surface_psd
synth)—
*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.