Ein Modul entspricht irgendeinem Programm (PPS, CPP) und wird angewendet auf einen SEVIRI Scan. Es kann durch module.run_all()
gestartet werden und generiert genau ein Produkt (eine netCDF Datei), das über module.product
verknüpft ist. Die abstrakte Basisklasse in module.py
gibt die Struktur vor, die von den erbenden Klassen in modules.py
implementiert werden muss (z.B. die Methoden _init()
, _run()
, etc). In der Methode run_all()
werden dann folgende Methoden aufgerufen:
self.init() # Umgebungsvariablen einrichten
self.unpack() # Input Daten auspacken (Download muss extern passieren)
self.create_required_dirs() # Arbeitsverzeichnisse erstellen, in denen das Modul lebt
self.post_dir_init() # Preprocessing, das Verzeichnisse benötigt (z.B. Config Files schreiben)
self.create_required_links() # Executables, input daten, ... in den Verzeichnissen verlinken
self.post_link_init() # Preprocessing, das die Links/Daten benötigt (z.B. NWP Daten remappen)
self.run() # Aufruf des Programms im Arbeitsverzeichnis
self.finalize() # Postprocessing (z.B. Dateien umbenennen, Attribute setzen)
Der ganze Spaß mit den Links ist nötig, weil die Software mit der wir arbeiten häufig nicht installierbar ist, sondern dort lebt und arbeitet wo sie kompiliert wurde. Durch das Linken klont und isoliert man diesen Lebensraum für jeden SEVIRI Scan.
Die obigen Methoden sind teilweise schon in der Basisklasse implementiert und tun dort die Dinge, die für alle Module gleich sind (z.B. Dateien umbenennen, leeres Produkt generieren). Andere sind mit @abstractmethod
dekoriert, d.h. die sind Modul-spezifisch und müssen in den PPS/CPP Klassen implementiert werden. Hier gibts jetzt folgende Aufgaben:
- Modul-spezifische Methoden in
modules.py
für PPS mit Leben füllen und für CPP auf den neuesten Stand bringen. Für PPS habe ich einfache Templates erstellt, wo Du sehen kannst, wie es funktioniert (class PPSCmask
,class PPSCtth
). Ich habe auf meinem Laptop z.B. Dummy Executables fürpps-cmask
undpps-ctth
erstellt, die einfach nur hallo sagen und eine leere Datei mit dem richtigen Namen erzeugen. Damit läuft dannclaas-run
schonmal komplett durch. - Außerdem muss das Postprocessing in
module.py
aktualisiert werden (Module.create_product
undModule._create_empty_product
). Sowohl das Umformatieren der PPS/CPP Produkte, als auch das Generieren leerer Produkte wenn es keinen Output gibt (keine Input Daten oder Crash). Ersteres kommt ja von Irina, für letzteres habe ich auch ein Template erstellt. Dort kann man auch gut sehen, wozu die ganzen Produkt- und Variablen Definitionen gut sind.
Damit das alles so schön funktioniert, muss man außerdem
- Für jedes Modul angeben, welches Produkt es generiert. Produkt-Definitionen liegen in
products.py
- Für jedes Produkt angeben,
- welche Variablen es enthält (damit man auch ohne PPS/CPP Output ein leeres Produkt erstellen kann; außerdem zum Plotten hilfreich). Variablen-Definitionen liegen in
variables.py
. - mit welchen CM SAF Metadaten es verknüpft ist (im Config File, Abschnitt
meta_info
). Das bestimmt z.B. den Dateinamen und damit später die Datenbank Kategorie und Anzeige im WUI.
- welche Variablen es enthält (damit man auch ohne PPS/CPP Output ein leeres Produkt erstellen kann; außerdem zum Plotten hilfreich). Variablen-Definitionen liegen in
Auch hier habe ich Templates für PPS erstellt, mit denen Du anfangen kannst.
Cleanup: Modul-spezifisches Cleanup ist nur nötig für Dateien, die an nicht-Standard Orten erstellt wurden (s.u.).
Für einige Pfade und Einstellungen von PPS macht es sicher Sinn, sie im Config File anzugeben. Auch hier habe ich ein Template in config.py
hinzugefügt (class PPSConfig
), an dem Du Dich orientieren kannst. Es wird auch schon in den PPS Klassen benutzt. Wenn Du neue Einträge zum Config File hinzufügen willst, musst Du sie inklusive Datentyp auch in der Spezifikation claas/data/claas.cfg.spec
einfügen. Dann werden sie richtig geparsed und überprüft.
Das Arbeitsverzeichnis wird ja über scratch_dir
im Config File angegeben. Dort gibt's folgende Unterordner:
download/ # Heruntergeladene Input Daten (gepackt). claas-get-mars/ecfs schreiben hier rein
upload/ # Hier werden finale Produkte tages-/monatsweise zusammengepackt, um sie ins ECFS hochzuladen (claas-archive)
import/ # ausgepackte Input Daten
work/ # Arbeitsverzeichnisse
# Hier lebt ein Modul für einen Scan.
# Hier können nach Belieben Verzeichnisse und Links erstellt
# werden, um das Modul zu isolieren.
yyyymmdd/HHMM/module_name/
exch/ # Hierüber können Daten Modul-übergreifend ausgetauscht werden
intermediate_products/
yyyymmdd/
# Zwischenprodukte, die von einem/mehreren nachfolgenden Scan(s)
# benötigt werden, z.B. CPP_RTTOV output oder irgendwelche Winkel
# für die Mittelung.
HHMM/
# Zwischenprodukte nur von diesem Scan. Hier landen momentan die
# PPS/CPP Produkte.
claas-run
löscht automatisch folgende Daten, nachdem alle Module für den Scan durchgelaufen sind (vorausgesetzt cleanup=True
im Config File):
- Arbeitsverzeichnisse
work/yyyymmdd/HHMM/[pps,cpp,cpp_rttov]
- Ausgepackte SEVIRI Daten in
import/seviri_data/yyyymmdd/HHMM
- Zwischenprodukte in
exch/intermediate_products/yyyymmdd/HHMM
Wenn ein Modul abstürzt, wird nicht aufgeräumt, damit man debuggen kann. Daten, die außerhalb dieser Verzeichnisse angelegt werden, müssen in Module._cleanup()
gelöscht werden. Das betrifft z.B. den CPP_RTTOV Output. CPP_RTTOV muss ja nur ein mal pro NWP File gerechnet werden und kann von mehreren Scans wiederverwendet werden. Der Output wird in exch/intermediate_products/yyyymmdd
gespeichert und von CPPRTTOV._cleanup()
gelöscht, sobald er out of date ist weil es ein neueres NWP file gibt.
Dann gibt es noch Daten, die ein Modul nicht selbst löschen kann, weil es noch andere Abhängigkeiten gibt. Z.B. werden NWP Daten auch von mehreren Scans benutzt, sogar über die Tagesgrenze hinaus (NWP File von d+1 00:00 ist näher am 23:45 Scan als das NWP File von 23:00). Wenn man dann auf Tagesbasis parallelisiert, dürfen die NWP Daten von Tag n
erst aufgeräumt werden, wenn Tag n-1
auch fertig ist. Oder aber L2 Produkte müssen aufgehoben werden, bis das Tagesmittel erstellt wurde. All diese Daten werden von claas-cleanup
gelöscht. Es wird von ecflow getriggert, unter Berücksichtigung dieser Abhängigkeiten.
cd pycmsaf && pip install .
cd claas && pip install .[plot]
Die Plotting Tools brauchen noch Basemap, und das gibt's leider nicht auf pypi.org, deswegen muss man es von Source installieren.
cd basemap-1.2.1rel && GEOS_DIR=/cmsaf/nfshome/routcm/Modules_CentOS/tools/2020.01 pip install .
Quellcode gibt's auf github. Da die Plotting Funktionalität hoffentlich bald in die CM SAF Toolbox eingebaut wird, macht es nicht viel Sinn, die Sachen hier noch auf Cartopy umzuziehen.
- Die NWP Klassen habe ich nur nach
ERA5
umbenannt. Da musst Du dir noch was ausdenken, wie Du die am besten an die neue CDS Logik anpasst. claas-get-mars
sollte man wohl nachclaas-get-nwp
umbenennen- Bisher war das L2 Gitter (aka area definition) fest verdrahtet (suche nach
full_disk
) weil statisch. Jetzt ist es zeitabhängig. Das muss berücksichtigt werden. - Änderungen am Config File:
- Die Metadaten für die Produkte (Abschnitt
meta_info
) müssen noch aktualisiert werden. Im Besten Fall nur Version003
nach004
erhöhen. - Ebenso müssen die globalen netCDF Attribute (Abschnitt
ncattrs
) auf den CDOP-3 Standard aktualisiert werden. Das meiste davon hat Irina sicherlich schon recherchiert. - In CLAAS-2 hatten wir keinen direkten Zugriff auf die Satelliten-Position jedes Scans. Daher haben wir eine Liste der Maneuver (d.h. permanente Positionsänderungen) im Config File angegeben (Abschnitt
platforms
). Die brauchen wir jetzt zwar nicht mehr für die eigentliche Prozessierung, aber wir sollten sie trotzem weiter pflegen, denn für einige Tools ist es praktisch die Maneuver offline zu haben ohne alle Daten durchsuchen zu müssen (data availability plots, Aux Daten).
- Die Metadaten für die Produkte (Abschnitt
- Die Reprocessing Datenbank (welcher Satellit welchen Scan aufgenommen hat) muss noch aktualisiert werden (siehe Manual). Zugang zur SKY Datenbank hast Du schon, oder? Die Ursprüngliche Motivation für diese Datenbank war die Reduktion von von
ls
Aufrufen, weil die bei ECMWF extremst langsam waren. Wenn ich aber weiß, welchen Satellit ich erwarte, kann ich alle Dateinamen vorher bestimmen und direkt drauf zugreifen, anstatt einls
zu machen. Ich weiß nicht, ob das immer noch ein Problem ist. Falls nicht, könnte man drüber nachdenken, das rauszuwerfen und nur den Teil der Datenbank zu behalten, in dem Prozessierungsfehler gespeichert werden. Das automatische Erkennen der Plattform aus dem Dateinamen ist schon implementiert und wird im ICDR schon verwendet. - Ansonsten gibts überall noch
#TODO
Kommentare im Code, die dich dran erinnern sollen, dass da noch was gemacht werden muss. Wenn was unklar ist einfach fragen! - Ich habe in
setup.py
mal schnell die neuen Requirements reingehackt. Musst mal testen, ob das in Deiner Conda Umgebung Probleme macht und dann die Versionsnummern angeben wo sie noch fehlen.
Und noch ein Paar Bemerkungen zu den einzelnen Scripten:
claas-domain-bounds
: Wird im WUI benutzt, um für eine gegebene lat/lon Box auszurechnen, welche SEVIRI Pixel man ausschneiden mussclaas-plot
: Wird aktuell im WUI für Quicklooks benutzt. Soll aber von der Toolbox abgelöst werden.claas-cmp
: Tool um Produkte verschiedener Runs miteinander zu vergleichenclaas-maneuvers
: Lädt Orbit Parameter von EUM runter und leitet daraus für jeden Satelliten die Maneuver ab.tools/plot_data_availability.py
: Erstellt einen Plot wo man sieht wann welche Plattform auf welcher position operationell war. Wird fürs ATBD gebraucht.
cd claas && pip install -e .[plot]
. Damit werden nur Links auf Dein Arbeitsverzeichnis installiert. Alle Änderungen am Quellcode werden also sofort wirksam ohne neu installieren zu müssen. Und Du kannst auch direkt testen, wie sich das installierte Paket verhält.- Beim Testen nicht vergessen: Du kannst im Config File in der ersten Zeile angeben, welche Abschnitte Du skippen willst. Außerdem kannst Du jedes Script mit
--no-checks
aufrufen, dann werden die Einträge nicht geprüft.
- Backup für finale Produkte (~30T) finden, bis der Datensatz released ist und die Produkte in der DWD Datenbank archiviert sind. DWD-ECFS ist leider keine Option.