# finiSCOPE

**Welche deiner gestackten Versionen ist wirklich die beste?**

*[English version: README_EN.md](README_EN.md)*

finiSCOPE nimmt mehrere gestackte TIFFs derselben Aufnahme — verschiedene
Frame-Prozentsätze, verschiedene Noise-Robust-Stufen, mit und ohne Drizzle —
misst sie alle nach denselben Regeln und sagt dir in einem Satz, welche
Version gewonnen hat und warum.

Statt am Bildschirm hin- und herzuklicken und zu raten, bekommst du Zahlen,
Kurven und ein Urteil in verständlichem Deutsch.

Gebaut für Sonne (H-Alpha und Weißlicht), Mond und Planeten.

> **Kostenlos, ohne Gewähr, Nutzung auf eigene Verantwortung.**
> finiSCOPE steht unter der MIT-Lizenz (siehe [LICENSE](LICENSE)) und darf
> frei weitergegeben werden. Eine Haftung für Schäden ist ausgeschlossen.

---

## Inhalt

1. [Fertige App herunterladen und starten](#1-fertige-app-herunterladen-und-starten)
2. [Bedienung](#2-bedienung)
3. [Die Messwerte — in einfachem Deutsch](#3-die-messwerte--in-einfachem-deutsch)
4. [Die zwei Bewertungen](#4-die-zwei-bewertungen)
5. [Der Punktescore (Platz)](#5-der-punktescore-platz)
6. [Objekt-Profile](#6-objekt-profile)
7. [Drizzle, .as3 und Sessions](#7-drizzle-as3-und-sessions)
8. [Aus dem Quelltext starten](#8-aus-dem-quelltext-starten)
9. [Die Programme selbst bauen](#9-die-programme-selbst-bauen)
10. [Wenn etwas nicht geht](#10-wenn-etwas-nicht-geht)
11. [Aufbau des Projekts](#11-aufbau-des-projekts)
12. [Farben](#12-farben)
13. [Getroffene Annahmen](#13-getroffene-annahmen)

---

## 1. Fertige App herunterladen und starten

Wer die fertigen Programme benutzt, braucht **kein Python** und muss nichts
installieren. Python steckt komplett in der App drin.

### macOS

1. `finiSCOPE.app` herunterladen und in den Ordner **Programme** ziehen.
2. **Beim allerersten Start:** nicht doppelklicken, sondern
   **Rechtsklick auf die App → Öffnen → im Hinweisfenster nochmals Öffnen**.

   Warum? Die App ist nicht bei Apple registriert (das kostet eine
   jährliche Entwicklergebühr). macOS blockiert deshalb den normalen
   Doppelklick und meldet, die App stamme von einem *unbekannten
   Entwickler*. Über Rechtsklick → Öffnen lässt sich das einmalig
   bestätigen. Danach startet die App ganz normal per Doppelklick.

3. Falls macOS meldet, die App sei **beschädigt**: das passiert, wenn die
   Datei aus dem Netz geladen wurde. Einmalig im Terminal:

   ```bash
   xattr -dr com.apple.quarantine /Applications/finiSCOPE.app
   ```

Die App läuft ab macOS 11 auf Apple-Silicon-Macs (M1 bis M4). Für ältere
Intel-Macs muss sie auf einem Intel-Mac gebaut werden — siehe
[Abschnitt 9](#9-die-programme-selbst-bauen).

### Windows

1. Die ZIP-Datei herunterladen und **vollständig entpacken**, zum Beispiel
   nach `C:\Programme\finiSCOPE`.
   Wichtig: den ganzen Ordner entpacken, nicht nur die `.exe` herausziehen —
   sie braucht die Dateien daneben.
2. `finiSCOPE.exe` doppelklicken.
3. **Beim ersten Start** meldet sich der Windows-Defender-SmartScreen mit
   *„Der Computer wurde durch Windows geschützt"*. Das ist normal bei
   Programmen ohne gekauftes Signaturzertifikat:

   → **„Weitere Informationen"** anklicken
   → **„Trotzdem ausführen"**

   Ab dem zweiten Start kommt die Meldung nicht mehr.

---

## 2. Bedienung

**1 · Bilder laden.** Die gestackten TIFFs ins Fenster ziehen — einzeln,
mehrere auf einmal oder gleich einen ganzen Ordner. Alternativ
*Dateien wählen*. Sinnvoll sind zwei oder mehr Versionen **derselben
Aufnahme**.

**2 · Objekttyp wählen.** Sonne, Mond oder Planet. Damit wechseln die
Messgrenzen und die Größe des Auswertefensters.

**3 · Optional: Optik eintragen.** Pixelgröße (µm), Brennweite (mm) und
Öffnung (mm).

Diese Angaben ändern **weder die Messung noch den Score** — sie schalten
zusätzliche Aussagen frei, die ohne sie unmöglich sind:

| Eingetragen | Was du zusätzlich bekommst |
|---|---|
| Pixelgröße + Brennweite | **Sampling** in Bogensekunden pro Pixel und die effektive Auflösung deiner Aufnahme in Bogensekunden |
| zusätzlich die Öffnung | **% vom Optimum** — wie nah die Aufnahme am theoretischen Auflösungsvermögen liegt, und die Einordnung des Samplings als *gut* / *zu grob* / *zu fein* |

Bleiben die Felder leer, läuft alles andere unverändert; es fehlen nur diese
Zeilen. **Automatisch befüllen lässt sich das leider nicht** — weder das
TIFF noch die `.as3` von AutoStakkert enthalten solche Angaben. Dafür merkt
sich finiSCOPE die Werte: einmal eintragen genügt, beim nächsten Start
stehen sie wieder da.

Typische Werte: Pixelgröße steht im Datenblatt der Kamera (z. B. 2,9 µm bei
ASI 174/178, 3,76 µm bei ASI 183). Brennweite inklusive Barlow. Öffnung ist
der Durchmesser des Teleskops.

**4 · Ergebnis lesen.**

* **Sieger-Box oben:** die beste Version mit Begründung in einem Satz.
* **Bildansicht:** das Bild mit dem Auswertefenster als blauem Rechteck.
  Rechts daneben, an fester Stelle, der Inhalt dieses Fensters in
  **Originalgröße**. Version umschalten, und dort erscheint dieselbe Stelle
  aus der anderen Aufnahme. So vergleichst du mit dem Auge genau das, was
  auch gemessen wurde — die Zahlen sagen, *was* besser ist, dieser
  Ausschnitt zeigt, *wie* es aussieht.
* **Diagramm:** eine Kurve je Bild, darunter ein **Satz in Klartext**, der
  sagt, was zu sehen ist — etwa „Die Kurven liegen fast übereinander, der
  Unterschied liegt beim Rauschen". Gerade wenn zwei Versionen fast gleich
  scharf sind, liegen die Kurven aufeinander und man sieht scheinbar
  nichts; dann ist dieser Satz die eigentliche Antwort.
* **Tabelle:** zwei Bewertungen nebeneinander — **Qualität** (absolut, mit
  Ampel) und **Platz** (der Vergleich untereinander). Zeile anklicken öffnet
  die Rohwerte und einen längeren Klartext. **✕ Entfernen** am Zeilenende
  nimmt eine Aufnahme wieder aus dem Vergleich; die Datei auf der Festplatte
  bleibt unangetastet.

Auch die aufgeklappten **Rohwerte** sind eingefärbt und haben jeweils ein
(i) mit einer Erklärung, was ein guter Wert ist.

Die Messwerte in der Tabelle sind ebenfalls eingefärbt: **grün** heißt praktisch
gleichauf mit dem besten Bild des Laufs, neutral heißt leicht dahinter,
warm heißt deutlich schlechter. Beim Rauschabstand gilt die Farbe
**absolut** — sie hängt nicht davon ab, was sonst geladen ist.

**Zwischen den Versionen wechseln** geht auf drei Wegen: die
Miniaturleiste über der Bildansicht, eine Tabellenzeile anklicken, oder mit
den **Pfeiltasten ← →**. Bild, Lupe und hervorgehobene Kurve springen
jeweils mit.

**5 · Auswertebereich anpassen.** Standardmäßig sucht finiSCOPE
automatisch die **detailreichste Region** — nicht stur die Bildmitte. Bei
einer Vollscheibe landet das Fenster damit von selbst auf einer aktiven
Region oder Fleckengruppe statt auf ruhiger Oberfläche.

Gesucht wird nicht im ersten Bild, sondern im **Mittelwert aller geladenen
Bilder**. Damit hängt die Stelle nicht davon ab, welche Datei zufällig
zuerst geladen wurde, und sie liegt dort, wo alle Versionen Struktur
zeigen. Das Fenster ist anschließend für alle Bilder dasselbe.

Weicht eine Aufnahme stark ab — andere Bildgröße, ganz andere Helligkeit —
kann sie nicht beitragen und finiSCOPE weist in der Hinweisleiste darauf
hin, dass die Bilder vermutlich nicht zusammengehören.

Willst du eine bestimmte Stelle bewerten, ziehe in der Bildansicht mit
gedrückter Maustaste ein Rechteck. Während des Ziehens steht die Größe in
Pixeln daneben. Das Fenster ist immer **quadratisch** — das verlangt die
Frequenzanalyse — und wird auf die **Mitte** des gezogenen Bereichs gelegt.

Ist das Fenster gesetzt, lässt es sich nachjustieren:

* **hineinziehen** verschiebt es,
* an einer **Ecke ziehen** ändert die Größe,
* vorher **hineinzoomen** macht das Setzen beliebig genau.

Der Bereich gilt für **alle** Bilder gleich — nur so ist der Vergleich fair.
Mit dem Haken *nur dieses Bild* gilt er ausnahmsweise nur für die gewählte
Aufnahme. *Bereich zurücksetzen* schaltet zurück auf die Automatik.

**Versatz zwischen den Aufnahmen** gleicht finiSCOPE dabei selbst aus.
Zwei Stacks derselben Session liegen fast nie pixelgenau übereinander — die
Sonne wandert, AutoStakkert setzt das Alignment anders auf. Ist der Haken
*Versatz ausgleichen* gesetzt (Standard), wird das Auswertefenster in jedem
weiteren Bild automatisch dorthin geschoben, wo derselbe Bildinhalt liegt.
Der gefundene Versatz steht in den Rohwerten der jeweiligen Zeile.

**6 · Im Bild zoomen.** Mausrad oder Zwei-Finger-Wischen zoomt bis 12×,
immer auf die Stelle unter dem Zeiger. Verschieben mit gedrückter
**Alt-Taste** (oder mittlerer Maustaste), **Doppelklick** zeigt wieder das
ganze Bild. Der Zoom bleibt beim Wechsel zwischen den Versionen erhalten —
so springst du zwischen zwei Stacks derselben Stelle hin und her und siehst
den Unterschied direkt.

**7 · Speichern.** *CSV* schreibt alle Rohwerte (mit Semikolon, öffnet
direkt in Excel). *HTML-Report* erzeugt eine einzelne, in sich geschlossene
Datei mit Bildern, Diagramm und Urteilen — verschickbar und archivierbar.

### Die beiden Diagramm-Ansichten

Oben rechts lässt sich zwischen zwei Darstellungen derselben Messung
umschalten:

* **Schärfe-Kurve** (Standard) — jede Kurve startet links bei 1,0 und fällt
  dort ab, wo das Bild kein Detail mehr überträgt. **Je weiter rechts eine
  Kurve abfällt, desto schärfer.** Der Punkt auf der gestrichelten Linie ist
  genau der MTF50-Wert aus der Tabelle. Das ist die Ansicht zum Vergleichen.
* **Powerspektrum** — die fachliche Rohform. Sie fällt von Natur aus steil
  nach rechts ab; das ist eine Eigenschaft des Motivs, nicht der Schärfe.
  Dafür sieht man hier das Rauschplateau: eine Kurve, die rechts flach hoch
  hängt, ist verrauscht.

---

## 3. Die Messwerte — in einfachem Deutsch

Gemessen wird immer im Auswertefenster, nie im ganzen Bild. Alle Bilder
bekommen dasselbe Fenster an derselben Stelle.

### Detailschärfe (MTF50)

**Was:** Bis zu welcher Feinheit das Bild noch echtes Detail zeigt,
angegeben in Zyklen pro Pixel. 0,5 wäre die theoretische Obergrenze
(zwei Pixel pro Detail). Typische gute Sonnenaufnahmen liegen bei 0,15–0,25.

**Merksatz:** höher = schärfer.

**Fallstrick:** Hartes Nachschärfen hebt den Wert künstlich an, treibt aber
gleichzeitig den Rauschgrund hoch. Deshalb nie allein lesen, sondern immer
zusammen mit SNR und Rauschen.

### Detailenergie

**Was:** Wie viel echte Struktur im Bild steckt — die Leistung im
Detailband des Spektrums, **nachdem der Rauschanteil abgezogen wurde**.
Auf das beste Bild des Laufs = 1,00 normiert.

**Merksatz:** höher = mehr echtes Detail.

**Warum der Abzug wichtig ist:** Rauschen ist breitbandig und würde sonst
als „Detail" mitgezählt. Ein verrauschtes Bild sähe dann detailreicher aus
als ein sauberes — genau das, was das Werkzeug verhindern soll.

### SNR (Signal-Rausch-Verhältnis)

**Was:** Wie viel Struktur im Verhältnis zum Rauschen da ist, in Dezibel.
Über 35 dB ist sehr sauber, unter 20 dB deutlich körnig.

**Merksatz:** höher = sauberer.

**Wozu:** Zeigt, ob Schärfe teuer erkauft wurde. Hohe MTF50 bei niedrigem
SNR heißt fast immer: überschärft.

### Rauschgrund

**Was:** Wie stark das pixelweise Rauschen ist — unabhängig davon, wie viel
Struktur im Bild steckt.

**Merksatz:** niedriger = besser.

**Wie gemessen:** Über einen Laplace-artigen Filter, der glatte Verläufe und
sogar Kanten weitgehend auslöscht; übrig bleibt im Wesentlichen Rauschen.
Der Vorteil: es funktioniert auch bei Ausschnitten ganz **ohne** dunklen
Himmel, etwa bei einer formatfüllenden aktiven Region. Zusätzlich wird —
wenn vorhanden — die Streuung im dunklen Bildbereich als
*Hintergrund* ausgewiesen.

### Kontrast und Tonwertumfang

**Was:** Wie kräftig die Helligkeitsunterschiede sind und wie viel vom
verfügbaren Tonwertumfang genutzt wird.

**Merksatz:** höher = knackiger, niedrig = flau.

**Fallstrick:** Kontrast lässt sich nachträglich fast beliebig verändern.
Deshalb zählt er im Score nur mit 10 %.

### Lokale Schärfe

**Was:** Schnellwert für Schärfe im Ortsraum (Streuung nach einem
Hochpassfilter). Läuft meist parallel zu MTF50, reagiert aber stärker auf
Nachschärfung.

### Rauschplateau

**Was:** Ab welcher Frequenz die Kurve im Rauschen versinkt (angegeben als
Bin-Nummer von 0 bis 255).

**Merksatz:** **früh = viel Rauschen**, spät = sauber.

### Effektive Auflösung (nur mit Optikangaben)

**Was:** Deine Detailschärfe umgerechnet in Bogensekunden, direkt neben dem
theoretischen Limit deiner Öffnung (Dawes-Grenze, 116 ÷ Öffnung in mm).

**Merksatz: kleiner ist besser.** 3,4″ heißt, zwei Details müssen
mindestens 3,4 Bogensekunden auseinander liegen, damit man sie noch als
zwei erkennt.

Der Wert daneben — was die Öffnung theoretisch könnte — ist deshalb immer
**kleiner** als der erreichte; besser als die Physik geht es nicht. Der
Prozentsatz sagt, wie nah du drankommst.

Beispiel: *3,44″, möglich wären 2,90″ — davon erreicht: 84 %.* Bleibt der
Prozentsatz dauerhaft unter 60 %, liegt es meist an Seeing, Fokus oder zu
wenigen guten Frames.

### Sampling (nur mit Optikangaben)

**Was:** Wie viel Himmel auf einem Pixel landet, in Bogensekunden pro Pixel.

**Faustregel:** etwa **2–3 Pixel** pro kleinstem auflösbarem Detail.
Deutlich gröber = Details gehen verloren (Barlow hilft). Deutlich feiner =
nur mehr Rauschen und längere Belichtung, ohne Detailgewinn.

---

## 4. Die zwei Bewertungen

finiSCOPE beantwortet zwei verschiedene Fragen, und es ist wichtig, sie
auseinanderzuhalten:

| | Frage | Wo |
|---|---|---|
| **Qualität** | Ist diese Aufnahme **für sich genommen** gut? | Ampel und Wort in der Tabelle |
| **Platz** | Welche der geladenen Versionen ist die **beste**? | Zahl von 0 bis 100 |

Der Unterschied zählt: Wenn du drei mäßige Versionen lädst, bekommt die
beste davon trotzdem 100 Punkte — **die Ampel bleibt aber gelb oder rot**.
Sind alle Zeilen gelb, weist finiSCOPE zusätzlich in der Hinweisleiste
darauf hin, dass hier auch der Sieger nicht viel wert ist.

### Woraus die Qualität berechnet wird

Nur aus Größen, die eine absolute Bedeutung haben:

* **Anteil am theoretischen Auflösungsvermögen** deiner Öffnung — das
  ehrlichste Maß überhaupt. Braucht die Optikangaben.
* **Rauschabstand (SNR)** in Dezibel — feste Grenzen, motivunabhängig.

Daraus wird ein Wort: *sehr gut · gut · mittel · schwach · sehr schwach*.
Die schlechtere der beiden Größen bestimmt das Ergebnis — ein knackscharfes,
aber stark verrauschtes Bild ist eben nicht gut.

**Ohne Optikangaben** ist die Einschätzung nur vorläufig und stützt sich
allein auf das Rauschen: ob 0,18 Zyklen/Pixel viel oder wenig ist, hängt von
Öffnung und Brennweite ab, das lässt sich ohne diese Angaben nicht sagen.
Die Sprechblase weist darauf hin.

**Über 100 % kann nicht sein.** Wenn die Rechnung mehr ergibt, als die
Öffnung physikalisch hergibt, meldet finiSCOPE das als *unklar* — meist ist
das Bild sehr stark nachgeschärft (dann täuscht die Messung Auflösung vor,
die gar nicht vom Teleskop stammt) oder die eingetragene Brennweite passt
nicht zur Aufnahme.

## 5. Der Punktescore (Platz)

Der Score fasst alles zu einer Zahl von 0 bis 100 zusammen:

| Metrik | Gewicht | Richtung |
|---|---|---|
| Detailschärfe (MTF50) | 40 % | höher ist besser |
| Detailenergie | 25 % | höher ist besser |
| SNR | 20 % | höher ist besser |
| Kontrast | 10 % | höher ist besser |
| Rauschgrund | −15 % | **niedriger** ist besser |

Die Ampel daneben: grün ab 80, gelb ab 60, orange ab 40, rot darunter.

> ### Das Wichtigste zum Score
>
> **Punktzahlen gelten nur innerhalb eines Vergleichslaufs.**
>
> Das beste geladene Bild bekommt immer genau 100 — auch dann, wenn alle
> geladenen Versionen mäßig sind. 100 heißt also **„die beste der hier
> geladenen"**, nicht „ein absolut gutes Bild".
>
> Deshalb steht in der Sieger-Box auch nicht „Punktescore", sondern
> **„beste von N Aufnahmen"**.
>
> Punktzahlen aus verschiedenen Sessions zu vergleichen ist sinnlos. Ein
> 95er von gestern kann besser oder schlechter sein als ein 100er von heute.

**Bei einem einzelnen Bild gibt es gar keinen Score** — dann steht dort ein
Strich. Ein Vergleichswert ohne Vergleich wäre eine Falschaussage.

### Was ist dann absolut aussagekräftig?

Drei Dinge — unabhängig davon, was sonst geladen ist:

| Wert | Absolute Bedeutung |
|---|---|
| **% vom Optimum** | Braucht die Optikangaben. Sagt, wie nah die Aufnahme am theoretischen Auflösungsvermögen der Öffnung liegt. Über 85 % ist ausgereizt, unter 65 % liegt meist Seeing oder Fokus im Weg. |
| **SNR** | Über 35 dB sehr sauber, 28–35 sauber, 22–28 brauchbar, 16–22 sichtbar körnig, darunter stark verrauscht. In der Tabelle ist der Wert entsprechend eingefärbt. |
| **Sampling** | Braucht die Optikangaben. *Gut* / *zu grob* / *zu fein*. |

Alle übrigen Zahlen — Score, Detailenergie, MTF50 — sind Vergleichswerte
und nur innerhalb eines Laufs zu lesen.

Die Gewichte stehen als Konstante `WEIGHTS` ganz oben in
[`analysis/scoring.py`](analysis/scoring.py) und lassen sich dort ändern.

---

## 6. Objekt-Profile

Jedes Profil legt fest, **wo** gemessen wird und **welche Frequenzen** als
echtes Detail gelten (Bin-Grenzen bezogen auf ein 512-px-Fenster):

| Profil | Detailband | Rauschen ab | Fenster | Wo gemessen wird |
|---|---|---|---|---|
| **Sonne** | 50–125 | 150 | 512 px | detailreichste Region |
| **Mond** | 55–135 | 155 | 512 px | detailreichste Region (meist am Terminator) |
| **Planet** | 40–110 | 140 | 256 px | Scheibchen über Helligkeitsschwelle, Fenster darauf zentriert |

Bei kleinen Bildern oder kleinen Planetenscheibchen wird das Fenster
automatisch verkleinert. Alle Werte stehen in
[`analysis/profiles.py`](analysis/profiles.py).

**Was der Umschalter praktisch bewirkt:** Zwischen **Sonne** und **Mond**
ist der Unterschied klein — beide messen an der detailreichsten Stelle, das
Detailband liegt beim Mond nur wenig höher, weil Kraterkanten feiner sind
als H-Alpha-Fibrillen. Der Score ändert sich dadurch meist nur um wenige
Punkte, die Rangfolge fast nie.

Deutlich anders ist **Planet**: dort wird zuerst das Scheibchen über eine
Helligkeitsschwelle gesucht und das Fenster darauf zentriert (statt auf die
detailreichste Kachel), und das Fenster ist mit 256 px nur halb so groß —
sonst würde bei einem kleinen Jupiter der schwarze Himmel mitgemessen. Für
Sonne und Mond wäre dieses Profil zu grob, für Planeten sind die anderen
beiden unbrauchbar.

Wähle also das Profil passend zum Motiv — aber verliere keine Zeit mit der
Frage, ob eine Mondaufnahme mit dem Sonnenprofil „falsch" gemessen wird.
Wichtig ist vor allem, dass **alle Bilder eines Laufs dasselbe Profil**
bekommen, und das ist immer der Fall.

Deep-Sky ist bewusst nicht dabei — dort gelten andere Regeln. Die Engine
ist aber über ein einfaches Interface gebaut
(`analyze(bild, profil) -> Messwerte`), ein weiteres Profil wäre also
nachrüstbar.

---

## 7. Drizzle, .as3 und Sessions

### Drizzle wird fair behandelt

Ein mit Drizzle 1,5× gestacktes Bild ist 1,5-mal so groß. Würde man es
einfach so vermessen, läge sein Detail bei anderen Frequenzen und der
Vergleich wäre wertlos. finiSCOPE rechnet solche Bilder deshalb **vor der
Messung** wieder auf die native Pixelgröße herunter (kubisch).

Erkannt wird das zurückhaltend — heruntergerechnet wird nur, wenn das Bild
tatsächlich größer ist als das kleinste des Laufs **und** das Verhältnis zu
einem üblichen Faktor (1,5× / 2× / 3×) passt, oder wenn Dateiname und
Größenverhältnis übereinstimmen. Ein Bild, das aus einem anderen Grund
größer ist, bleibt unangetastet und löst stattdessen eine Session-Warnung
aus.

Der Nachweis, dass das funktioniert, steckt im Testlauf: dieselbe Aufnahme
einmal nativ und einmal als Drizzle 1,5× gestackt wird auf **0,1 % gleiche
Detailschärfe** gemessen.

### .as3 wird gelesen, wenn sie da ist

**Die .as3 musst du nicht laden.** finiSCOPE sucht sie von selbst: liegt
neben `bild.tif` eine `bild.as3` von AutoStakkert, wird daraus die
`Median quality` gelesen und in der Tabelle gezeigt. AutoStakkert hängt oft
Suffixe an die TIFF-Namen (`_conv`, `_lapl4_ap1274`) — finiSCOPE findet die
passende .as3 auch dann.

**Selbst zuordnen geht auch.** Heißt die .as3 ganz anders als das TIFF,
findet die Automatik sie nicht — dann gibt es zwei Wege:

* in der Tabelle auf den Wert in der Spalte **as3** klicken (steht dort
  *„laden …"*, wurde keine gefunden) und die Datei auswählen, oder
* die .as3 einfach **ins Fenster ziehen** — sie wird der gerade
  ausgewählten Aufnahme zugeordnet.

Die Sprechblase in der Spalte zeigt, aus welcher Datei der Wert stammt und
ob er automatisch gefunden oder von dir zugeordnet wurde.

**Achtung:** Dieser Wert ist nur **innerhalb derselben Aufnahme**
vergleichbar. Zwischen zwei Sessions bedeutet er nichts. Fehlt die Datei,
läuft alles normal weiter, in der Spalte steht dann ein Strich.

### Session-Warnungen

finiSCOPE prüft, ob die geladenen Bilder plausibel zusammengehören, und
warnt bei stark abweichender Bildgröße, deutlich unterschiedlicher mittlerer
Helligkeit oder wenn Dateien übersprungen werden mussten. Die Warnungen
stehen unter der Tabelle und stehen auch im HTML-Report.

---

## 8. Aus dem Quelltext starten

Nötig, wenn du am Programm etwas ändern willst. Voraussetzung ist Python
3.9 oder neuer (empfohlen 3.11+).

### macOS

Doppelklick auf **`run_mac.command`**. Beim ersten Start wird eine eigene
Python-Umgebung angelegt und alle Pakete werden geladen — das dauert
einmalig ein paar Minuten.

Falls macOS das Ausführen verweigert, einmalig im Terminal:

```bash
chmod +x run_mac.command build_mac.command
```

### Windows

Doppelklick auf **`run_windows.bat`**. Auch hier richtet der erste Start
alles automatisch ein.

Ist noch kein Python installiert: von <https://www.python.org/downloads/>
holen und bei der Installation unbedingt den Haken bei
**„Add python.exe to PATH"** setzen.

### Von Hand

```bash
python3 -m venv .venv
source .venv/bin/activate        # Windows:  .venv\Scripts\activate
pip install -r requirements.txt
python app.py
```

Dateien lassen sich auch direkt mitgeben:

```bash
python app.py bild1.tif bild2.tif
```

---

## 9. Die Programme selbst bauen

> **Wichtig:** Eine Windows-`.exe` lässt sich **nur auf Windows** bauen und
> eine macOS-`.app` **nur auf einem Mac**. PyInstaller kann nicht für ein
> fremdes Betriebssystem übersetzen. Wer beide Versionen anbieten will,
> braucht beide Systeme — oder lässt sie automatisch bauen (siehe unten).

### macOS → `dist/finiSCOPE.app`

```bash
./build_mac.command
```

Dauert ein bis zwei Minuten, das Ergebnis ist rund 180 MB groß und läuft
ohne installiertes Python. Die App wird ad-hoc signiert, damit macOS sie
nicht als beschädigt meldet. Sie läuft auf dem Prozessortyp, auf dem sie
gebaut wurde (Apple Silicon bzw. Intel).

**Zum Weitergeben** anschließend `./paket_mac.command` starten. Das schnürt
eine `dist/finiSCOPE-0.1-macOS.dmg` mit App, Verknüpfung zum
Programme-Ordner und einer Kurzanleitung darin — eine einzelne Datei, die
sich verschicken lässt.

### Windows → `dist\finiSCOPE\finiSCOPE.exe`

```bat
build_windows.bat
```

Zum Weitergeben den **kompletten Ordner** `dist\finiSCOPE` packen — die
`.exe` allein läuft nicht.

Schritt für Schritt mit allen Stolpersteinen:
**[WINDOWS_BAUEN.md](WINDOWS_BAUEN.md)** · englisch:
**[WINDOWS_BUILD_EN.md](WINDOWS_BUILD_EN.md)**

### Beides automatisch bauen lassen

Wer das Projekt auf GitHub legt, kann sich beide Programme kostenlos von
GitHub Actions bauen lassen — auch ohne zweiten Rechner. Eine fertige
Konfiguration liegt unter
[`.github/workflows/build.yml`](.github/workflows/build.yml). Nach dem
Hochladen entstehen bei jedem Änderungsstand `finiSCOPE-macOS` und
`finiSCOPE-Windows` als Download.

### Prüfen, ob eine gebaute App vollständig ist

```bash
./dist/finiSCOPE.app/Contents/MacOS/finiSCOPE --selftest
```

Listet alle Pakete und Bilddateien auf und sagt am Ende, ob etwas fehlt.

---

## 10. Wenn etwas nicht geht

**Die Datei wird nicht geladen.**
finiSCOPE liest TIFF (`.tif`, `.tiff`) mit 8, 16 oder 32 Bit, ein- oder
dreikanalig. Farbbilder werden zur Helligkeit zusammengefasst. FITS, PNG und
JPG werden nicht gelesen. Defekte Dateien werden übersprungen, die übrigen
trotzdem gemessen — in der Hinweiszeile steht, welche.

**„Die Bilder haben unterschiedliche Abmessungen."**
Sie stammen vermutlich aus verschiedenen Aufnahmen. Der Vergleich läuft
weiter, aber das Powerspektrum vergleicht dann verschiedene Motive — die
Punktzahlen sind mit Vorsicht zu lesen.

**Alle Bilder bekommen fast denselben Score.**
Dann sind sie tatsächlich fast gleich gut. Sieh in der 1:1-Lupe nach: wenn
du dort keinen Unterschied siehst, gibt es auch keinen, der zählt.

**Das Auswertefenster sitzt an einer uninteressanten Stelle.**
Zieh dein eigenes Rechteck über die Stelle, die dich interessiert.

**Die Messung dauert lange.**
Große Drizzle-TIFFs (4000 px und mehr) müssen zurückgerechnet werden. Das
Fenster bleibt bedienbar, der Fortschritt läuft als dünne Linie unter der
Statusleiste.

**macOS: „App ist beschädigt".**
Siehe [Abschnitt 1](#macos) — einmalig das Quarantäne-Merkmal entfernen.

---

## 11. Aufbau des Projekts

```
finiSCOPE/
  app.py                  Einstieg (auch --selftest)
  analysis/
    core.py               Laden, Rückskalierung, Fenstersuche, PSD,
                          MTF50, SNR, Rauschen, Kontrast
    profiles.py           Sonne / Mond / Planet: Bänder und Fenster
    scoring.py            Gewichteter Score + Klartext-Urteile
    as3.py                AutoStakkert-Datei auslesen
  ui/
    theme.py              Farben, Schrift, Stylesheet, Bildpfade
    widgets.py            Drop-Zone, Karten, Sieger-Box, (i)-Erklärungen
    imageview.py          Bildansicht mit Auswertefenster und 1:1-Lupe
    chart.py              Powerspektrum-Diagramm
    table.py              Vergleichstabelle mit aufklappbaren Rohwerten
    mainwindow.py         Zusammenbau, Analyse-Thread, Export
  export/
    report.py             CSV und HTML erzeugen
    report.html.j2        Vorlage des HTML-Reports
  assets/                 Hintergrund, Logo, Symbole (austauschbar)
  prototype/preview.html  Design-Prototyp (statisch, im Browser)
  tests/
    make_testdata.py      erzeugt synthetische Prüfbilder
    test_analysis.py      27 Prüfungen der Messung
    screenshot.py         rendert das Fenster als Bild
  requirements.txt · LICENSE · README.md
  run_mac.command · run_windows.bat
  build_mac.command · build_windows.bat · finiSCOPE.spec
```

Der Name steht als Konstante `APP_NAME` in
[`ui/theme.py`](ui/theme.py) — dort einmal ändern genügt.

Die Bilder in `assets/` werden über ihren **Basisnamen** gefunden, die
Endung ist frei. `background.png` lässt sich also jederzeit durch
`background.jpg` ersetzen. Erwartet werden `background`, `favicon`, `logo`
und `logo_wordmark`; fehlt eines, läuft die App trotzdem.

### Tests

```bash
python tests/make_testdata.py tests/data   # Prüfbilder erzeugen
python tests/test_analysis.py              # 27 Prüfungen
```

Der Test erzeugt aus **einem** Motiv vier Varianten und weist nach, dass

* die weichgezeichnete Version **weniger** Detail zeigt (MTF50 0,128 gegen
  0,221, Detailenergie ein Fünftel),
* die Drizzle-1,5×-Version nach der Rückskalierung **gleichwertig** gemessen
  wird (Abweichung 0,1 %),
* die verrauschte Version trotz nominell gleicher Schärfe einen zehnfach
  höheren Rauschgrund und 18 dB schlechteres SNR bekommt — und im Ranking
  entsprechend zurückfällt.

Dazu Prüfungen für RGB, 8 Bit, fehlende Dateien, defekte Dateien, fehlende
.as3, sehr kleine Bilder und manuell gesetzte Auswertefenster.

---

## 12. Farben

Die Oberfläche kommt bewusst **ohne Gelb** aus:

* **Grün** ist die einzige Entwarnung — gut, sauber, gleichauf mit dem
  besten Bild. Auch der Sieger ist grün, denn grün heißt hier durchgehend
  „gut".
* **Blau** ist die Grundfarbe der ganzen Anwendung: neutral, mittelmäßig,
  und alle Bedienelemente. Es ist dasselbe Blau wie auf finisky.com
  (`#4F8DE0` / `#8FC0FF` auf `#16263D`). Auch das Auswertefenster im Bild
  ist blau — es hebt sich auf grauen Mond- wie auf orangen Sonnenbildern
  gleichermaßen ab.
* **Warm und rot** bleiben dem vorbehalten, was wirklich schwach ist.

Gelb und Gold kommen bewusst **nirgends** vor.

Alle Farbwerte stehen als Konstanten in [`ui/theme.py`](ui/theme.py).

---

## 13. Getroffene Annahmen

Wo die Aufgabenstellung offen war, wurde so entschieden:

**Ein Feld für die Öffnung wurde ergänzt.** Ohne sie lässt sich die
theoretische Auflösungsgrenze (Dawes) nicht berechnen und der Vergleich
„wie nah am Optimum" wäre nicht möglich. Das Feld ist optional.

**MTF50 wird auf einem entrauschten und „geweißten" Spektrum bestimmt.**
Ein Motiv hat von sich aus ein zu hohen Frequenzen abfallendes Spektrum —
das ist eine Eigenschaft des Motivs, nicht der Schärfe. Sucht man einfach
den Halbwertspunkt der rohen Kurve, kommt für ein scharfes und ein
weichgezeichnetes Bild fast derselbe Wert heraus. Deshalb wird zuerst der
Rauschgrund abgezogen und dann der natürliche Abfall herausgerechnet; übrig
bleibt die Übertragungsfunktion des Systems. Erst dadurch trennt der Wert
scharf und weich sauber (0,221 gegen 0,128 im Testlauf).

**Der Rauschgrund wird im Auswertefenster gemessen, nicht im dunklen
Himmel.** Ein Ausschnitt einer aktiven Region hat keinen dunklen Himmel.
Das verwendete Verfahren (Laplace-Filter mit Median) funktioniert in beiden
Fällen. Die Streuung im dunklen Bereich wird zusätzlich ausgewiesen, wenn
einer vorhanden ist.

**Vom Rauschen befreite Detailenergie.** Ohne den Abzug würde Korn als
Detail zählen und ein verrauschtes Bild gewänne — im ersten Testlauf war
genau das der Fall.

**Zurückhaltende Drizzle-Erkennung.** Lieber einmal nicht zurückrechnen als
ein Bild aus einer anderen Session fälschlich verkleinern. Bei
unerklärlichen Größenunterschieden gibt es stattdessen eine Warnung.

**Ein gezogener Bereich gilt standardmäßig für alle Bilder.** Alles andere
wäre kein fairer Vergleich. Der Haken *nur dieses Bild* erlaubt die
Ausnahme.

**Das Diagramm ist selbst gezeichnet** statt mit pyqtgraph oder Matplotlib.
Das ergibt exakt das entworfene Aussehen, startet schneller und spart der
fertigen App rund 40 MB.

**Die Skala des Diagramms passt sich den Daten an.** Die ersten Bins tragen
nur den großflächigen Helligkeitsverlauf und werden nicht gezeichnet, sonst
würde alles Interessante an den unteren Rand gedrückt.

**Klartext-Urteile berücksichtigen die Größe des Unterschieds.** Bei zwei
fast gleich guten Bildern heißt es „nur eine Spur körniger" statt
„deutlich verrauscht" — auch wenn eines rechnerisch zurückliegt.

**Ein einzelnes Bild bekommt keinen Score.** Eine große „100" bei nur einer
geladenen Datei würde als „perfekt" gelesen, gemeint wäre aber „das einzige
da". Stattdessen steht dort ein Strich, und die Sieger-Box zeigt die
absolute Aussage: wie nah die Aufnahme am Auflösungsvermögen der Optik liegt.

**Der Versatz zwischen den Bildern wird per Phasenkorrelation ausgeglichen.**
Ohne das würde man bei leicht verschobenen Stacks zwei verschiedene Stellen
vergleichen — der häufigste denkbare Messfehler in diesem Werkzeug. Das
Verfahren ist unempfindlich gegen Helligkeitsunterschiede und findet den
Versatz auf ein Pixel genau (im Testlauf: Abweichung nach dem Ausgleich
exakt null). Ausschaltbar, falls die Bilder garantiert deckungsgleich sind.

**Der automatische Auswertebereich wird auf dem Mittelwert aller Bilder
gesucht.** Nähme man das erste Bild, hinge die Messstelle davon ab, in
welcher Reihenfolge die Dateien geladen wurden — und wäre womöglich auf
einer Stelle, die nur in der unschärfsten Version interessant aussieht.

**Ein einzelnes Bild bekommt keine Punktzahl, aber eine Qualitätsampel.**
Der Vergleich fällt weg, die absolute Einschätzung bleibt.

**Die Schärfe-Kurve ist die Standardansicht des Diagramms.** Das rohe
Powerspektrum fällt von Natur aus steil nach rechts ab und sieht deshalb
für alle Bilder ähnlich aus — die Unterschiede stecken in Details, die man
erst mit Übung sieht. Die geweißte Kurve zeigt direkt, was interessiert:
wo das Bild aufhört, Detail zu übertragen. Das Powerspektrum bleibt einen
Klick entfernt erhalten.

---

---

## Urheber und Lizenz

finiSCOPE ist ein Werkzeug von **Josef Kreidl** — Astrofotografie unter
[finisky.com](https://finisky.com).

**Kostenlos, ohne Gewähr, Nutzung auf eigene Verantwortung.** Die Software
steht unter der MIT-Lizenz und darf genutzt, weitergegeben und verändert
werden, solange Lizenztext und Urheberhinweis beigelegt bleiben. Eine
Haftung für Schäden ist ausgeschlossen. Die berechneten Werte sind
Anhaltspunkte für den Vergleich eigener Aufnahmen und keine messtechnisch
garantierten Größen.

Dieselben Angaben stehen auch in der App selbst unter **Info & Lizenz** in
der Fußzeile, der vollständige Text in [LICENSE](LICENSE).

Die mitgelieferten Aufnahmen in `assets/` (Sonne, Mond, Logo, Symbol) sind
urheberrechtlich geschützte Fotografien von Josef Kreidl und **nicht** Teil
der MIT-Lizenz.

## Unterstützung

finiSCOPE ist und bleibt kostenlos, alle Funktionen sind ohne Einschränkung
nutzbar. Wer die Weiterentwicklung unterstützen möchte, findet auf
[finisky.com/unterstuetzung](https://finisky.com/unterstuetzung) eine
Möglichkeit dazu — freiwillig und ohne Gegenleistung. In der App steht der
Link leise in der Fußzeile und unter **Hilfe → finiSCOPE unterstützen**.

*© 2026 Josef Kreidl · finisky.com*
