synth_starfield — ASTROSTACK synth op

• Datenarten: keine → image2d (ein Operator, der allein durch seine Argumente bestimmt ist — er nimmt kein Bild und keine Daten entgegen)

• Aufruf: import fullseye as fs; fs.ledger.synth_starfield(shape=(128, 128), n_stars=30, flux_min=400.0, flux_max=9000.0, fwhm_px=3.2, psf='gaussian', moffat_beta=2.5, sky=60.0, read_sigma=6.0, shift_row=0.0, shift_col=0.0, n_cosmic=0, cosmic_flux=4000.0, margin_px=6.0, seed=0, field_seed=None, noise=True) (die Implementierung direkt: import astrostack; astrostack.synth_starfield(shape=(128, 128), n_stars=30, flux_min=400.0, flux_max=9000.0, fwhm_px=3.2, psf='gaussian', moffat_beta=2.5, sky=60.0, read_sigma=6.0, shift_row=0.0, shift_col=0.0, n_cosmic=0, cosmic_flux=4000.0, margin_px=6.0, seed=0, field_seed=None, noise=True); aus dem Register: opsastrostack.get("synth_starfield"))

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

• Rückgabe der Funktion: (frame, truth) -> image2d

Verwendung

Synthetisiert ein bekanntes Sternfeld — die Quelle der Ground Truth dieser Familie.

Jeder Stern zieht seinen Gesamtfluss (Elektronen) aus einer log-gleichförmigen Verteilung über flux_min–flux_max und wird gleichförmig mindestens margin_px innerhalb des Bildrands platziert. Ist *psf* "gaussian", ist es ein exaktes Pixelintegral über scipy.special.erf, sodass die Summe von 1 Stern exakt dem vorgegebenen Fluss entspricht (abgesehen vom Anteil außerhalb des Bildes). "moffat" ist (1 + (r/alpha)^2)^(-beta) aus Moffat, *A Theoretical Investigation of Focal Stellar Images*, A&A 3, 455 (1969), das Standardmodell für Sternbilder, die von der bodengebundenen Atmosphäre dominiert sind (das beugungsbegrenzte Geschwister ist optics.airy_pattern).

Das Rauschen folgt nur 1 Theorie —— auf Poisson(Stern + sky) (Aufruf von photoncount.photon_sample mit photons_per_unit=1.0) werden danach kosmische Strahlen addiert und zuletzt additives gaußsches Ausleserauschen read_sigma. Die Reihenfolge folgt der Physik:

kosmische Strahlen sind keine Photonen (sie durchlaufen keine Poisson-Abtastung). Die Positionen der kosmischen Strahlen übernimmt der gleichförmige Punktprozess von defectgen.defect_pits —— "seltene, kleine, scharfe Ablagerungen an zufälligen Positionen" haben dieselbe stochastische Geometrie wie Lochfraß, es gibt also keinen Grund, ein zweites Modell zu schreiben.

*shift_row* / *shift_col* verschieben das ganze Sternfeld um Subpixel (Dithering). Die synthetisierten Ground-Truth-Koordinaten verschieben sich entsprechend, daher eignet es sich zur Gegenprobe von Registrierung und Drizzle.

Returns (frame, truth):

• frame —— (H, W) float64, Einheit Elektronen.

• truth —— dict. rows / cols (N,) sind die wahren Sternzentren (Konvention: ganzzahlige Koordinaten sind Pixelzentren), fluxes (N,) die wahren Gesamtflüsse, fwhm_px / sigma_px / alpha_px / beta die PSF, sky / read_sigma das Rauschen, cosmic_mask (H, W) bool die Pixel mit kosmischer Strahlung, noiseless (H, W) der Erwartungswert vor dem Rauschen (zur Gegenprobe).

Es gibt 2 seeds. field_seed bestimmt das Sternfeld (Koordinaten und Flüsse), seed die jeweilige Beobachtung (Schrotrauschen, Ausleserauschen, Positionen der kosmischen Strahlung). Bei field_seed=None gilt derselbe Wert wie seed. Der Grund für die Trennung ist ein bei Messungen gefundener Unfall: In der ersten Version mit 1 seed

änderte synth_frame_series seed pro Frame, mit dem Ergebnis, dass das Sternfeld selbst in jedem Frame ein anderes war, die Registrierung nur 1 Korrespondenz fand (frame_align hat korrekt fail-closed abgebrochen) und die Entfernung kosmischer Strahlung über Frames hinweg "jedes Pixel ist ein Ausreißer" lieferte. Denselben Himmel erneut aufzunehmen und einen anderen Himmel aufzunehmen, lässt sich durch 1 Argument verwechseln —— daher die Trennung über den Namen, nicht über den Typ. Beide Zufallsgeneratoren sind numpy.random.default_rng, daher ergibt dasselbe seed-Paar auf jeder Maschine denselben Frame.

Ground truth it reproduces (fixiert in tests/test_astrostack.py):

Bei einem 1-Stern-Frame mit noise=False, sky=0, fwhm_px=3.0 (64x64, Fluss 5000 e-) ist der relative Fehler zwischen der Summe über das ganze Bild und dem vorgegebenen Fluss 1.8e-16 —— 1 float64-Rundung: nicht "nahezu erhalten", sondern erhalten. Der Anteil, den eine kreisförmige Apertur mit Radius r erfasst, ist 1 - exp(-r^2/(2 sigma^2)):

0.8647 bei r = 2 sigma, 0.98889 bei r = 3 sigma.

Raises ValueError: *shape* zu klein / *n_stars* keine nichtnegative ganze Zahl / flux_min > flux_max / *psf* nicht in PSF_MODELS / moffat_beta <= 1 (das Integral divergiert) / margin_px größer als das Bild / *seed* keine nichtnegative ganze Zahl.

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)

• astro_stacking — py -3.11 examples/astro_stacking.py

• poc_astro_photometry — py -3.11 examples/poc_astro_photometry.py

Typkompatible Folge-Operatoren (nehmen image2d als Eingabe)

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

Gleiche Kategorie (synth)

synth_frame_series


*Provenance: astrostack.py — ASTROSTACK 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.