Open dcesari opened 1 year ago
La tua analisi è sostanzialmente corretta.
Il codice che formatta i valori per --format
è qui: https://github.com/ARPA-SIMC/arkimet/tree/master/python/arkimet/formatter
La formattazione viene fatta a partire dai metadati arkimet e non dal grib, per cui non posso semplicemente interrogare eccodes, e devo reimplementare il lookup delle tabelle di eccodes. L'implementazione attuale è un po' un prototipo, visto che nessuno finora ha veramente guardato a cosa esce da --format
, e visto che sei il primo che ci guarda seriamente, hai l'onore di vincere facile e trovare un sacco di magagne.
Il codice si può sicuramente migliorare (c'è da capire come), anche se non si arriverà mai allo stesso livello di quello che dice eccodes, a meno di non mettersi a reimplementare l'interprete delle sue definition, che mi sembra fuori scope.
Il lavoro su questo fronte è duplice: sia implementare quello che manca, sia delineare i compromessi giusti su cosa non implementare per contenere la complessità del codice di formattazione.
Detto questo, possiamo progettare i passi successivi per migliorare la cosa, almeno sui dati che abbiamo
Grazie, si ricordavo di questo vecchio problema, che eccodes non espone le API per fare il parsing delle definizioni, poi pensavo che in qualche modo fosse stata trovata una soluzione senza rifare il parsing in casa, mentre evidentemente non è così.
La stranezza n.0, se non sbaglio, si risolverebbe con un'istruzione break
dopo questa riga https://github.com/ARPA-SIMC/arkimet/blob/0af4e0861dd497ca37a22739819e53a8d97beb53/python/arkimet/formatter/eccodes.py#L65 perché eccodes quando cerca un file in GRIB_DEFINITION_PATH
si ferma al primo che trova, non prosegue (prima metti le definitions specifiche, poi quelle generiche).
Questo comunque non risolverebbe il grosso del problema perché questo gioco delle tabelle esplicite vale solo per un sottoinsieme di tabelle locali (per intenderci, in grib1 quelle tipo grib1/2.[centre].[table2VersionNumber].table
a cui si potrebbe estendere il parsing ser già non è così. Purtroppo però, buona parte di quelle che interessano a noi sono definite in una maniera diversa tramite le tabelle in localConcepts/[centre]/...
e qui concordo sul fatto che non ha senso mettersi a reimplementare il parsing e la definizione dei localconcepts, se anche fossero documentati in qualche modo.
L'unica cosa che mi viene in mente è tenersi in memoria dei mini-gribtemplate da riempire con i metadati di product (origin, tableversion, indicatorofparameter, discipline, etc.) e poi usarli per chiedere ad eccodes le chiavi descrittive dei parametri. Non so quanto sia (in)efficiente un approccio del genere. Però anche questo non risolverebbe completamente perché diverse variabili in localConcepts (v. ad es. `grib1/localConcepts/edzw/name.def) fanno match solo se fa match contemporaneamente parametro e livello, che per noi sono metadati indipendenti, e quindi il risultato sarebbe parziale.
Insomma, approfondendo, vedo che non c'è una soluzione banale e forse neanche una non banale, ma magari la discussione ti stimola una buona idea...
Ripensandoci, non sarebbe un gran lavoro (da parte nostra) per grib1 ricreare a mano le tabelle locali esplicite grib1/2.[centre].[table2VersionNumber].table
per i parametri che ci interessano, se è possibile fare il parsing anche di quelle in eccodes.py.
Per grib2 bisogna vedere meglio, perché mi pare che non stia funzionando neanche con i parametri standard.
Intanto ho aggiunto il break che hai suggerito.
diverse variabili in localConcepts (v. ad es. `grib1/localConcepts/edzw/name.def) fanno match solo se fa match contemporaneamente parametro e livello, che per noi sono metadati indipendenti, e quindi il risultato sarebbe parziale
Ok, parliamo di questo. In teoria, ogni metadato in arkimet dovrebbe essere univocamente definito a prescindere dai valori degli altri metadati, che è il motivo, per esempio, per cui il prodotto riporta dentro l'identificatore del centro di emissione.
Se ho capito bene, ci sono casi per cui questa cosa non è piú vera, perché ci sono parametri che cambiano nome a seconda dei livelli, a parità di centro, categoria, disciplina, numero, dati della tabella.
È una situazione per cui se voglio il prodotto X non posso piú fare match solo sul product:
ma devo sempre specificare anche il livello?
A parte dare una possibile ambiguità per un prodotto se si presenta senza il livello associato, questo almeno non dovrebbe dare problemi in fase di identificazione di dati duplicati, perché se un dato valore di un prodotto potrebbe identificare due dati diversi, questi sono comunque sempre accompagnati da un livello che li discrimina, e finché la definizione unique
del dataset indica sia prodotto che livello, non c'è il rischio di collisioni
È il caso di rilassare l'idea che ogni elemento dei metadati sia completamente autocontenuto?
Questo potrebbe portare a un po' di cose interessanti:
Non so se questo sia sufficiente a riempire abbastanza l'header di un grib costruito da zero, in modo da poter chiamare la grib_api e farsi dire i nomíni per le varie cose (non so quanto efficiente possa essere una cosa del genere, ma si può provare a metterci su un po' di caching).
Oppure si può arrivare fin dove si arriva parsando le definition senza perderci la testa, e compensare il resto con delle tabelle hardcoded nei file python del formatter, che mi sembra un buon compromesso. Però in tutti i modi mi sembra che questo non arrivi un gran ché in là, almeno finché il formatter non possa riuscire a vedere tutto il metadato.
Sto pensando anche che ci sono situazioni in cui il formatter non può proprio avere a disposizione tutto il metadato: per esempio arki-query --summary-short --annotate
perde l'informazione su quali elementi dei metadati siano associati a quali altri
Il caso si complica: organizziamo una piccola call?
Volentieri, ci risentiamo tra una settimana circa (magari ricordamenlo), che ora sono in affanno.
For the medium term plan, I opened #306 and #307.
For the short term, I propose to maintain a file in /etc/arkimet/format/
with hand-crafted entries for the cases where the current formatter falls short.
Would you like an example of such a script?
Yes, please!
Ok, prova a mettere in /etc/arkimet/format
un file prova.py
con questo:
from arkimet.formatter import Formatter
def format_level(v):
# Gestisci alcuni livelli in modo speciale
if v["style"] == "GRIB1":
type, l1, l2 = v["level_type"], v.get("l1"), v.get("l2")
if type == 1:
return "Tutti giú per terra!"
# Lascia il comportamento di default
return None
Formatter.register("level", format_level)
Cercando di formattare un GRIB1 con livello al suolo dovrebbe venire "Tutti giú per terra!" invece del solito valore, e gli altri livelli restano immutati.
Lo script viene eseguito una volta sola, e solo la funzione format_level
viene chiamata per ogni livello. Questo vuol dire che fuori dalla format_level
si possono caricare e parsare file (tipo dalla eccodes) e il caricamento non avviene per ogni livello. Oppure si può caricare la prima volta che viene formattato un livello, e poi tenere in cache (usando per esempio functools.cache se si può usare python 3.9).
L'esempio è molto basilare: se serve qualcosa di piú specifico datemi un'idea di cosa deve fare e lo raffino
Grazie, credo di aver capito, sto preparando il formattatore per le variabili che mancano, ci riaggiorniamo.
Ho finalmente creato in https://github.com/ARPA-SIMC/arkimet/tree/master/conf/format un formattatore per le variabili locali dei modelli cosmo, consiste di qualche riga di formattazione e di un grosso dizionario generato da codice fortran, che a sua volta include pezzi del modello stesso. Testato su un file grib, funziona. Se va bene se ne potrebbe attivare l'installazione nel pacchetto.
Se avete qualche idea di un angolino in cui conservare anche il programma fortran, da rilanciare alla bisogna, fatemi sapere.
Ho aggiunto il file all'installazione, sia in autotools che in meson (anche se noi usiamo solo il secondo).
Problema` articolato. Nel tar issue300.tar.gz ci sono 4 messaggi grib, edzw e cnmc differiscono per il centro di emissione (DWD-Offenbach e Roma) mentre _1 e _2 differiscono per l'uso di una variabile standard WMO o locale rispettivamente. Ci sono inoltre delle definizioni aggiuntive locali di prova.
Lo scopo dei tentativi che generano questa issue è arrivare ad avere delle descrizioni corrette del Product in
arki-scan --annotate
(ovvero nelle interfacce arkiweb/meteohub) anche per parametri che stanno nelle tabelle locali e non in quelle standard WMO.Però fin dai primi tentativi mi sono scontrato con delle stranezze di comportamento del risultato di
--annotate
. Primo tentativo con i file grib allegati, non modifico nessun ambiente, uso le definizioni standard di eccodes:mentre grib_dump (non so con quale chiave interna) restituisce più giustamente in entrambi i casi:
trattandosi di variabile standard WMO; questa ci limitiamo a definirla stranezza numero 0.
Se ora faccio il source di
./profile
per arricchire le definizioni eccodes con quelle nella cartella corrente, per arki-scan non cambia niente, mentre il grib_dump restituisceche è il valore atteso in quanto ho taroccato la tabella relativa in
$PWD/definitions
.Quindi il primo problema nel tentativo di estendere le spiegazioni di
--annotate
è che -apparentemente-arki-scan
sembra ignorare eventuali definizioni aggiuntive fornite con la variabile d'ambienteECCODES_DEFINITION_PATH
.Passando ai messaggi *_2.grib, qui abbiamo una variabile della tabella 201 specifica del DWD che è in qualche modo nota anche nelle definizioni standard di eccodes, estensioni DWD (
/usr/share/eccodes/definitions/grib1/localConcepts/edzw
, edzw == DWD) e in effetti grib_dump, nel caso di centro DWD riconosce il parametro:ma nella didascalia che compare prima di indicatorOfParameter, che pare parzialmente coincidere con l'annotation di arki-scan, la variabile non è riconosciuta
e quindi
arki-scan --annotate grib:edzw_2.grib
non fornisce una didascalia in chiaro per il product:In questo caso la limitazione è che --annotate prende le informazioni da una parte, mentre le definizioni local del DWD specificano le informazioni da un'altra parte (chiave
name
ad es.), e quindi, se anche risolvessimo il pimo problema estendendo le definizioni italiane con quelle DWD, non otterremmo comunque la didascalia desiderata con arki-scan.