de:praktikum:photometrie_python

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen Revision Vorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
de:praktikum:photometrie_python [2025/02/17 09:23] – [Magnitudenkalibrierung] rhainichde:praktikum:photometrie_python [2026/04/23 15:12] (aktuell) – [Kreuzkorrelation mit den extrahierten Daten] rhainich
Zeile 87: Zeile 87:
 Konfigurationsbereich von ''1_add_images.py'': Konfigurationsbereich von ''1_add_images.py'':
  
-  ##########################  Individual folders  ############################ +<code Python> 
-  ### Path to the bias -- If set to '?', bias exposures are not used. +##########################  Individual folders  ############################ 
-  bias: str = '?'+### Path to the bias -- If set to '?', bias exposures are not used. 
 +bias: str = '?'
      
-  ### Path to the darks +### Path to the darks 
-  darks: str = '?'+darks: str = '?'
      
-  ### Path to the flats +### Path to the flats 
-  flats: str = '?'+flats: str = '?'
      
-  ### Path to the images +### Path to the images 
-  images: str  = '?'+images: str  = '?'
      
-  #######################  Simple folder structure  ########################## +#######################  Simple folder structure  ########################## 
-  raw_files: str = '?'+raw_files: str = '?' 
 +</code>
  
 Wurden die Pfandangaben und der Name des Sternhaufens angepasst, kann anschließend das Skript mittels Wurden die Pfandangaben und der Name des Sternhaufens angepasst, kann anschließend das Skript mittels
Zeile 119: Zeile 121:
   kate auswertung.py &   kate auswertung.py &
  
-/+Am den Beginn des //Python//-Skripts werden erst einmal die benötigten Module mit hilfreichem Code eingebundenIn unserem Fall sind das Numpy, einige Astropymodule, Astroquery sowie einige Teile unserer OST-Bibliothek:
-++++ Ausführbarkeit mittels ./auswertung.py | +
-Soll das Skript auch mittels+
  
-  ./auswertung.py +<code Python> 
-   +import os
-ausführbar sein, muss in die erste Zeile des Skripts folgender Text geschrieben werden:+
  
-  #! /usr/bin/python+import numpy as np
  
-Auf diese Weise wird dem System mitgeteiltum welche Art von Skript es sich handelt und wie dieses zu interpretieren istDes Weiteren muss die Datei mittels+from astropy.coordinates import SkyCoordmatching 
 +import astropy.units as u 
 +from astropy.table import Table
  
-   chmod u+x auswertung.py+from astroquery.vizier import Vizier
  
-noch als ausführbar gekennzeichnet werden. +from ost_photometry import checks 
-++++ +from ost_photometry.analyze.extraction import main_extract 
-*/ +from ost_photometry.analyze.plots import 
- +    plot_calibration_color_color_cal_stars, 
-Am den Beginn des //Python//-Skripts werden erst einmal die benötigten Module mit hilfreichem Code eingebunden. In unserem Fall sind das Numpy, einige Astropymodule, Astroquery sowie einige Teile unserer OST-Bibliothek: +    plot_combined_separation_histograms, 
- +    plot_instrumental_vs_catalog_magnitudes, 
-   import numpy as np +    plot_photometry_mag_vs_error, 
-    +    plot_zeropoint_residual_distribution, 
-   from astropy.coordinates import SkyCoord, matching +    plot_zeropoint_residual_vs_color, 
-   import astropy.units as u +    scatter
-   from astropy.table import Table +    starmap, 
-    +) 
-   from astroquery.vizier import Vizier +from ost_photometry.utilities import ( 
-    +    find_wcs_astrometry, 
-   from ost_photometry.analyze.analyze import main_extract  +    Image, 
-   from ost_photometry.analyze.plots import starmap, scatter +
-   from ost_photometry.utilities import ( +from ost_photometry.analyze.utilities import ( 
-       find_wcs_astrometry, +    clear_duplicates, 
-       Image, +) 
-   +</code>
-   from ost_photometry.analyze.utilities import ( +
-       clear_duplicates, +
-   )+
  
-   import warnings +<code Python> 
-   warnings.filterwarnings('ignore')+import warnings 
 +warnings.filterwarnings('ignore') 
 +</code>
  
 Über die letzten zwei Zeilen werden noch einige Warnungen abgeschaltet, die die Konsolenausgabe unnötig überfrachten. Über die letzten zwei Zeilen werden noch einige Warnungen abgeschaltet, die die Konsolenausgabe unnötig überfrachten.
Zeile 165: Zeile 165:
 Als nächstes sollten einige Variablen definiert werden. Dies sollten wenigsten der Name des Sternhaufens (''name''), das Verzeichnis in dem die Ergebnisse später abgelegt werden (''out_path'') sowie die Pfade (''V_path'' und ''B_path'') zu den beiden über die obige Pipeline aufaddierten und reduzierten Aufnahmen des Sternhaufens in den betrachteten Filtern (hier ''V'' und ''B'') sein.  Als nächstes sollten einige Variablen definiert werden. Dies sollten wenigsten der Name des Sternhaufens (''name''), das Verzeichnis in dem die Ergebnisse später abgelegt werden (''out_path'') sowie die Pfade (''V_path'' und ''B_path'') zu den beiden über die obige Pipeline aufaddierten und reduzierten Aufnahmen des Sternhaufens in den betrachteten Filtern (hier ''V'' und ''B'') sein. 
  
-   #   Cluster name (recognizable by Simbad/Vizier) +<code Python> 
-   name = 'NGC7789'+#   Cluster name (recognizable by Simbad/Vizier) 
 +name = 'NGC7789'
        
-   #   Directory to save the data +#   Directory to save the data 
-   out_path='output/'+out_path='output/'
        
-   #   Images +#   Images 
-   V_path = 'output/combined_trimmed_filter_V.fit' +V_path = 'output/combined_filter_V.fit' 
-   B_path = 'output/combined_trimmed_filter_B.fit'+B_path = 'output/combined_filter_B.fit' 
 +</code>
  
 Hinweis: Die hier und im weiteren angegeben Variablennamen sind nur beispielhaft und können durch jede beliebige andere Bezeichnung ersetzt werden.   Hinweis: Die hier und im weiteren angegeben Variablennamen sind nur beispielhaft und können durch jede beliebige andere Bezeichnung ersetzt werden.  
Zeile 183: Zeile 185:
 Wir öffnen die FIT-Dateien mit Aufnahmen mittels der Funktion ''image'', die über die OST-Bibliothek bereit gestellt wird. Dies hat den Vorteil, dass wir uns nicht um die Details des Einleseprozesses kümmern müssen und gleichzeitig für jedes Bild ein //Python//-Objekt zur Verfügung steht, in dem die Ergebnisse der folgenden Schritte sortiert abgelegt werden können. Die ''image''-Funktion hat folgende Argumente: 1. Index des Bildes (kann hier auf ''0'' gesetzt werden), 2. Filterbezeichnung, 3. Pfad zur Bilddatei und 4. Pfad zum Output-Verzeichnis:  Wir öffnen die FIT-Dateien mit Aufnahmen mittels der Funktion ''image'', die über die OST-Bibliothek bereit gestellt wird. Dies hat den Vorteil, dass wir uns nicht um die Details des Einleseprozesses kümmern müssen und gleichzeitig für jedes Bild ein //Python//-Objekt zur Verfügung steht, in dem die Ergebnisse der folgenden Schritte sortiert abgelegt werden können. Die ''image''-Funktion hat folgende Argumente: 1. Index des Bildes (kann hier auf ''0'' gesetzt werden), 2. Filterbezeichnung, 3. Pfad zur Bilddatei und 4. Pfad zum Output-Verzeichnis: 
  
-   #   Load images +<code Python> 
-   V_image = Image(0, 'V', V_path, out_path) +#   Load images 
-   B_image = Image(0, 'B', B_path, out_path)+V_image = Image(0, 'V', V_path, out_path) 
 +B_image = Image(0, 'B', B_path, out_path) 
 +</code>
  
 ==== World Coordinate System ==== ==== World Coordinate System ====
Zeile 194: Zeile 198:
 Für die Bestimmung des WCS fehlen uns allerdings noch ein paar Voraussetzungen. Die ungefähren zentralen Koordinaten des abgebildeten Himmelsausschnitt sind zwar bereits in den Header der FIT-Dateien hinterlegt, das genau Gesichtsfeld und die Pixel-Skala der erstellten Aufnahmen müssen allerdings noch ermittelt werden. Dies erzielen wir mit der Funktion ''cal_fov'', der als Argument das bereits angelegt ''image''-Objekt übergeben wird: Für die Bestimmung des WCS fehlen uns allerdings noch ein paar Voraussetzungen. Die ungefähren zentralen Koordinaten des abgebildeten Himmelsausschnitt sind zwar bereits in den Header der FIT-Dateien hinterlegt, das genau Gesichtsfeld und die Pixel-Skala der erstellten Aufnahmen müssen allerdings noch ermittelt werden. Dies erzielen wir mit der Funktion ''cal_fov'', der als Argument das bereits angelegt ''image''-Objekt übergeben wird:
  
-   #   Calculate FOV +<code Python> 
-   calculate_field_of_view(V_image) +#   Calculate FOV 
-   calculate_field_of_view(B_image)+calculate_field_of_view(V_image) 
 +calculate_field_of_view(B_image) 
 +</code>
  
 Das Gesichtsfeld und die Pixel-Skala wird automatisch im ''image''-Objekt hinterlegt. Das Gesichtsfeld und die Pixel-Skala wird automatisch im ''image''-Objekt hinterlegt.
Zeile 205: Zeile 211:
 Mittels der Funktion ''find_wcs_astrometry'' kann die Bestimmung des WCS gestartet werden: Mittels der Funktion ''find_wcs_astrometry'' kann die Bestimmung des WCS gestartet werden:
  
-   #   Find the WCS solution for the images +<code Python> 
-   find_wcs_astrometry(V_image) +#   Find the WCS solution for the images 
-   find_wcs_astrometry(B_image)+find_wcs_astrometry(V_image) 
 +find_wcs_astrometry(B_image) 
 +</code>
  
 Wurde eine WCS-Lösung gefunden wird auf der Kommandozeile in grün Wurde eine WCS-Lösung gefunden wird auf der Kommandozeile in grün
Zeile 221: Zeile 229:
 Die Identifikation der Sterne in den beiden Bildern erfolgt mittels der Funktion ''main_extract''. Diese Funktion nimmt als erstes Argument wiederum das ''image''-Objekt. Als optionales Argument kann dann noch die Extraaktionsmethode ausgewählt werden (''photometry''). Hier spezifizieren wir '''APER''', und wählen so Apertur-Photometrie aus, bei der der Fluss der einzelnen Objekte und der zugehörigen Himmelshintergründe innerhalb einer fest definierten (hier kreis- bzw. ringförmigen) Apertur ausgelesen wird. Um diese Apertur zu spezifizieren geben wir noch den Radius für die kreisförmige Objektapertur (''rstars'') sowie die beiden Radien für die ringförmige Hintergrundapertur (''rbg_in'' und ''rbg_out'') an. Bewährt haben sich hier ''4'' sowie ''7'' und ''10''. Die Radien sind jeweils in Bogensekunden.  Die Identifikation der Sterne in den beiden Bildern erfolgt mittels der Funktion ''main_extract''. Diese Funktion nimmt als erstes Argument wiederum das ''image''-Objekt. Als optionales Argument kann dann noch die Extraaktionsmethode ausgewählt werden (''photometry''). Hier spezifizieren wir '''APER''', und wählen so Apertur-Photometrie aus, bei der der Fluss der einzelnen Objekte und der zugehörigen Himmelshintergründe innerhalb einer fest definierten (hier kreis- bzw. ringförmigen) Apertur ausgelesen wird. Um diese Apertur zu spezifizieren geben wir noch den Radius für die kreisförmige Objektapertur (''rstars'') sowie die beiden Radien für die ringförmige Hintergrundapertur (''rbg_in'' und ''rbg_out'') an. Bewährt haben sich hier ''4'' sowie ''7'' und ''10''. Die Radien sind jeweils in Bogensekunden. 
  
-   #   Extract objects +<code Python> 
-   main_extract( +#   Extract objects 
-       V_image, +main_extract( 
-       photometry_extraction_method='APER', +    V_image, 
-       radius_aperture=4., +    photometry_extraction_method='APER', 
-       inner_annulus_radius=7., +    radius_aperture=4., 
-       outer_annulus_radius=10., +    inner_annulus_radius=7., 
-   +    outer_annulus_radius=10., 
-   main_extract( +
-       B_image, +main_extract( 
-       photometry_extraction_method='APER', +    B_image, 
-       radius_aperture=4., +    photometry_extraction_method='APER', 
-       inner_annulus_radius=7., +    radius_aperture=4., 
-       outer_annulus_radius=10. +    inner_annulus_radius=7., 
-   )+    outer_annulus_radius=10. 
 +) 
 +</code>
  
 Zusätzlich zu den Sternkoordinaten (in Pixel) speichert ''main_extract'' auch alle extrahierten Flüsse automatisch in den ''image''-Objekten. Zusätzlich zu den Sternkoordinaten (in Pixel) speichert ''main_extract'' auch alle extrahierten Flüsse automatisch in den ''image''-Objekten.
Zeile 247: Zeile 257:
 Für die weiteren Schritte benötigen wir die extrahierten Flüsse und die Sternposition am Besten in Form von Astropy-Tabellen bzw. Spalten aus diesen. Die Tabellen mit den Ergebnissen erhalten wir mittels: Für die weiteren Schritte benötigen wir die extrahierten Flüsse und die Sternposition am Besten in Form von Astropy-Tabellen bzw. Spalten aus diesen. Die Tabellen mit den Ergebnissen erhalten wir mittels:
  
-   #   Get table +<code Python> 
-   photo_V = V_image.photometry +#   Get table 
-   photo_B = B_image.photometry +photo_V = V_image.photometry 
 +photo_B = B_image.photometry  
 +</code>
  
 Aus diesen lassen sich wiederum einfach die bestimmten Sternpositionen in Pixel extrahieren: Aus diesen lassen sich wiederum einfach die bestimmten Sternpositionen in Pixel extrahieren:
  
-   x_V = photo_V['x_fit'+<code Python> 
-   y_V = photo_V['y_fit']+x_V = photo_V['x_fit'].value.ravel() 
 +y_V = photo_V['y_fit'].value.ravel() 
 +</code>
  
 sowie sowie
-   x_B = photo_B['x_fit'+<code Python> 
-   y_B = photo_B['y_fit']+x_B = photo_B['x_fit'].value.ravel() 
 +y_B = photo_B['y_fit'].value.ravel() 
 +</code>
  
 === Kreuzkorrelation und Sortierung der Ergebnisse === === Kreuzkorrelation und Sortierung der Ergebnisse ===
Zeile 266: Zeile 282:
 Als erstes legen wir uns ''SkyCoord''-Objekte für jeden der beiden Datensätze an. Diese Objekte, wenn sie einmal definiert sind, erlauben die Ausgabe der Koordinaten in einer Vielzahl von bereits vordefinierten Koordinatensystem. Darüber hinaus, und das ist noch praktischer, werden diese Objekte auch als Argument von einer Reihe von //Astropy//-Funktionen und -Klassen akzeptiert. Aus diesem Grund braucht man sich in der Regel keine weiteren Sorgen darüber machen, in welchem Koordinatensytem man gerade eigentlich arbeitet, da dies alles intern von //Astropy// geregelt wird. Wir definieren unsere ''SkyCoord''-Objekte über die Option ''.from_pixel()'', welches es uns erlaubt diese direkt auf Basis der Pixelkoordinaten und des zuvor bestimmten WCS (welches wir dem ''image''-Objekt entnehmen können) zu definieren.   Als erstes legen wir uns ''SkyCoord''-Objekte für jeden der beiden Datensätze an. Diese Objekte, wenn sie einmal definiert sind, erlauben die Ausgabe der Koordinaten in einer Vielzahl von bereits vordefinierten Koordinatensystem. Darüber hinaus, und das ist noch praktischer, werden diese Objekte auch als Argument von einer Reihe von //Astropy//-Funktionen und -Klassen akzeptiert. Aus diesem Grund braucht man sich in der Regel keine weiteren Sorgen darüber machen, in welchem Koordinatensytem man gerade eigentlich arbeitet, da dies alles intern von //Astropy// geregelt wird. Wir definieren unsere ''SkyCoord''-Objekte über die Option ''.from_pixel()'', welches es uns erlaubt diese direkt auf Basis der Pixelkoordinaten und des zuvor bestimmten WCS (welches wir dem ''image''-Objekt entnehmen können) zu definieren.  
  
-   #   Create SkyCoord objects +<code Python> 
-   coords_V = SkyCoord.from_pixel(x_V, y_V, V_image.wcs) +#   Create SkyCoord objects 
-   coords_B = SkyCoord.from_pixel(x_B, y_B, B_image.wcs)+coords_V = SkyCoord.from_pixel(x_V, y_V, V_image.wcs) 
 +coords_B = SkyCoord.from_pixel(x_B, y_B, B_image.wcs) 
 +</code>
  
 Diese beiden ''SkyCoord''-Objekte können dann mittels der Funktion ''search_around_sky'' miteinander korreliert werden. Neben den beiden ''SkyCoord''-Objekten benötigt diese Funktion als drittes Argument noch die erlaubte Toleranz in den Koordinaten (unter derer zwei Objekte aus beiden Datensatz noch als das Gleiche erkannt werden). In unserem Fall wählen wir großzügige 2 Bogensekunden. Die Einheit wird hier über das ''astropy.units''-Paket definiert, dass wir oben unter der Abkürzung ''u'' geladen haben.  Diese beiden ''SkyCoord''-Objekte können dann mittels der Funktion ''search_around_sky'' miteinander korreliert werden. Neben den beiden ''SkyCoord''-Objekten benötigt diese Funktion als drittes Argument noch die erlaubte Toleranz in den Koordinaten (unter derer zwei Objekte aus beiden Datensatz noch als das Gleiche erkannt werden). In unserem Fall wählen wir großzügige 2 Bogensekunden. Die Einheit wird hier über das ''astropy.units''-Paket definiert, dass wir oben unter der Abkürzung ''u'' geladen haben. 
  
-   #   Correlate results from both images +<code Python> 
-   id_V, id_B, d2, _ = matching.search_around_sky(coords_V, coords_B, 2.*u.arcsec)+#   Correlate results from both images 
 +id_V, id_B, d2, _ = matching.search_around_sky(coords_V, coords_B, 2.*u.arcsec) 
 +</code>
  
 Die erfolgreich zugeordneten Sterne bekommen jeweils einen Eintrag in ''id_V'', ''id_B'' und ''d2''. Diese beiden ersten Listen (genauer gesagt Numpy arrays) enthalten die Indexwerte, die diese Sterne in den ursprünglich unsortierten Datensätzen hatten. Das heißt wir können diese Indexwerte nutzen, um die ursprünglichen Tabellen mit den Flüssen und Sternpositionen so zu sortieren, dass sie nur noch Sterne enthalten die in beiden Aufnahmen detektiert wurden und das die Reihenfolge der Sterne in beiden Datensätzen die Gleiche ist. Diese Zuordnung ist essentiell für das weitere Vorgehen.  Die erfolgreich zugeordneten Sterne bekommen jeweils einen Eintrag in ''id_V'', ''id_B'' und ''d2''. Diese beiden ersten Listen (genauer gesagt Numpy arrays) enthalten die Indexwerte, die diese Sterne in den ursprünglich unsortierten Datensätzen hatten. Das heißt wir können diese Indexwerte nutzen, um die ursprünglichen Tabellen mit den Flüssen und Sternpositionen so zu sortieren, dass sie nur noch Sterne enthalten die in beiden Aufnahmen detektiert wurden und das die Reihenfolge der Sterne in beiden Datensätzen die Gleiche ist. Diese Zuordnung ist essentiell für das weitere Vorgehen. 
Zeile 279: Zeile 299:
 Bevor dies jedoch geschehen kann, müssen noch potentielle Mehrfachidentifikationen aussortiert werden. Es ist nämlich möglich, dass ''matching.search_around_sky()'' z.B. Objekt 3 aus ''coords_V'' sowohl Objekt 2 als auch Objekt 4 aus ''coords_B'' zuordnet. Das Aussortieren dieser Duplikate erfolgt mit: Bevor dies jedoch geschehen kann, müssen noch potentielle Mehrfachidentifikationen aussortiert werden. Es ist nämlich möglich, dass ''matching.search_around_sky()'' z.B. Objekt 3 aus ''coords_V'' sowohl Objekt 2 als auch Objekt 4 aus ''coords_B'' zuordnet. Das Aussortieren dieser Duplikate erfolgt mit:
  
-   #   Identify and remove duplicate indices +<code Python> 
-       id_V, d2, id_B = clear_duplicates( +#   Identify and remove duplicate indices 
-           id_V, +id_V, d2, id_B = clear_duplicates( 
-           d2, +    id_V, 
-           id_B, +    d2, 
-       +    id_B, 
-       id_B, _, id_V = clear_duplicates( +
-           id_B, +id_B, _, id_V = clear_duplicates( 
-           d2, +    id_B, 
-           id_V, +    d2, 
-       )+    id_V, 
 +) 
 +</code>
  
 Anschließend können die Tabellen mit den photometrischen Werten sortiert werden, indem die Arrays mit den Indexwerten in die entsprechenden Tabellen eingesetzt werden. Auf diese Weise selektieren und sortieren wir gleichzeitig die Sterne, die in den beiden Aufnahmen identifiziert wurden. Anschließend können die Tabellen mit den photometrischen Werten sortiert werden, indem die Arrays mit den Indexwerten in die entsprechenden Tabellen eingesetzt werden. Auf diese Weise selektieren und sortieren wir gleichzeitig die Sterne, die in den beiden Aufnahmen identifiziert wurden.
  
-   #   Sort table with extraction results and SkyCoord object +<code Python> 
-   photo_V_sort = photo_V[id_V] +#   Sort table with extraction results and SkyCoord object 
-   photo_B_sort = photo_B[id_B] +photo_V_sort = photo_V[id_V] 
-    +photo_B_sort = photo_B[id_B] 
-   coords_objs = coords_V[id_V]+ 
 +coords_objs = coords_V[id_V] 
 +</code>
  
 Neben den beiden Tabellen mit den Extraaktionsergebnissen haben wir auch eines (welches ist egal) der ''SkyCoord''-Objekte sortiert. Dies wird uns im übernächsten Schritt noch von Nutzen sein. Neben den beiden Tabellen mit den Extraaktionsergebnissen haben wir auch eines (welches ist egal) der ''SkyCoord''-Objekte sortiert. Dies wird uns im übernächsten Schritt noch von Nutzen sein.
Zeile 305: Zeile 329:
 Da im folgenden in Magnituden gearbeitet wird, müssen die Flüsse entsprechend umgerechnet werden. Die Umrechnung kann gleich auf Basis der zuvor extrahierten Tabellen erfolgen (die Flüsse sind hier in der Spalte ''flux_fit'' abgelegt) bzw. die Magnituden können auch gleich als neue Spalte den Tabellen hinzugefügt werden: Da im folgenden in Magnituden gearbeitet wird, müssen die Flüsse entsprechend umgerechnet werden. Die Umrechnung kann gleich auf Basis der zuvor extrahierten Tabellen erfolgen (die Flüsse sind hier in der Spalte ''flux_fit'' abgelegt) bzw. die Magnituden können auch gleich als neue Spalte den Tabellen hinzugefügt werden:
  
-   #   Calculate magnitudes +<code Python> 
-   photo_V_sort['mag'] = -2.5 * np.log10(photo_V_sort['flux_fit']) +#   Calculate magnitudes 
-   photo_B_sort['mag'] = -2.5 * np.log10(photo_B_sort['flux_fit'])+photo_V_sort['mag'] = -2.5 * np.log10(photo_V_sort['flux_fit']) 
 +photo_B_sort['mag'] = -2.5 * np.log10(photo_B_sort['flux_fit']) 
 +</code>
  
 Man beachte, dass die Magnituden nur bis auf eine additive Konstante bestimmt sind, solange noch keine Eichung durchgeführt wurde.  Man beachte, dass die Magnituden nur bis auf eine additive Konstante bestimmt sind, solange noch keine Eichung durchgeführt wurde. 
Zeile 320: Zeile 346:
 ''II/336/apass9'' läuft. Des Weiteren definieren wir die Spalten, die wir benötigen. Wir beschränken uns hier auf die Spalten, die wir wirklich brauchen, um die Downloadzeit gering zu halten. Die Spaltenbezeichnungen sind zum Teil Katalog spezifisch, sodass für einen anderen Katalog unter Umständen andere Spaltenbezeichnungen zu benutzen sind. ''II/336/apass9'' läuft. Des Weiteren definieren wir die Spalten, die wir benötigen. Wir beschränken uns hier auf die Spalten, die wir wirklich brauchen, um die Downloadzeit gering zu halten. Die Spaltenbezeichnungen sind zum Teil Katalog spezifisch, sodass für einen anderen Katalog unter Umständen andere Spaltenbezeichnungen zu benutzen sind.
  
-   #   Get calibration from Vizier +<code Python> 
-   catalog = 'II/336/apass9' +#   Get calibration from Vizier 
-   columns = ['RAJ2000', 'DEJ2000', "Bmag", "Vmag", "e_Bmag", "e_Vmag"]+catalog = 'II/336/apass9' 
 +columns = ['RAJ2000', 'DEJ2000', "Bmag", "Vmag", "e_Bmag", "e_Vmag"] 
 +</code>
  
 Anschließend definieren wir das ''Vizier''-Objekt. Wir übergeben diesem die Katalog-ID, die Spaltendefinition und setzen das sogenannte ''row_limit'' noch auf 10^6. Durch letzteres wird die herunterzuladende Tabelle auf 10^6 Zeilen und somit das Downloadvolumen begrenzt. Dies machen wir, um beim Download nicht in eine Zeitüberschreitung des Servers zu laufen. Anschließend definieren wir das ''Vizier''-Objekt. Wir übergeben diesem die Katalog-ID, die Spaltendefinition und setzen das sogenannte ''row_limit'' noch auf 10^6. Durch letzteres wird die herunterzuladende Tabelle auf 10^6 Zeilen und somit das Downloadvolumen begrenzt. Dies machen wir, um beim Download nicht in eine Zeitüberschreitung des Servers zu laufen.
  
-   v = Vizier(columns=columns, row_limit=1e6, catalog=catalog)+<code Python> 
 +v = Vizier(columns=columns, row_limit=1e6, catalog=catalog) 
 +</code>
  
 Im nächsten Schritt können wir den Download ausführen. Hierbei nutzen wir die Funktion ''.query_region''. Dieser müssen wir noch die Koordinaten und die Größe des abzufragenden Himmelsbereiches übergeben. Glücklicherweise ist beides bereits bekannt. Die Koordinaten kennen wir aus den FIT-Header der Sternhaufenaufnahmen und für den Radius des abzufragenden Bereichs nehmen wir einfach das Gesichtsfeld, was wir uns bereits oben ausgerechnet haben. Beide Größen können wir z.B. dem ''V_image''-Objekt entnehmen. Im nächsten Schritt können wir den Download ausführen. Hierbei nutzen wir die Funktion ''.query_region''. Dieser müssen wir noch die Koordinaten und die Größe des abzufragenden Himmelsbereiches übergeben. Glücklicherweise ist beides bereits bekannt. Die Koordinaten kennen wir aus den FIT-Header der Sternhaufenaufnahmen und für den Radius des abzufragenden Bereichs nehmen wir einfach das Gesichtsfeld, was wir uns bereits oben ausgerechnet haben. Beide Größen können wir z.B. dem ''V_image''-Objekt entnehmen.
  
-   calib_tbl = v.query_region(V_image.V_image.coordinates_image_center, radius=V_image.field_of_view_x*u.arcmin)[0]+<code Python> 
 +calib_tbl = v.query_region(V_image.coordinates_image_center, radius=V_image.field_of_view_x*u.arcmin)[0] 
 +</code>
  
 Die Tabelle ''calib_tbl'' enthält nun alle in dem **APASS**-Katalog enthaltenen Objekte mit ihren ''B''- und ''V''-Magnituden, welche sich in unserem Gesichtsfeld befinden. Die Tabelle ''calib_tbl'' enthält nun alle in dem **APASS**-Katalog enthaltenen Objekte mit ihren ''B''- und ''V''-Magnituden, welche sich in unserem Gesichtsfeld befinden.
Zeile 345: Zeile 377:
 Anschließend muss nun der heruntergeladene Katalog mit den oben extrahierten Sternkoordinaten korreliert werden. Hierfür legen wir erneut ein ''SkyCoord''-Objekt an. Diesmal für die Kalibrationssterne. Anders als oben konstruieren wir das ''SkyCoord''-Objekt diesmal direkt aus den Rektaszension- und Deklinationskoordinaten, welche wir der Tabelle ''calib_tbl'' entnehmen können. Die Rektaszensionswerte findet man in der Spalte ''RAJ2000'', wohingegen die Deklinationswerte sich in der Spalte ''DEJ2000'' befinden. Des Weiteren müssen noch die Einheiten für die Koordinaten angegeben werden. In unserem Fall sind das jeweils Grad (''u.deg''). Als letztes Argument (''frame'') sollte noch das Koordinatensystem definiert werden. In unserem Fall müssen wir ''icrs'' angeben. Anschließend muss nun der heruntergeladene Katalog mit den oben extrahierten Sternkoordinaten korreliert werden. Hierfür legen wir erneut ein ''SkyCoord''-Objekt an. Diesmal für die Kalibrationssterne. Anders als oben konstruieren wir das ''SkyCoord''-Objekt diesmal direkt aus den Rektaszension- und Deklinationskoordinaten, welche wir der Tabelle ''calib_tbl'' entnehmen können. Die Rektaszensionswerte findet man in der Spalte ''RAJ2000'', wohingegen die Deklinationswerte sich in der Spalte ''DEJ2000'' befinden. Des Weiteren müssen noch die Einheiten für die Koordinaten angegeben werden. In unserem Fall sind das jeweils Grad (''u.deg''). Als letztes Argument (''frame'') sollte noch das Koordinatensystem definiert werden. In unserem Fall müssen wir ''icrs'' angeben.
  
-   #   Set up SkyCoord object with position of the calibration objects +<code Python> 
-   coord_calib = SkyCoord( +#   Set up SkyCoord object with position of the calibration objects 
-       calib_tbl['RAJ2000'].data, +coord_calib = SkyCoord( 
-       calib_tbl['DEJ2000'].data, +    calib_tbl['RAJ2000'].data, 
-       unit=(u.deg, u.deg), +    calib_tbl['DEJ2000'].data, 
-       frame="icrs" +    unit=(u.deg, u.deg), 
-       )+    frame="icrs" 
 +    ) 
 +</code>
  
-Wie bereits oben korrelieren wir auch hier die Kalibrationsdaten mit unseren Ergebnissen mittels der''search_around_sky''-Funktion aus dem ''matching''-Modul von //Astropy//. Als Argumente übergeben wir das soeben definierte ''SkyCoord''-Objekt''  für die Kalibrationssterne, das ''SkyCoord''-Objekt'' für die Sterne welche wir in beiden Filtern gefunden haben (''coords_objs'') sowie die maximale Distanz zwischen Sternen in beiden Datensätzen unter derer diese noch als das selbe Objekt erkannt werden.+Wie bereits oben korrelieren wir auch hier die Kalibrationsdaten mit unseren Ergebnissen mittels der''search_around_sky''-Funktion aus dem ''matching''-Modul von //Astropy//. Als Argumente übergeben wir das soeben definierte ''SkyCoord''-Objekt für die Kalibrationssterne, das ''SkyCoord''-Objekt für die Sterne welche wir in beiden Filtern gefunden haben (''coords_objs'') sowie die maximale Distanz zwischen Sternen in beiden Datensätzen unter derer diese noch als das selbe Objekt erkannt werden.
  
-   #   Correlate extracted object position with calibration table +<code Python> 
-   ind_fit, ind_lit, d2, _ = matching.search_around_sky( +#   Correlate extracted object position with calibration table 
-       coords_objs, +ind_fit, ind_lit, d2, _ = matching.search_around_sky( 
-       coord_calib, +    coords_objs, 
-       2.*u.arcsec, +    coord_calib, 
-       )+    2.*u.arcsec, 
 +    ) 
 +</code>
                
 Wie ebenfalls oben beschrieben, müssen nun noch die Dubletten aussortiert werden:  Wie ebenfalls oben beschrieben, müssen nun noch die Dubletten aussortiert werden: 
  
-   #   Identify and remove duplicate indexes +<code Python> 
-       ind_fit, d2, ind_lit = clear_duplicates( +#   Identify and remove duplicate indexes 
-           ind_fit, +ind_fit, d2, ind_lit = clear_duplicates( 
-           d2, +    ind_fit, 
-           ind_lit, +    d2, 
-       +    ind_lit, 
-       ind_lit, _, ind_fit = clear_duplicates( +
-           ind_lit, +ind_lit, _, ind_fit = clear_duplicates( 
-           d2, +    ind_lit, 
-           ind_fit, +    d2, 
-       )+    ind_fit, 
 +) 
 +</code>
  
 Auf diese Weise erhalten wir wieder Indexwerte, die wir nutzen können, um die Kalibrationssterne sowohl aus den Datensätzen für die beiden Filter als auch aus dem heruntergeladenen Katalog zu selektieren:   Auf diese Weise erhalten wir wieder Indexwerte, die wir nutzen können, um die Kalibrationssterne sowohl aus den Datensätzen für die beiden Filter als auch aus dem heruntergeladenen Katalog zu selektieren:  
  
-   #   Select data of the calibration stars +<code Python> 
-   photo_V_sort_calib = photo_V_sort[ind_fit] +#   Select data of the calibration stars 
-   photo_B_sort_calib = photo_B_sort[ind_fit] +photo_V_sort_calib = photo_V_sort[ind_fit] 
-    +photo_B_sort_calib = photo_B_sort[ind_fit]
-   #   Select literature data of the calibration stars +
-   calib_tbl_sort = calib_tbl[ind_lit] +
- +
-=== Magnitudenkalibrierung === +
- +
-Nun sind wir in der Lage die eigentliche Kalibrierung der Magnituden durchzuführen. Hierfür berechnen wir den sogenannten Zeropoint, indem wir für die Kalibrationssterne in jeden der beiden Filter unsere extrahierten Magnituden von den Magnituden aus dem heruntergeladenen Katalog abziehen und anschließend mit der Funktion ''.ma.median'' aus dem //Numpy//-Modul über alle Kalibrationssterne den Median bilden: +
- +
-   #   Calculate zero points +
-   ZP_V = np.ma.median(calib_tbl_sort['Vmag'] - photo_V_sort_calib['mag']) +
-   ZP_B = np.ma.median(calib_tbl_sort['Bmag'] - photo_B_sort_calib['mag']) +
- +
-Anschließend müssen die berechneten Zeropoints noch zu den Magnituden der Sterne in den Tabellen ''photo_V_sort'' und ''photo_B_sort'' addiert werden. Um die Übersichtlichkeit und Reproduzierbarkeit zu gewährleisten sollten die kalibrierten Magnituden jeweils in einer eigene Spalte den Tabellen hinzugefügt werden:+
  
-   #   Calibrate magnitudes +#   Select literature data of the calibration stars 
-   photo_V_sort['mag_cali'photo_V_sort['mag'+ ZP_V +calib_tbl_sort calib_tbl[ind_lit
-   photo_B_sort['mag_cali'] = photo_B_sort['mag'] + ZP_B+</code>
  
 +++++ Qualitätskontrolle I: Prüfen der Kalibrationssterne |
 +=== Starmap ===
  
-++++ Prüfen der Kalibrationssterne | 
 Eine Möglichkeit, die  Validität der Kalibrationssterne zu prüfen ist diese sich auf einer Starmap darzustellen (ähnlich zu dem was die ''main_extract'' oben automatisch macht). In diesem Fall wollen wir aber die heruntergeladenen Sternpositionen als auch die Sterne darstellen, die dann später auch wirklich für die Kalibrierung verwendet wurden. Hierfür bietet die OST-Bibliothek eine geeignete Funktion (''starmap'') an, die solche Plots erstellen kann. Diese Funktion kann über  Eine Möglichkeit, die  Validität der Kalibrationssterne zu prüfen ist diese sich auf einer Starmap darzustellen (ähnlich zu dem was die ''main_extract'' oben automatisch macht). In diesem Fall wollen wir aber die heruntergeladenen Sternpositionen als auch die Sterne darstellen, die dann später auch wirklich für die Kalibrierung verwendet wurden. Hierfür bietet die OST-Bibliothek eine geeignete Funktion (''starmap'') an, die solche Plots erstellen kann. Diese Funktion kann über 
  
-   from ost_photometry.analyze.plot import starmap+<code Python> 
 +from ost_photometry.analyze.plots import starmap 
 +</code>
  
 eingebunden werden. Da diese Funktion als Eingabe eine Astropy-Tabellen, mit den darzustellenden Daten erwartet, müssen wir zuerst diese erstellen, bevor wir die Starmap plotten können. Die Position der Kalibrationssterne liegen bisher nicht in Pixelkoordinaten vor, da wir diese Information von der Simbad- bzw. Vizier-Datenbank bezogen haben. Daher müssen wir zuerst diese erzeugen. An dieser Stelle ist es wieder praktisch, dass wir zuvor ein ''SkyCoord''-Objekt für diese Sterne erzeugt haben. Mittels ''.to_pixel()'' unter Angabe des WCS des Bildes lassen sich hieraus ganz einfach Pixelkoordinaten erzeugen: eingebunden werden. Da diese Funktion als Eingabe eine Astropy-Tabellen, mit den darzustellenden Daten erwartet, müssen wir zuerst diese erstellen, bevor wir die Starmap plotten können. Die Position der Kalibrationssterne liegen bisher nicht in Pixelkoordinaten vor, da wir diese Information von der Simbad- bzw. Vizier-Datenbank bezogen haben. Daher müssen wir zuerst diese erzeugen. An dieser Stelle ist es wieder praktisch, dass wir zuvor ein ''SkyCoord''-Objekt für diese Sterne erzeugt haben. Mittels ''.to_pixel()'' unter Angabe des WCS des Bildes lassen sich hieraus ganz einfach Pixelkoordinaten erzeugen:
  
-   #   Calculate object positions in pixel coordinates +<code Python> 
-   x_cali, y_cali = coord_calib.to_pixel(V_image.wcs)+#   Calculate object positions in pixel coordinates 
 +x_cali, y_cali = coord_calib.to_pixel(V_image.wcs) 
 +</code>
  
 Anschließend können wir mit diesen Information die Tabelle erstellen: Anschließend können wir mit diesen Information die Tabelle erstellen:
  
-   tbl_xy_cali_all = Table( +<code Python> 
-       names=['id','xcentroid', 'ycentroid'], +tbl_xy_cali_all = Table( 
-       data=[np.arange(0,len(y_cali)), x_cali, y_cali] +    names=['id','x_centroid', 'y_centroid'], 
-       )+    data=[np.arange(0,len(y_cali)), x_cali, y_cali] 
 +    ) 
 +</code>
  
 +/*
 Das Ganze wiederholen wir jetzt noch einmal für das ''SkyCoord''-Objekt, dass nur die Sterne enthält, die sowohl in der Datenbank waren als auch auf beiden Aufnahmen (beide Filter) des Sternhaufens identifiziert wurden: Das Ganze wiederholen wir jetzt noch einmal für das ''SkyCoord''-Objekt, dass nur die Sterne enthält, die sowohl in der Datenbank waren als auch auf beiden Aufnahmen (beide Filter) des Sternhaufens identifiziert wurden:
  
-   x_cali_s, y_cali_s = coords_objs.to_pixel(V_image.wcs+<code Python> 
-    +x_cali_s, y_cali_s = coords_objs.to_pixel(V_image.wcs)
-   tbl_xy_cali_s = Table( +
-       names=['id','xcentroid', 'ycentroid'], +
-       data=[np.arange(0,len(y_cali_s)), x_cali_s, y_cali_s] +
-       )+
  
-Daraufhin haben wir alles vorbereitet und können die Starmap plotten: +tbl_xy_cali_s = Table
-   starmap+    names=['id','x_centroid', 'y_centroid']
-       out_path, +    data=[np.arange(0,len(y_cali_s))x_cali_sy_cali_s]
-       V_image.get_data(), +
-       'V', +
-       tbl_xy_cali_all, +
-       label='Downloaded calibration stars', +
-       tbl_2=tbl_xy_cali_s, +
-       label_2='Identified calibration stars', +
-       rts='calibration',+
     )     )
 +</code>
 +*/
 +
 +Das Ganze wiederholen wir nun noch einmal für die Sterne, die wir tatsächlich als Kalibrationssterne verwenden können, also alle, die wir auch auf unseren Aufnahmen finden konnten. Hierfür erstellen wir zunächst ein entsprechendes ''SkyCoord''-Objekt:
 +
 +<code Python>
 +coord_calib_correlated = SkyCoord(
 +   calib_tbl_sort['RAJ2000'].data,
 +   calib_tbl_sort['DEJ2000'].data,
 +   unit=(u.deg, u.deg),
 +   frame="icrs",
 +)
 +</code>
 +
 +Anschließend können wir die Pixelkoordinaten wie oben beschrieben ermitteln und eine entsprechende Tabelle anlegen:
 +
 +<code Python>
 +x_cali_correlated, y_cali_correlated = coord_calib_correlated.to_pixel(V_image.wcs)
 +
 +tbl_xy_cali_correlated = Table(
 +   names=['id','x_centroid', 'y_centroid'],
 +   data=[np.arange(0,len(y_cali_correlated)), x_cali_correlated, y_cali_correlated]
 +)
 +</code>
 +
 +Daraufhin haben wir alles vorbereitet und können die Starmap plotten:
 +
 +<code Python>
 +starmap(
 +   out_path,
 +   V_image.get_data(),
 +   'V',
 +   tbl_xy_cali_all,
 +   label='Downloaded calibration stars',
 +   tbl_2=tbl_xy_cali_correlated,
 +   label_2='Identified calibration stars',
 +   rts='calibration',
 +)
 +</code>
  
 Hierbei ist das erste Argument unser Ausgabeverzeichnis, das zweite Argument das eigentlich Bild (als //Numpy//-Array), das dritte Argument die Filterbezeichnung, das vierte Argument die erste Tabelle, ''label'' das Label zum ersten Datensatz, ''tbl_2'' die zweite Tabelle, ''label_2'' das Label zum zweiten Datensatz und ''rts'' eine Beschreibung des Plots. Hierbei ist das erste Argument unser Ausgabeverzeichnis, das zweite Argument das eigentlich Bild (als //Numpy//-Array), das dritte Argument die Filterbezeichnung, das vierte Argument die erste Tabelle, ''label'' das Label zum ersten Datensatz, ''tbl_2'' die zweite Tabelle, ''label_2'' das Label zum zweiten Datensatz und ''rts'' eine Beschreibung des Plots.
Zeile 442: Zeile 504:
 **Alternativ** kann man die Starmap auch direkt über ''pyplot'' aus dem ''matplotlib''-Modul erstellen. Dies ist nicht viel aufwendiger bietet aber mehr Möglichkeiten zur Anpassung des Plots. Geladen wird ''pyplot'' mittels: **Alternativ** kann man die Starmap auch direkt über ''pyplot'' aus dem ''matplotlib''-Modul erstellen. Dies ist nicht viel aufwendiger bietet aber mehr Möglichkeiten zur Anpassung des Plots. Geladen wird ''pyplot'' mittels:
  
-   import matplotlib.pyplot as plt+<code Python> 
 +import matplotlib.pyplot as plt 
 +</code>
  
 Der "Grafikgrundstock" wird über Der "Grafikgrundstock" wird über
  
-   fig = plt.figure(figsize=(20,9))+<code Python> 
 +fig = plt.figure(figsize=(20,9)) 
 +</code>
  
 erstellt. Anschließend kann das eigentliche Bild geladen werden: erstellt. Anschließend kann das eigentliche Bild geladen werden:
  
-   plt.imshow(V_image, origin='lower')+<code Python> 
 +plt.imshow(V_image, origin='lower') 
 +</code>
  
 ''image'' sind hierbei die eigentlichen Bilddaten und ''origin=lower'' stellt sicher, dass das mit dem überplotten der Koordinaten auch klappt. Daraufhin können die Symbole, die die Sternposition kennzeichnen geplottet werden: ''image'' sind hierbei die eigentlichen Bilddaten und ''origin=lower'' stellt sicher, dass das mit dem überplotten der Koordinaten auch klappt. Daraufhin können die Symbole, die die Sternposition kennzeichnen geplottet werden:
  
-      plt.scatter(x_positions, y_positions)+<code Python> 
 +plt.scatter(x_positions, y_positions) 
 +</code>
  
 ''x_positions'' und ''y_positions'' sind hier die X- bzw Y-Sternpositionen in Pixel. ''.scatter'' bietet eine Vielzahl an Konfigurationsmöglichkeiten wie z.B. die Auswahl des Symbols, Farbe, Linienstärke und vieles vieles mehr. Diesbezüglich verweisen wir auf die vielfältigen Dokumentation und Tutorials hierzu im Internet. Auch bezüglich Labels, Titel, Legenden und Achsenbeschriftungen lassen sich dort mehr als genug Informationen finden. Über ''x_positions'' und ''y_positions'' sind hier die X- bzw Y-Sternpositionen in Pixel. ''.scatter'' bietet eine Vielzahl an Konfigurationsmöglichkeiten wie z.B. die Auswahl des Symbols, Farbe, Linienstärke und vieles vieles mehr. Diesbezüglich verweisen wir auf die vielfältigen Dokumentation und Tutorials hierzu im Internet. Auch bezüglich Labels, Titel, Legenden und Achsenbeschriftungen lassen sich dort mehr als genug Informationen finden. Über
  
-   plt.savefig(filename)+<code Python> 
 +plt.savefig(filename) 
 +</code>
    
 lässt sich der Plot abspeichern. Hierbei ist ''filename'' der Dateiname bzw. der Pfad zur Datei. Alternativ kann der Plot über lässt sich der Plot abspeichern. Hierbei ist ''filename'' der Dateiname bzw. der Pfad zur Datei. Alternativ kann der Plot über
  
 +<code Python>
    plt.show()    plt.show()
 +</code>
  
 auch direkt dargestellt werden. In diesem Fall muss aber unter Umständen das Backend geändert werden bevor ''plt.show()'' aufgerufen wird: auch direkt dargestellt werden. In diesem Fall muss aber unter Umständen das Backend geändert werden bevor ''plt.show()'' aufgerufen wird:
  
-   plt.switch_backend('TkAgg')+<code Python> 
 +plt.switch_backend('TkAgg') 
 +</code>
  
 Am Ende des Plots sollte dieser mittels Am Ende des Plots sollte dieser mittels
  
-   plt.close()+<code Python> 
 +plt.close() 
 +</code>
  
 geschlossen werden.    geschlossen werden.   
- + 
 +=== Histogramm mit Abständen zwischen den Objekten === 
 + 
 +Mithilfe dieser Vorbereitungen können wir auch gleich ein Histogramm der Abstände zwischen den von uns gemessenen Positionen und den Positionen aus der Literatur plotten. Dies kann Hinweise auf Fehlzuordnungen zwischen den Objekten liefern.  
 + 
 +Zunächst berechnen wir die benötigten Abstände mit Hilfe der ''SkyCoord''-Objekte: 
 + 
 +<code Python> 
 +#   Calculate separation between objects and the calibration objects 
 +sep_cal = coords_objs[ind_fit].separation( 
 +   coord_calib_correlated 
 +).arcsec 
 + 
 +#   Calculate separation between objects on the two images (inter-filter separations) 
 +sep_inter = coords_V[id_V].separation(coords_B[id_B]).arcsec 
 +</code> 
 + 
 +Bis auf die Starmaps, die ihr eigenes Verzeichnis haben, packen wir alle übrigen Diagnoseplots in ein eigenes Unterverzeichnis: 
 + 
 +<code Python> 
 +#   Prepare path for diagnostic plots 
 +diagnostic_path = os.path.join(out_path, 'diagnostics'
 +checks.check_output_directories(out_path, diagnostic_path) 
 +</code> 
 + 
 +Anschließend können wir das Histogramm plotten: 
 + 
 +<code Python> 
 +#   Plot separation histograms 
 +plot_combined_separation_histograms( 
 +   np.asarray(sep_inter, dtype=float), 
 +   np.asarray(sep_cal, dtype=float), 
 +   diagnostic_path, 
 +   'pdf', 
 +   reference_filter='V', 
 +   other_filters=['B'], 
 +
 +</code> 
 +++++ 
 + 
 +=== Magnitudenkalibrierung === 
 + 
 +Nun sind wir in der Lage die eigentliche Kalibrierung der Magnituden durchzuführen. Hierfür berechnen wir den sogenannten Zeropoint, indem wir für die Kalibrationssterne in jeden der beiden Filter unsere extrahierten Magnituden von den Magnituden aus dem heruntergeladenen Katalog abziehen und anschließend mit der Funktion ''.ma.median'' aus dem //Numpy//-Modul über alle Kalibrationssterne den Median bilden: 
 + 
 +<code Python> 
 +#   Calculate zero points 
 +ZP_V = np.ma.median(calib_tbl_sort['Vmag'] - photo_V_sort_calib['mag']) 
 +ZP_B = np.ma.median(calib_tbl_sort['Bmag'] - photo_B_sort_calib['mag']) 
 +</code> 
 + 
 +Anschließend müssen die berechneten Zeropoints noch zu den Magnituden der Sterne in den Tabellen ''photo_V_sort'' und ''photo_B_sort'' addiert werden. Um die Übersichtlichkeit und Reproduzierbarkeit zu gewährleisten sollten die kalibrierten Magnituden jeweils in einer eigene Spalte den Tabellen hinzugefügt werden: 
 + 
 +<code Python> 
 +#   Calibrate magnitudes 
 +photo_V_sort['mag_cali'] = photo_V_sort['mag'] + ZP_V 
 +photo_B_sort['mag_cali'] = photo_B_sort['mag'] + ZP_B 
 +</code> 
 + 
 +++++ Qualitätsskontrolle II: Stelle die instrumentellen Helligkeiten gegenüber den Kataloghelligkeiten und den Zeropoint-Abweichungen dar | 
 + 
 +Um die Qualität der Magnitudenkalibrierung einschätzen zu können, sollten wir uns die Verteilung der Magnituden sowie die Residuen der Nullpunkte visualisieren. Hierfür stellt die OST-Bibliothek einige Diagramme bereit. Um diese effizient nutzen zu können, definieren wir zunächst ein paar Abkürzungen: 
 + 
 +<code Python> 
 +m_inst_v = np.asarray(photo_V_sort_calib['mag'].ravel(), dtype=float) 
 +m_inst_b = np.asarray(photo_V_sort_calib['mag'].ravel(), dtype=float) 
 +m_cat_v = np.asarray(calib_tbl_sort['Vmag'].ravel(), dtype=float) 
 +m_cat_b = np.asarray(calib_tbl_sort['Bmag'].ravel(), dtype=float) 
 +m_cal_v = m_inst_v + float(zp_v) 
 +m_cal_b = m_inst_b + float(zp_b) 
 +</code> 
 + 
 +Anschließend können wir über die in der OST-Bibliothek bereitgestellten Plots direkt die gewünschten Abbildungen zur Qualitätskontrolle erstellen: 
 + 
 +<code Python> 
 +#   Plot instrumental vs. catalog magnitudes (V) 
 +plot_instrumental_vs_catalog_magnitudes( 
 +    m_cal_v, 
 +    m_cat_v, 
 +    diagnostic_path, 
 +    'pdf', 
 +    band_label='V', 
 +    show_one_to_one=True, 
 +    x_label=r'$m_\mathrm{cal}$ [mag]', 
 +    title='Cal stars: calibrated vs. catalog (V)', 
 +    filename_stem='calibrated_vs_catalog_V', 
 +
 + 
 +#   Plot instrumental vs. catalog magnitudes (B) 
 +plot_instrumental_vs_catalog_magnitudes( 
 +    m_cal_b, 
 +    m_cat_b, 
 +    diagnostic_path, 
 +    'pdf', 
 +    band_label='B', 
 +    show_one_to_one=True, 
 +    x_label=r'$m_\mathrm{cal}$ [mag]', 
 +    title='Cal stars: calibrated vs. catalog (B)', 
 +    filename_stem='calibrated_vs_catalog_B', 
 +
 + 
 +#   Plot zero point residuals distribution 
 +plot_zeropoint_residual_distribution( 
 +    None, 
 +    diagnostic_path, 
 +    'pdf', 
 +    residuals_by_band={ 
 +        'V': m_cat_v - m_inst_v - float(ZP_V), 
 +        'B': m_cat_b - m_inst_b - float(ZP_B), 
 +    }, 
 +    filename_stem='zeropoint_residuals_B_V', 
 +
 + 
 +#   Plot zero point residuals vs. color index 
 +color_lit = m_cat_b - m_cat_v 
 +plot_zeropoint_residual_vs_color( 
 +    color_lit, 
 +    None, 
 +    diagnostic_path, 
 +    'pdf', 
 +    residuals_by_band={ 
 +        'V': m_cat_v - m_inst_v - float(ZP_V), 
 +        'B': m_cat_b - m_inst_b - float(ZP_B), 
 +    }, 
 +    filename_stem='zeropoint_residual_vs_color_B_V', 
 +
 + 
 +#   Plot calibration color vs. color 
 +plot_calibration_color_color_cal_stars( 
 +    m_cat_b - m_cat_v, 
 +    m_inst_b - m_inst_v, 
 +    diagnostic_path, 
 +    'pdf', 
 +
 +</code> 
 ++++ ++++
 ==== Speichern der Ergebnisse ==== ==== Speichern der Ergebnisse ====
Zeile 480: Zeile 692:
  
  
-   #   Create new table for the CMD +<code Python> 
-   results = Table() +#   Create new table for the CMD 
-   results['id'] = photo_V_sort['id'+results = Table() 
-   results['x'] = photo_V_sort['x_fit'+results['id'] = photo_V_sort['id'].ravel() 
-   results['y'] = photo_V_sort['y_fit'+results['x'] = photo_V_sort['x_fit'].ravel() 
-   results['B [mag]'] = photo_B_sort['mag_cali'+results['y'] = photo_V_sort['y_fit'].ravel() 
-   results['V [mag]'] = photo_V_sort['mag_cali']+results['B [mag]'] = photo_B_sort['mag_cali'].ravel() 
 +results['V [mag]'] = photo_V_sort['mag_cali'].ravel() 
 +</code>
  
 Ist die neue Tabelle fertig befüllt, erlaubt es //Astropy// diese Tabelle sehr bequem über den Befehl ''.write'' zu speichern. Es muss noch als erstes Argument der Pfand bzw. Dateinamen angegeben werden, unter dem die Tabelle gespeichert werden soll. Des Weiteren spezifizieren wir noch das Format ''format'' (wir wählen hier ''ascii'') und setzen den Parameter ''overwrite'' auf ''True'', sodass falls wir das Skript mehrfach laufen lassen auch immer die aktuellen Daten in die Datei geschrieben werden können.   Ist die neue Tabelle fertig befüllt, erlaubt es //Astropy// diese Tabelle sehr bequem über den Befehl ''.write'' zu speichern. Es muss noch als erstes Argument der Pfand bzw. Dateinamen angegeben werden, unter dem die Tabelle gespeichert werden soll. Des Weiteren spezifizieren wir noch das Format ''format'' (wir wählen hier ''ascii'') und setzen den Parameter ''overwrite'' auf ''True'', sodass falls wir das Skript mehrfach laufen lassen auch immer die aktuellen Daten in die Datei geschrieben werden können.  
  
-   #   Save table +<code Python> 
-   results.write(out_path + 'cmd.dat', format='ascii', overwrite=True)+#   Save table 
 +results.write(out_path + 'cmd.dat', format='ascii', overwrite=True) 
 +</code>
  
 ===== Nachbearbeitung ===== ===== Nachbearbeitung =====
Zeile 523: Zeile 739:
 ausgeführt werden. Als Ergebnis erhält man eine PDF-Datei mit dem scheinbarem FHD. Die Axenskalierung erfolgt automatisch. Da dies aufgrund von Ausreißern nicht immer ideal ist, sollte der Plotbereich über die Variablen ''x_Range_apparent'' und ''y_Range_apparent'' angepasst werden. An dieser Stelle sind die Anführungszeichen einfach durch die Axenbegrenzungen zu ersetzen, wie z.B. ''x_Range_apparent = [-0.5, 2]'' ausgeführt werden. Als Ergebnis erhält man eine PDF-Datei mit dem scheinbarem FHD. Die Axenskalierung erfolgt automatisch. Da dies aufgrund von Ausreißern nicht immer ideal ist, sollte der Plotbereich über die Variablen ''x_Range_apparent'' und ''y_Range_apparent'' angepasst werden. An dieser Stelle sind die Anführungszeichen einfach durch die Axenbegrenzungen zu ersetzen, wie z.B. ''x_Range_apparent = [-0.5, 2]''
  
-   ############################################################################ +<code Python> 
-   ####          Configuration: modify the file in this section            #### +############################################################################ 
-   ############################################################################ +####          Configuration: modify the file in this section            #### 
-    +############################################################################ 
-   #   Name of the star cluster + 
-   nameOfStarcluster = "NGC7789" +#   Name of the star cluster 
-    +nameOfStarcluster = "NGC7789" 
-   #   Name of CMD data file + 
-   CMDFileName = "output/cmd.dat" +#   Name of CMD data file 
-    +CMDFileName = "output/cmd.dat" 
-   ### + 
-   #   Plot parameter +### 
-   +#   Plot parameter 
-    +
-   #   x_Range=[xRangeMin:xRangeMax] & y_Range=[yRangeMin:yRangeMax] + 
-   #       -> x and y range to plot (change according to your data) +#   x_Range=[xRangeMin:xRangeMax] & y_Range=[yRangeMin:yRangeMax] 
-   #       -> The plot range is automatically adjusted, if range is set to "" +#       -> x and y range to plot (change according to your data) 
-   #   Apparent CMD: +#       -> The plot range is automatically adjusted, if range is set to "" 
-   x_Range_apparent=["",""+#   Apparent CMD: 
-   y_Range_apparent=["",""+x_Range_apparent=["",""
-    +y_Range_apparent=["",""
-   #   Absolute CMD: + 
-   x_Range_absolute=["",""+#   Absolute CMD: 
-   y_Range_absolute=["",""]+x_Range_absolute=["",""
 +y_Range_absolute=["",""] 
 +</code>
  
 Hinweis: Neben diesen Einstellungen gibt es noch eine Reihe weiterer Konfigurationsmöglichkeiten, auf die wir hier aber nicht weiter eingehen. Hinweis: Neben diesen Einstellungen gibt es noch eine Reihe weiterer Konfigurationsmöglichkeiten, auf die wir hier aber nicht weiter eingehen.
Zeile 569: Zeile 787:
 Nachdem das $E_{(B-V)}$ und die Entfernung bzw. das Distanzmodul für den entsprechenden Sternhaufen herausgesucht wurden, können diese bei den entsprechenden Variablen im Skript ''3_plot_cmd.py '' eingetragen werden. ''m_M'' ist hierbei das Distanzmodul. Die übrigen Variablen sollten selbsterklärend sein. Ist entweder ''m_M'' oder ''distance'' gegeben, wird von dem Skript neben dem scheinbaren FHD auch das absolute FHD erstellt. Sollte es nötig sein $R_V$ anzupassen kann auch dies vorgenommen werden.  Nachdem das $E_{(B-V)}$ und die Entfernung bzw. das Distanzmodul für den entsprechenden Sternhaufen herausgesucht wurden, können diese bei den entsprechenden Variablen im Skript ''3_plot_cmd.py '' eingetragen werden. ''m_M'' ist hierbei das Distanzmodul. Die übrigen Variablen sollten selbsterklärend sein. Ist entweder ''m_M'' oder ''distance'' gegeben, wird von dem Skript neben dem scheinbaren FHD auch das absolute FHD erstellt. Sollte es nötig sein $R_V$ anzupassen kann auch dies vorgenommen werden. 
  
-   #   EB-V of the cluster +<code Python> 
-   eB_V = 0. +#   EB-V of the cluster 
-    +eB_V = 0. 
-   #   R_V + 
-   RV = 3.1 +#   R_V 
-    +RV = 3.1 
-   #   Give either distance modulus of the cluster or the distance in kpc + 
-   m_M = '?' +#   Give either distance modulus of the cluster or the distance in kpc 
-   +m_M = '?' 
-   distance = '?'+ 
 +distance = '?' 
 +</code>
        
 Hinweis: Neben diesen Einstellungen gibt es noch eine Reihe weiterer Konfigurationsmöglichkeiten, auf die wir hier aber nicht weiter eingehen. Hinweis: Neben diesen Einstellungen gibt es noch eine Reihe weiterer Konfigurationsmöglichkeiten, auf die wir hier aber nicht weiter eingehen.
Zeile 600: Zeile 820:
 Für die [[http://stev.oapd.inaf.it/cgi-bin/cmd|PARCEC-Isochronen]] sieht die Konfigurationsdatei z.B. so aus: Für die [[http://stev.oapd.inaf.it/cgi-bin/cmd|PARCEC-Isochronen]] sieht die Konfigurationsdatei z.B. so aus:
  
-   +<code YAML> 
-   --- +--- 
-   #   PARCES isochrones (CMD 3.6) +#   PARCES isochrones (CMD 3.6) 
-    + 
-   #   Files +#   Files 
-   # isochrones: '~/isochrone_database/parsec_iso/3p6/solar_0p2Gyr/iso_parsec_0p2Gyr.dat' +# isochrones: '~/isochrone_database/parsec_iso/3p6/solar_0p2Gyr/iso_parsec_0p2Gyr.dat' 
-   # isochrones: '~/isochrone_database/parsec_iso/3p6/solar_0p5Gyr/iso_parsec_0p5Gyr.dat' +# isochrones: '~/isochrone_database/parsec_iso/3p6/solar_0p5Gyr/iso_parsec_0p5Gyr.dat' 
-   isochrones: '~/isochrone_database/parsec_iso/3p6/solar_1Gyr/iso_parsec_1Gyr.dat' +isochrones: '~/isochrone_database/parsec_iso/3p6/solar_1Gyr/iso_parsec_1Gyr.dat' 
-    + 
-   #   Type +#   Type 
-   isochrone_type: 'file' +isochrone_type: 'file' 
-    + 
-   #   Type of the filter used in CMD plots +#   Type of the filter used in CMD plots 
-   #   Format: +#   Format: 
-   #     'filter name': +#     'filter name': 
-   #       - column type (single or color) +#       - column type (single or color) 
-   #       - ID of the filter if the column type is color, e.g., if the filter is +#       - ID of the filter if the column type is color, e.g., if the filter is 
-   #         R and the color is V-R, the filter ID would be 1. If column-type is +#         R and the color is V-R, the filter ID would be 1. If column-type is 
-   #         single, the ID will be 0. +#         single, the ID will be 0. 
-   #       - name of the second filter, in the example above it would be V. If +#       - name of the second filter, in the example above it would be V. If 
-   #         column-type is single, the name can be set to '-'+#         column-type is single, the name can be set to '-'
-   isochrone_column_type: +isochrone_column_type: 
-       'U':  +    'U':  
-         - 'single' +      - 'single' 
-         - 0 +      - 0 
-         - '-' +      - '-' 
-       'B':  +    'B':  
-         - 'single' +      - 'single' 
-         - 0 +      - 0 
-         - '-' +      - '-' 
-       'V':  +    'V':  
-         - 'single' +      - 'single' 
-         - 0 +      - 0 
-         - '-' +      - '-' 
-       'R':  +    'R':  
-         - 'single' +      - 'single' 
-         - 0 +      - 0 
-         - '-'+      - '-' 
 +  
 +#   ID of the columns in the isochrone data file containing the magnitudes 
 +#   and the age 
 +isochrone_column: 
 +    'U': 29 
 +    'B': 30 
 +    'V': 31 
 +    'R': 32 
 +    'AGE': 3
          
-   #   ID of the columns in the isochrone data file containing the magnitudes +#   Keyword to identify a new isochrone 
-   #   and the age +isochrone_keyword: '# Zini' 
-   isochrone_column: + 
-       'U': 29 +#   Logarithmic age 
-       'B': 30 +isochrone_log_age: true 
-       'V': 31 + 
-       'R': 32 +#   Plot legend for isochrones? 
-       'AGE':+isochrone_legend: true 
-        +... 
-   #   Keyword to identify a new isochrone +</code>   
-   isochrone_keyword: '# Zini' +
-    +
-   #   Logarithmic age +
-   isochrone_log_age: true +
-    +
-   #   Plot legend for isochrones? +
-   isochrone_legend: true +
-   ...+
  
 ''isochrones'' verweist auf die Datei mit den Isochronen. Hier ist ''isochrone_type'' auf ''file'' gesetzt, was dem Skript sagt, dass alle Isochronen in einer Datei zu finden sind. Eine Alternative ist ''directory''. In diesem Fall erwartet das Skript, dass die Isochronen in einzelnen Dateien in einem bestimmten Verzeichnis zu finden sind und dass die Variable ''isochrones'' auf dieses Verzeichnis zeigt. Mit ''isochrone_column'' kann man die gewünschten Spaltennummern angeben. ''isochrone_column_type'' gibt an, ob die Größen als Farben oder als "einzelne" Magnituden angegeben werden. Weitere Informationen findet man in der obigen Formatbeschreibung. Die grundlegenden Optionen sind hier ''color'' und ''single''. Mit ''isochrone_log_age'' kann man angeben, ob die Werte in der Altersspalte logarithmiert sind oder nicht. Man kann zwischen ''True'' und ''False'' wählen. Wenn sich die Isochronen alle in einer Datei befinden, benötigt das Skript ein Schlüsselwort, um zu erkennen, wann eine Isochrone endet und die nächste beginnt. Dies kann mit der Variablen ''isochrone_keyword'' angegeben werden. Schließlich kann man entscheiden, ob eine Legende für die Isochronen gezeichnet werden soll. Dies wird durch die Variable ''isochrone_legend'' gesteuert.  ''isochrones'' verweist auf die Datei mit den Isochronen. Hier ist ''isochrone_type'' auf ''file'' gesetzt, was dem Skript sagt, dass alle Isochronen in einer Datei zu finden sind. Eine Alternative ist ''directory''. In diesem Fall erwartet das Skript, dass die Isochronen in einzelnen Dateien in einem bestimmten Verzeichnis zu finden sind und dass die Variable ''isochrones'' auf dieses Verzeichnis zeigt. Mit ''isochrone_column'' kann man die gewünschten Spaltennummern angeben. ''isochrone_column_type'' gibt an, ob die Größen als Farben oder als "einzelne" Magnituden angegeben werden. Weitere Informationen findet man in der obigen Formatbeschreibung. Die grundlegenden Optionen sind hier ''color'' und ''single''. Mit ''isochrone_log_age'' kann man angeben, ob die Werte in der Altersspalte logarithmiert sind oder nicht. Man kann zwischen ''True'' und ''False'' wählen. Wenn sich die Isochronen alle in einer Datei befinden, benötigt das Skript ein Schlüsselwort, um zu erkennen, wann eine Isochrone endet und die nächste beginnt. Dies kann mit der Variablen ''isochrone_keyword'' angegeben werden. Schließlich kann man entscheiden, ob eine Legende für die Isochronen gezeichnet werden soll. Dies wird durch die Variable ''isochrone_legend'' gesteuert. 
Zeile 663: Zeile 884:
  
 Hinweis: Ein paar zusätzliche Informationen zu den einzelnen Variablen findet sich noch im //YAML//-Template. Hinweis: Ein paar zusätzliche Informationen zu den einzelnen Variablen findet sich noch im //YAML//-Template.
 +
 ===== Protokoll ===== ===== Protokoll =====
  
 Es ist ein übliches Protokoll einzureichen. Eine allgemeine Übersicht über den erforderlichen Aufbau und Inhalt findet man [[https://polaris.astro.physik.uni-potsdam.de/wiki/doku.php?id=de:praktikum:protocol|hier]]. Es ist ein übliches Protokoll einzureichen. Eine allgemeine Übersicht über den erforderlichen Aufbau und Inhalt findet man [[https://polaris.astro.physik.uni-potsdam.de/wiki/doku.php?id=de:praktikum:protocol|hier]].
  
 +/*
 Für diesen Versuch sollte im theoretischen Teil des Protokolls ein Überblick über offene und kugelförmige Sternhaufen mit Schwerpunkt auf dem beobachteten Typ und dessen Abgrenzung zu anderen Ansammlungen und Gruppen von Sternen beschreiben werden. Erläutern Sie was ein Hertzsprung-Russell-Diagramme (HRD) und was ein Farb-Helligkeits-Diagramme (FHD) ist und wie sich diese beiden Typen unterscheiden. Legen Sie des Weiteren //Kurz// die Entwicklung von Sternen unterschiedlicher Masse im Rahmen eines HRD da und erläutern Sie die Konzepte der Isochronen und des Abknickpunktes und wie man damit das Alter eines Sternhaufens schätzt. Für diesen Versuch sollte im theoretischen Teil des Protokolls ein Überblick über offene und kugelförmige Sternhaufen mit Schwerpunkt auf dem beobachteten Typ und dessen Abgrenzung zu anderen Ansammlungen und Gruppen von Sternen beschreiben werden. Erläutern Sie was ein Hertzsprung-Russell-Diagramme (HRD) und was ein Farb-Helligkeits-Diagramme (FHD) ist und wie sich diese beiden Typen unterscheiden. Legen Sie des Weiteren //Kurz// die Entwicklung von Sternen unterschiedlicher Masse im Rahmen eines HRD da und erläutern Sie die Konzepte der Isochronen und des Abknickpunktes und wie man damit das Alter eines Sternhaufens schätzt.
 +*/
  
-Beschreiben Sie im Methodenteil die Beobachtungen und die Datenreduktion, heben Sie Punkte hervor, die von der allgemeinen Beschreibung hier abweichen, und führen Sie alle Parameter auf, die Sie für die Extraktion gesetzt haben. Fügen Sie außerdem alle Diagramme der Datenreduktion in den Bericht ein (einige wenige im Text, die meisten im Anhang). Geben Sie auch alle Parameter für Rötung, Extinktion und Entfernung an, die Sie aus der Literatur übernommen haben.+Beschreiben Sie im Methodenteil die Beobachtungen und die Datenreduktion, heben Sie insbesondere Punkte hervor, die von der allgemeinen Beschreibung hier abweichen, und führen Sie alle Parameter auf, die Sie für die Extraktion gesetzt haben. Fügen Sie außerdem **alle Diagramme und Grafiken** der Datenreduktion in den Bericht ein. Geben Sie auch alle Parameter für Rötung, Extinktion und Entfernung an, die Sie aus der Literatur übernommen haben.
  
 Im Ergebnisteil werden die CMDs des Sternhaufens dargestellt und die darin beobachtbaren Merkmale beschrieben. Im Ergebnisteil werden die CMDs des Sternhaufens dargestellt und die darin beobachtbaren Merkmale beschrieben.
  • de/praktikum/photometrie_python.1739784196.txt.gz
  • Zuletzt geändert: 2025/02/17 09:23
  • von rhainich