thin_film_reflectance — OPTICS appearance op

• Datenarten: signal → signal

• Aufruf: import fullseye as fs; fs.ledger.thin_film_reflectance(nm, thickness_nm=350.0, n_film=1.33, n_sub=1.0, cos_theta=1.0, n_out=1.0, polarization='unpolarized', under_layers=()) -> 'np.ndarray' (die Implementierung direkt: import matappear; matappear.thin_film_reflectance(nm, thickness_nm=350.0, n_film=1.33, n_sub=1.0, cos_theta=1.0, n_out=1.0, polarization='unpolarized', under_layers=()) -> 'np.ndarray'; aus dem Register: opsoptics.get("thin_film_reflectance"))

Verwendung

Der spektrale Reflexionsgrad eines dünnen Films (Dicke d, Index n_film). Die exakte Lösung mit der charakteristischen Matrix (alle Mehrfachreflexionen eingeschlossen).

nm: Wellenlänge [nm] (Array erlaubt).

thickness_nm: Schichtdicke [nm]. 200–800 für eine Seifenblase, 50–300 für eine Eloxalschicht. Ein mit nm broadcastbares Array

ist ebenfalls erlaubt (ein Dickenfeld; z. B. (H, W, 1) Dicken und (K,) Wellenlängen → (H, W, K)).

n_film/n_sub: Brechzahl von Schicht / Substrat. Wahlweise eine reelle Zahl, ein komplexes n + ik (k ≥ 0; Metallsubstrate

und absorbierende Schichten), ein Materialname (gemeinsame Materialtabelle materials, z. B. "TI" / "AL" / "SI" ——

deren n,k bei jeder Wellenlänge), ein Materialdatensatz (dict) oder ein mit nm broadcastbares Array je Wellenlänge (Dispersion der Schicht).

cos_theta: cos des Einfallswinkels auf der Einfallsseite (Array erlaubt, in einer mit nm broadcastbaren Form).

n_out: Brechzahl der Einfallsseite (reelle Zahl oder Materialname, ohne Absorption).

polarization: "unpolarized" (Standard, Mittel aus s und p) / "s" / "p".

under_layers: Schichten zwischen Film und Substrat ([(Brechzahl, Dicke nm), ...] von der Einfallsseite aus; die Brechzahl wird wie

n_film geschrieben). Leer (Standard) bedeutet ein Einzelfilm. Für mehrlagige AR-Schichten, dielektrische Spiegel, Nitrid unter Oxid usw.

Rückgabewert: Reflexionsgrad R (0–1), in der Broadcast-Form von nm, thickness_nm und cos_theta.

★Vorzeichenkonvention: der komplexe Index ist N = n + ik mit k ≥ 0. Für eine Quelle, die N = n − ik schreibt, dasselbe k positiv übergeben (eine Eingabe mit negativem Imaginärteil löst ValueError aus —— die Konvention wird nicht geraten).

Physik: die charakteristische Matrix jeder Schicht [[cos δ, −i sin δ / η], [−i η sin δ, cos δ]], δ = 2π N d cosθ̃ / λ (das komplexe Snelliussche Gesetz liefert cosθ̃ in der Schicht, mit dem abklingenden Zweig), mit der geneigten optischen Admittanz η = N cosθ̃ (s) / N / cosθ̃ (p). Für eine Schicht ergibt das denselben Wert wie die Airy-Formel R = |r1 + r2 e^{2iβ}|² / |1 + r1 r2 e^{2iβ}|² (in Tests mit einer getrennt geschriebenen Formel verglichen). Die Reflexion ist bei ungeraden Vielfachen von λ/4 maximal (wenn n_film > n_sub), und mit der Dicke wandert die Farbe —— das ist die Farbe einer Seifenblase. Bei Schichtdicke 0 stimmt R mit der Fresnel-Reflexion des bloßen Substrats überein. Gerechnet wird an einer Stelle, der charakteristischen Matrix von filmoptics (dieselbe Funktion wie filmoptics.multilayer_reflectance).

★2026-10-14: Früher waren die drei Brechzahlen nur reell (eine komplexe Zahl löste TypeError aus). Ein Metallsubstrat reell genähert (angelaufenes Titan, 90 nm, mit n_sub = 2.6) ergab Reflexionsgrade von 0.15–0.19, mit dem n,k von Ti dagegen 0.35–0.61 (380–780 nm) —— ein stiller Fehler, der die Farbe in eine andere verwandelt. Jetzt bringt "TI" als Substrat das n,k der Materialtabelle ein.

>>> r = thin_film_reflectance([450.0, 550.0, 650.0], 90.0, "TIO2_AMORPHOUS", "TI")

>>> bool(r.min() > 0.3)

True

Familienweiter Eingabevertrag (fail-closed)

Jeder optics-Operator prüft seine Eingabe vor der Berechnung (nichts rutscht stillschweigend durch):

• Einheiten stecken im Argumentnamen — _mm / _um / _deg / _mrad. Eine Verwechslung von mm und µm stürzt nicht ab, sondern liefert eine plausibel aussehende falsche Antwort; der Name verhindert das. Aus der Größenordnung wird nie auf die Einheit geschlossen.

• Strings lösen ValueError aus — float('50') gelingt, sodass ein ungeparster Konfigurationswert als Länge durchrutschen würde (gemessen: thin_lens('50', '200') lieferte plausible 66,667 mm). bool wird als implizite Hochstufung True == 1 ebenfalls abgelehnt.

• complex / Masked Arrays lösen ValueError aus (nur reelle Slots; das stille Verwerfen des Imaginärteils bzw. Abstreifen der Maske wird abgelehnt). NaN/Inf löst bei jeder Eingabe ValueError aus.

• Division durch null und Verwandtes wird namentlich abgelehnt: Brennweite 0, Krümmungsradius 0, Brechzahl <= 0, undurchlässige Blende (alles 0, die Normierung wird 0/0), PSF mit Summe <= 0, Stokes-Vektor mit S0 = 0 und ein Objekt im vorderen Brennpunkt (Bild im Unendlichen).

• Nur zwei Operatoren liefern einen nicht-endlichen Wert, und beide halten das vertraglich fest: depth_of_field liefert jenseits der hyperfokalen Distanz far_mm = inf (genau das bedeutet die hyperfokale Distanz), und gaussian_beam liefert an der Taille wavefront_radius_mm = inf (der Krümmungsradius einer ebenen Wellenfront). Beide liefern zusätzlich einen endlichen Partner (far_is_infinite / curvature_per_mm). Jedes andere stille NaN/Inf wird intern erkannt und löst ValueError aus — "float64 ist übergelaufen" und "die Antwort ist unendlich" sind verschiedene Aussagen; die erste wird nie im Gewand der zweiten geliefert.

• Größenobergrenzen: erzeugte Gitter durch optics.MAX_GRID (4096), übergebene Felder/PSFs/Blenden durch optics.MAX_FIELD_ELEMENTS (2^24), ABCD-Elementketten durch optics.MAX_SYSTEM_ELEMENTS (1024), Zernike durch MAX_ZERNIKE_TERMS (512) / MAX_ZERNIKE_ORDER (40) / MAX_ZERNIKE_BASIS (2^25). Damit werden Pfade fail-closed geschlossen, in denen ein kleines Argument eine riesige interne Allokation auslöst (gemessen: n_max=40 × 4096² braucht 108 GB).

• Physikalisch unmögliche Zustände werden ebenfalls abgelehnt: Stokes-Vektor mit Polarisationsgrad > 1, negative Transmission, negative Intensität und ungültige Zernike-Indizes wie ungerades n-|m|.

Ausführlicher Anwendungsleitfaden

• Leitfaden zur Familie optics_imaging

Hintergrundwissen (Physik und Konventionen hinter diesem Operator)

• colorimetry — Farbmetrik und Spektren — Farbe ist nur durch Spektrum × Lichtart × Beobachter bestimmt

• mv_illumination_practice — Beleuchtung in der Praxis — Wellenlänge, Polarisation, Ansteuerung, Fremdlicht, Sicherheit

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)

• appearance_structural_colour — py -3.11 examples/appearance_structural_colour.py

• simcal_tour — py -3.11 examples/simcal_tour.py

Typkompatible Folge-Operatoren (nehmen signal als Eingabe)

emva_photon_transfer · emva_quantum_efficiency · emva_linearity_error · emva_snr_curve · emva_dark_current · emva_total_snr · emva_exposure_for_snr · emva_photon_exposure

Gleiche Kategorie (appearance)

cie_xyz_from_wavelength · spectrum_to_srgb · grating_wavelengths · grating_rgb · thin_film_rgb · ward_anisotropic


*Provenance: matappear.py — OPTICS 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.