lutraconsulting / MDAL

Mesh Data Abstraction Library
http://www.mdal.xyz/
MIT License
160 stars 50 forks source link

Allow to read velocities from Copernicus Ocean Currents Forecast Model #193

Closed marceloandrioni closed 4 years ago

marceloandrioni commented 4 years ago

Hello, checking the MDAL code I saw in this section that MDAL recognizes zonal and meridional components of the velocity vector (from wind, current, etc) by checking for some pre-defined strings, e.g.:

"u-component of"
"v-component of"
"U wind component"
"V wind component"
"x-component of"
"y-component of"
...

In the CF Conventions, the main set of "rules" used for NetCDF metocean, this is done a little different. The Standard Name Table uses eastward and northward as u and v components respectively, but this is done in the standard_name attribute and not in the long_name. Reading University's ncWMS also uses this convention to "create" the velocity layer from u and v layers. A few examples from the Standard Name Table:

geostrophic_eastward_wind
geostrophic_northward_wind

eastward_wind
northward_wind

eastward_sea_water_velocity
northward_sea_water_velocity

surface_geostrophic_eastward_sea_water_velocity
surface_geostrophic_northward_sea_water_velocity

My suggestion would be to add this option of representing vector quantities to MDAL to increase the CF Conventions compatibility (so far I have been changing the long_name attribute "by hand" so that MDAL could recognize the variables as vector components). I thought of doing a simple PR to add this extra option to mdal_gdal.cpp, something like:

    band_name = MDAL::replace( band_name, "eastward_", " ", MDAL::CaseInsensitive );
    band_name = MDAL::replace( band_name, "northward_", " ", MDAL::CaseInsensitive );

so that, e.g.:

eastward_wind and northward_wind -> wind
surface_geostrophic_eastward_sea_water_velocity and surface_geostrophic_northward_sea_water_velocity -> surface_geostrophic_sea_water_velocity

but from what I understood the band_name variable represents the long_name attribute and not the standard_name, is that correct? Also, probably some implementation of first checking if the variable has a standard_name attribute and if not, defaulting to long_name attribute would need to be done.

Thank you.

PeterPetrik commented 4 years ago

Hi thanks for pointing this out.

Feel free to create a small PR, but as you said it would be more complicated by fact it is not in the long name. Usually this information is in long name, so to suggest something I would need to see some example

GRIB (gdal) format uses grib_valid_time

NETCDF (gdal) format uses first long_name and netcdf_varname afterwards.

marceloandrioni commented 4 years ago

Hello @PeterPetrik, here is an example from Copernicus Ocean Currents Forecast Model.

You can see in the metadata (ncdump -h) that the standard_name attribute is eastward_sea_water_velocity and northward_sea_water_velocity.

    float vo(time, depth, latitude, longitude) ;
        vo:_FillValue = 1.e+20f ;
        vo:least_significant_digit = 3 ;
        vo:long_name = "Northward Eulerian velocity (Navier-Stokes current)" ;
        vo:standard_name = "northward_sea_water_velocity" ;
        vo:units = "ms-1" ;
        vo:_ChunkSizes = 1, 1, 681, 1440 ;
    float uo(time, depth, latitude, longitude) ;
        uo:_FillValue = 1.e+20f ;
        uo:least_significant_digit = 3 ;
        uo:long_name = "Eastward Eulerian velocity (Navier-Stokes current)" ;
        uo:standard_name = "eastward_sea_water_velocity" ;
        uo:units = "m s-1" ;
        uo:_ChunkSizes = 1, 1, 681, 1440 ;

From your message my sugestion would be to use the order standard_name > long_name > netcdf_varname when trying to combine u and v.

Thank you very much and sorry I could not help more, but my C++ knowledge is basically null.