drizzle_resample — ASTROSTACK stack op

• Data kinds: images → image2d

• Call: import fullseye as fs; fs.ledger.drizzle_resample(frames, shifts=None, scale=2.0, pixfrac=1.0) (implementation को सीधे call करना हो तो import astrostack; astrostack.drizzle_resample(frames, shifts=None, scale=2.0, pixfrac=1.0), registry से लेना हो तो opsastrostack.get("drizzle_resample"))

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

• मूल function का return: (sci, wht) -> image2d

उपयोग

Drizzle — sub-pixel खिसके कई frame से बारीक grid बनाता है (क्षेत्रफल संरक्षित)।

Fruchter & Hook, *Drizzle: A Method for the Linear Reconstruction of Undersampled Images*, PASP 114, 144 (2002)। हर इनपुट pixel को थोड़ा सिकुड़ा हुआ "drop" (भुजा pixfrac) माना जाता है, और उसका flux आउटपुट grid के pixels के साथ overlap area के अनुपात में बाँटा जाता है। क्योंकि कुछ भी interpolate नहीं किया जाता,

• कुल flux संरक्षित रहता है। जब तक drops आउटपुट grid के अंदर रहते हैं, sci.sum() इनपुट frames के कुल योगों के mean के ठीक बराबर होता है (मापा गया: shifts=0, scale=2, pixfrac=0.7 के साथ relative error 0.0)। इसीलिए इसे इस तरह बनाया गया है कि केवल return value से cross-check किया जा सके।

• pixfrac जितना छोटा होगा, हर drop का उतना बड़ा अंश एक ही आउटपुट pixel के अंदर पड़ेगा: resolution बढ़ता है, लेकिन कुछ आउटपुट pixels ढके नहीं रहते (वहाँ wht छोटा हो जाता है)। यह खींचतान drizzle का एकमात्र tuning knob है।

यह केवल तब मदद करता है जब sampling अपर्याप्त हो — यही मापा गया निष्कर्ष है। 48x48, 10 तारे, dithering 1.5 px, 16 frames (मान इनपुट pixels में बदले गए FWHM हैं)::

true FWHM single frame plain mean drizzle x2 (pixfrac=0.5)

1.0 1.773 2.249 1.312

1.3 1.929 2.876 1.572

1.8 2.262 2.648 3.086

2.5 4.057 4.295 3.586

Drizzle केवल वहीं जीतता है जहाँ FWHM 2 pixels से नीचे जाता है (Nyquist का उल्लंघन)। dithered frames का सादा औसत लेने से image वास्तव में धुंधली हो जाती है (1.773 → 2.249) —— क्योंकि offsets औसत में मिट जाते हैं; drizzle उन्हीं offsets को resolution में बदल देता है। 1.8 px और उससे ऊपर image पहले से पर्याप्त रूप से sampled है, इसलिए drizzle को कुछ नहीं मिलता और drop के साथ convolution से केवल नुकसान होता है।

इसे सबसे आसानी से इस बात में देखा जा सकता है कि दो तारे अलग पहचाने जाते हैं या नहीं। σ=0.55 px के 2 तारे अलग-अलग दूरियों पर, 16 frames में dithered, mean से और drizzle x3 (pixfrac=0.4) से stack किए गए, फिर star_detect से मापा गया: 1.6 इनपुट pixels की दूरी पर, mean stack को 1 मिला, drizzle को 2 मिले (2.0 px और उससे ऊपर दोनों को 2 मिलते हैं)।

*shifts* (dr, dc) का (N, 2) है: frame i reference से कितना खिसका हुआ है (synth_frame_series का truth["shifts"] यही दिशा उपयोग करता है)। None का अर्थ सभी 0 है।

★ चिह्न का ध्यान रखें —— frame_align / align_frames द्वारा लौटाए गए matrix का translation उस दिशा में है जो frame को reference पर वापस लाती है, यानी यहाँ आवश्यक (dr, dc) उलटे चिह्न के साथ। अनुमान को जैसा है वैसा देने से offset रद्द नहीं होता बल्कि दोगुना हो जाता है, और बिना exception उठाए double image बनती है (मापा गया: 96x96 के 6 frames est + truth ≈ 0 देते हैं; जैसा है वैसा देने से residual 2 गुना बड़ा हो जाता है)। matrix से सही दिशा वाले shifts बनाने के लिए drizzle_shifts उपयोग करें। Rotation स्वीकार नहीं है —— rotation के साथ axes अलग नहीं रहते और overlap area का कोई closed form नहीं होता, इसलिए पहले align_frames से उसे हटाएँ (interpolation error वहीं चुकाते हुए; उस सौदे को दिखाई देता रखना अधिक ईमानदार है)।

★ इनपुट pixel आउटपुट में कहाँ पहुँचता है (यह convention पहले लिखी नहीं गई थी)। pixel केंद्रों के मेल से::

out = in * scale + (scale - 1) / 2

scale=2 के साथ इनपुट (8, 8) पर स्थित तारा आउटपुट (16.5, 16.5) पर होता है। इनपुट pixel in द्वारा ढका अंतराल [in, in+1) आउटपुट में [in*scale, (in+1)*scale) पर map होता है, और उसका केंद्र ऊपर का सूत्र है —— केवल in*scale नहीं। आधा pixel छोड़ देने से, scale=4 पर, 1.5 आउटपुट pixels यानी 0.375 इनपुट pixels का systematic offset आता है, और registration के बाद photometry तथा double-star दूरियाँ ठीक उतनी ही चुपचाप गलत हो जाती हैं।

मापा गया (24x24, single-pixel तारा, pixfrac=1, centroid से मापा गया): scale 2 / 3 / 4 के लिए सूत्र से अंतर ठीक 0 है। scale=2.5 पर यह 0.05 आउटपुट pixels से हटता है, लेकिन यह सूत्र की त्रुटि (error) नहीं है: किनारे के आउटपुट pixels केवल आंशिक रूप से ढके होते हैं, इसलिए indices पर centroid continuous centroid से हट जाता है (integer factors के साथ यह शेष नहीं आता)। जब स्थितियाँ exact होनी चाहिए, तो integer scale उपयोग करें।

(sci, wht) लौटाता है:

• sci —— (round(H*scale), round(W*scale)) float64, total-flux इकाइयों में (इनपुट जैसे ही electrons)। grid से बाहर जाने वाले drops योग घटाते हैं, इसलिए sci.sum() और इनपुट कुल के बीच का अंतर ठीक "किनारों पर खोई मात्रा" है।

• wht —— समान shape का weight map: हर आउटपुट pixel को कितने drops जितना ढकते हैं (आउटपुट pixel area = 1)। pixfrac=1 और shifts=0 के साथ अंदरूनी भाग ठीक 1.0 होता है।

★ देखते / मापते समय sci / wht उपयोग करें। कुल flux संरक्षित रखने के लिए sci "बाँटी गई मात्रा" को जैसा है वैसा रखता है, इसलिए coverage की असमानता image में बनी रहती है। छोटे pixfrac के साथ coverage grid pattern में असमान होती है, इसलिए raw sci पर detection चलाने से वह grid तारों में बदल जाता है —— मापा गया (scale=3, pixfrac=0.4, 1 double star के 24 frames): star_detect ने raw sci पर 200 लौटाए (cap पर अटका) और sci / wht पर सही ढंग से 2। संरक्षण मात्रा (sci) और दिखावट (sci / wht) अलग-अलग मात्राएँ हैं; एक की जगह दूसरी उपयोग करना बिना किसी अपवाद के गलत है।

Raises ValueError: यदि *frames* list / tuple नहीं / shapes मेल नहीं खाते / *scale* 1 से कम है / *pixfrac* (0, 1] से बाहर है / *shifts* shape (N, 2) का नहीं / आउटपुट MAX_OUTPUT_ELEMENTS से अधिक है।

संदर्भ (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 करते हैं)

• astro_stacking — py -3.11 examples/astro_stacking.py

• poc_astro_photometry — py -3.11 examples/poc_astro_photometry.py

• poc_superresolution_limits — py -3.11 examples/poc_superresolution_limits.py

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

frame_quality · noise_sigma · cosmic_ray_reject · star_detect · psf_fit · aperture_photometry · frame_align

इसी category के (stack)

sigma_clip_stack


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

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