.. _variable-attributes: Variablen und deren Attribute ============================= Der Variablenname in der netCDF-Datei ist im Prinzip frei wählbar (unter Beachtung der Anmerkungen in Kapitel 2.2), die Variable muss jedoch über die entsprechenden *attributes* (s. Tabelle in 4.2) beschrieben werden. In vielen Communities haben sich Standards für diese Namen etabliert wie z.B. die mehrfach angesprochene P09-Datenbank [8]_. Es gibt verpflichtende und optionale Attribute. .. _variable-types: Datentypen ---------- Es werden nur netCDF *data types* char, byte, short, float, real, double akzeptiert. .. _variable-mandatory: Verpflichtende Attribute ------------------------ Zu jeder Variable *müssen* Angaben zur Einheit (units) sowie zur Definition (standard_name\ [9]_ bzw. long_name) gemacht werden. In seltenen Spezialfällen ist es nicht sinnvoll, einen standard_name zu beantragen. Nur dann ist das *attribute* long_name verpflichtend und der long_name sollte wie ein Standardname konstruiert werden. .. card:: Example (dimensionslose Größe, ``standard_name`` existiert, ``long_name`` frei wählbar) .. code-block:: double Salinity(levels) ; Salinity:units = " 1e-3 " ; Salinity:standard_name = "sea_water_salinity" ; Salinity:long_name = "salinity from SeaBird CTD" ; Wenn der passende *Standard Name Modifier* nicht in der Tabelle eingetragen ist, muss er anlog zum *standard_name* bei cf-metadata beantragt werden (siehe standard_name\ [9]_). .. [8] http://seadatanet.maris2.nl/v_bodc_vocab_v2/browse.asp?order=conceptid&formname=search&screen=0&lib=p09&v1_0=conceptid%2Cpreflabel%2Caltlabel%2Cdefinition%2Cmodified&v2_0=0&v0_1=&v1_1=conceptid&v2_1=3&v0_2=&v1_2=preflabel&v2_2=3&v0_3=&v1_3=altlabel&v2_3=3&v0_4=&v1_4=modified&v2_4=9&v0_5=&v1_5=modified&v2_5=10&v1_6=&v2_6=&v1_7=&v2_7= .. [9] Existiert dieser bisher in der cf-conventions Tabelle nicht, sollte er beantragt werden. Weitere Infos zu Standardnamen und deren Beantragung bei Beate Geyer und https://github.com/cf-convention/discuss/. .. metadata_table:: data/variable_mandatory.yml .. _variable-optional: Optionale Attribute ------------------- Die optionalen Attribute sollen die Beschreibung der Variable sinnvoll ergänzen. .. metadata_table:: data/variable_optional.yml .. card:: Beispiel für die Verwendung des Attributs cell_methods: .. code-block:: dimensions: time = UNLIMITED ; // (744 currently) bnds = 2 ; rlon = 234 ; rlat = 228 ; variables: double time(time) ; time:standard_name = "time" ; time:long_name = "time" ; time:units = "seconds since 1948-01-01 00:00:00" ; time:bounds = "time_bnds" ; double time_bnds(time, bnds) ; time_bnds:long_name = "time bounds" ; time_bnds:units = "seconds since 1948-01-01 00:00:00" ; float TOT_PREC(time, rlat, rlon) ; TOT_PREC:standard_name = "precipitation_amount" ; TOT_PREC:long_name = "total precipitation amount" ; TOT_PREC:units = "kg m-2" ; TOT_PREC:cell_methods = "time: sum" ; .. _variable-missing: Umgang mit fehlenden Daten -------------------------- - Fehlende Werte im Datensatz werden nur durch das *attribute* \_FillValue angezeigt. Der *value* von \_FillValue kann NaN oder NaN.f (bei float) gesetzt werden. In manchen Fällen hat man sich auf andere Werte zur Benennung der aus technischen Gründen fehlenden Werte geeinigt (-1.0E20 ist ein oft verwendeter Standard). Die Verwendung eines tatsächlichen Wertes hat den Vorteil, dass in Visualisierungen wie ncWMS die Pixel mit dem Wert von \_FillValue transparent dargestellt werden. Dateien mit einem \_FillValue = NaN können nicht für ncWMS\ **2** verwendet werden, da ncwms2 dieses nicht mehr unterstützt (vgl. Abschnitt :ref:`variable-types`). .. _variable-coordinates: Koordinaten ----------- Koordinaten sind die Variablen zu einer Dimension. Da die richtige Angabe der Koordinaten von immenser Wichtigkeit ist, die Erläuterungen hier aber allgemein gehalten sind, finden sich im Anhang verschiedene Beispiele aus Datensätzen des Hereons für Koordinatenangaben. Den geografischen Längen- und Breitengraden zugeordneten Dimensionen sollen Indices von West nach Ost bzw. Süd nach Nord aufsteigend zugeordnet werden. .. _variable-latitude: Geographische Breite ~~~~~~~~~~~~~~~~~~~~ - Der Variablenname ist ``lat`` und das Format float. - Das *attribute* units ist ``degrees_north`` [11]_. - Das *attribute* standard_name ist ``latitude``. - Das *attribute* axis (optional) erhält den *value* ``Y``. - Bei transformierten Gittern (z.B. Koordinatensystemen mit rotierten Polen) wird als units nur degrees verwendet. .. card:: Beispiel .. code-block:: dimensions: lon = 69 ; lat = 64 ; float lat(lat); lat:units = "degrees_north" ; lat:standard_name = "latitude" ; .. [11] http://cfconventions.org/cf-conventions/cf-conventions.html#_independent_latitude_longitude_vertical_and_time_axes .. _variable-longitude: Geographische Länge ~~~~~~~~~~~~~~~~~~~ - Der Variablenname ist ``lon`` und das Format float. - Das *attribute* units ist ``degree_east``. [11]_ - Das *attribute* standard_name ist ``longitude``. - Das *attribute* axis (optional) erhält den *value* ``X``. - Bei transformierten Gittern (z.B. Koordinatensystemen mit rotierten Polen) wird als units nur degrees verwendet. .. card:: Beispiel .. code-block:: dimensions: lon = 69 ; lat = 64 ; float lon(lon); lon:units = "degrees_east" ; lon:standard_name = "longitude" ; .. _variable-height: Höhen- und Tiefenangaben (vertical coordinates) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Das *attribute* positive ist obligatorisch, da häufig Uneinigkeit über die Richtung der Vertikalkoordinate besteht. - Die Richtung aufsteigender Koordinatenwerte ist mit dem *attribute* positive und den möglichen *values* up oder down zu versehen. .. card:: Beispiele .. tab-set:: .. tab-item:: Allgemein .. code-block:: axis_name:units = "m" ; axis_name:positive = "down" ; .. tab-item:: Pressure .. code-block:: double Pressure(levels) ; Pressure:units = "dbar" ; Pressure:standard_name = "sea_water_pressure" ; Pressure:positive = "down" ; Hier liegt der Koordinatenursprung an der Meeresoberfläche; Druck nimmt mit Tiefe zu. .. tab-item:: Altimeter .. code-block:: double Altimeter(levels) ; Altimeter:units = "m" ; Altimeter:positive = "up" ; Altimeter: standard_name = "height_above_sea_floor" ; Altimeter:long_name = "distance to bottom" ; Hier liegt der Koordinatenursprung am Boden. Der Wert nimmt zu, wenn man sich der Meeresoberfläche nähert. .. tab-item:: Depth .. code-block:: double Depth(levels) ; Depth:units = "m" ; Depth:positive = "down" ; Depth:long_name = "water depth relative to sea surface" ; Depth:standard_name = "depth" ; Hier liegt der Koordinatenursprung an der Meeresoberfläche. .. tab-item:: 2D variable with depth .. code-block:: double time(time) ; time:standard_name = "time" ; time:long_name = "time" ; time:units = "seconds since 1979-01-01 00:00:00" ; float rlon(rlon) ; rlon:standard_name = "grid_longitude" ; rlon:long_name = "rotated longitude" ; rlon:units = "degrees" ; float rlat(rlat) ; rlat:standard_name = "grid_latitude" ; rlat:long_name = "rotated latitude" ; rlat:units = "degrees" ; float height_2m ; height_2m:standard_name = "height" ; height_2m:long_name = "height above the surface" ; height_2m:units = "m" ; height_2m:positive = "up" ; float T_2M(time, rlat, rlon) ; T_2M:standard_name = "air_temperature" ; T_2M:long_name = "2m temperature" ; T_2M:units = "K" ; T_2M:coordinates = "lon lat height_2m" ; Obwohl die Temperatur in 2 m Höhe über Grund angegeben wird, gibt es dafür keine eigene *dimension*. .. _variable-time: Zeit-Koordinate (time) ~~~~~~~~~~~~~~~~~~~~~~ Der *value* von *units* für die Zeitkoordinate time ist, z.B. - ``"days since YYYY-MM-DD HH:mm:SS"`` oder - entsprechende Formulierungen [13]_ **Eine Zeitzonenangabe erfolgt nicht!** Damit ist UTC automatisch als Zeitkoordinate festgelegt. Als *type* möglichst *double* verwenden, sonst besteht die Gefahr, dass Sekunden nicht mehr aufgelöst werden. Das *attribute* ``calendar`` sollte auf ``proleptic-gregorian`` oder ``standard`` gesetzt sein. Im Falle von Vereinfachungen, wie Rechnungen ohne Schaltjahr oder nur Monaten mit 30 Tagen, wird diesen durch das entsprechende Kalender-Attribut Rechnung getragen: ``noleap`` bzw. ``360_day``. .. card:: Beispiel .. code-block:: dimensions: time = UNLIMITED ; // (744 currently) variables: double time(time) ; time:standard_name = "time" ; time:long_name = "time" ; time:calendar = "proleptic_gregorian" ; .. [13] weitere Erläuterungen: http://cfconventions.org/cf-conventions/cf-conventions.html#time-coordinate .. _variable-quality-flags: Quality Flags ~~~~~~~~~~~~~ Quality Flags ------------- In der Regel wird man *Quality Flags* nur bei Beobachtungsdaten verwenden. Das Fernziel in Bezug auf Qualität ist die Abschätzung und Angabe eines Fehlers. Dies könnte dann auch für Modelloutput gelten. Die folgenden Vorschriften von OceanSites [14]_ sind für Daten verbindlich, die für den Copernicus Marine Environment Monitoring Service vorgesehen sind und dort auch verwaltet werden. Wenn möglich, sollten Beobachtungsdaten immer mit *Quality Flags* angegeben werden. Diese *Quality Flags* geben für jeden Datenpunkt an, ob dieser Datenpunkt über eine Qualitätskontrolle abgesichert wurde und wie das Ergebnis dieser Qualitätskontrolle war. Das *Quality Flag* gibt keine Auskunft darüber, ob der Datenpunkt nahe bei der Realität liegt. In der netCDF-Datei eignet sich als *Quality Flag* eine zusätzlich Variable, die den gleichen Namen hat wie die Variable, für die die Qualitätsangabe gilt, aber mit einem angehängten String "_QC" (OceanSITES) bzw. "_qc" (CF-conventions, vgl. Kapitel *Flags*\ [15]_). "QC" steht für *Quality Control* des jeweiligen Parameters. Beispielnamen sind TIME_QC, POSITION_QC oder TEMP_QC. Für die Attribute dieser Variablen gilt:: conventions = "OceanSITES reference table 2" ; long_name = "quality flag" ; _FillValue = -128b ; valid_min = 0b ; valid_max = 9b ; flag_values = "0, 1, 2, 3, 4, 5, 7, 8, 9" ; flag_meanings = "no_qc_performed good_data probably_good_data bad_data_that_are_potentially_correctable bad_data value_changed not_used nominal_value interpolated_value missing_value" ; In der Datenvariablen wird auf das *Quality Flag* mittels des Attributs ``ancillary_variable`` hingewiesen. .. card:: Beispiel .. code-block:: float PSAL(TIME, DEPTH) ; PSAL:units = "1e-3" ; PSAL:standard_name = "sea_water_practical_salinity" ; PSAL:_FillValue = -999.f ; PSAL:DM_indicator = "R" ; PSAL:ancillary_variables = "PSAL_QC" ; PSAL:valid_min = 0 ; PSAL:valid_max = 40 ; PSAL:long_name = "Practical salinity" ; PSAL:cell_methods = "TIME:point DEPTH:point LATITUDE:point LONGITUDE:point" ; byte PSAL_QC(TIME, DEPTH) ; PSAL_QC:flag_values = "0, 1, 2, 3, 4, 5, 7, 8, 9" ; PSAL_QC:flag_meanings = "no_qc_performed good_data probably_good_data bad_data_that_are_potentially_correctable bad_data value_changed not_used nominal_value interpolated_value missing_value" ; PSAL_QC:_FillValue = -128b ; PSAL_QC:long_name = "quality flag" ; PSAL_QC:conventions = "OceanSITES reference table 2" ; PSAL_QC:valid_min = 0b ; PSAL_QC:valid_max = 9b ; byte current_speed_qc(time, depth, lat, lon) ; current_speed_qc:long_name = "Current Speed Quality" ; current_speed_qc:standard_name = "status_flag" ; current_speed_qc:_FillValue = -128b ; current_speed_qc:valid_range = 0b, 2b ; current_speed_qc:flag_values = 0b, 1b, 2b ; current_speed_qc:flag_meanings = "quality_good sensor_nonfunctional outside_valid_range" ; .. [14] http://www.oceansites.org/docs/oceansites_data_format_reference_manual.pdf .. [15] http://cfconventions.org/cf-conventions/cf-conventions.html#flags