OpenDrift / opendrift

Open source framework for ocean trajectory modelling
https://opendrift.github.io
GNU General Public License v2.0
232 stars 113 forks source link

Reading NEMO data #550

Open ocgabs opened 3 years ago

ocgabs commented 3 years ago

I am using the reader_netCDF_CF_generic to read in NEMO data, it seems to work, but it doesn't get the projection. Is there a specific syntax to provide the projection? I couldn't find anything about it in the tutorial. Maybe there is a specific reader for NEMO being developed? Thanks a lot for your help. .................... No proj string or projection could be derived, using 'fakeproj'. This assumes that the variables are structured and gridded approximately equidistantly on the surface (i.e. in meters). This must be guaranteed by the user. You can get rid of this warning by suppling a valid projection to the reader.

In [2]: print(reader_NEMO) Reader: /projectsa/CME/Caribe_Arch_NEMO/Caribbean_RUN2_1d_20100101_20100331_grid_UV_001.nc Projection: None Coverage: [pixels] xmin: 0.000000 xmax: 543.000000 step: 1 numx: 544 ymin: 0.000000 ymax: 341.000000 step: 1 numy: 342 Corners (lon, lat): ( -1.00, -1.00) (-54.93, 31.60) ( -1.00, -1.00) (-54.92, 4.95) Vertical levels [m]: Not specified Available time range: start: 2009-12-05 12:00:00 end: 2010-03-04 12:00:00 step: 1 day, 0:00:00 90 times (0 missing) Variables: latitude longitude x_sea_water_velocity y_sea_water_velocity

knutfrode commented 3 years ago

Could you please provide the ncdump of this file?

ocgabs commented 3 years ago

Hi, thanks a lot for your quick reply. See ncdump output below.
NEMO uses a c-grid and in this run variables where output by grid. In this file I put together u and v, but the lat, lon, belong to the v-grid... Can OpenDrift take variables from different files? ...............

netcdf Caribbean_RUN2_1d_20100101_20100331_grid_UV_001 { dimensions: depthu = 75 ; axis_nbounds = 2 ; y = 342 ; x = 544 ; time_counter = UNLIMITED ; // (90 currently) depthv = 75 ; variables: float depthu(depthu) ; depthu:name = "depthu" ; depthu:long_name = "Vertical U levels" ; depthu:units = "m" ; depthu:positive = "down" ; depthu:bounds = "depthu_bounds" ; float depthu_bounds(depthu, axis_nbounds) ; depthu_bounds:units = "m" ; float nav_lat(y, x) ; nav_lat:standard_name = "latitude" ; nav_lat:long_name = "Latitude" ; nav_lat:units = "degrees_north" ; float nav_lon(y, x) ; nav_lon:standard_name = "longitude" ; nav_lon:long_name = "Longitude" ; nav_lon:units = "degrees_east" ; double time_centered(time_counter) ; time_centered:standard_name = "time" ; time_centered:long_name = "Time axis" ; time_centered:calendar = "noleap" ; time_centered:units = "seconds since 1900-01-01 00:00:00" ; time_centered:time_origin = "1900-01-01 00:00:00" ; time_centered:bounds = "time_centered_bounds" ; double time_centered_bounds(time_counter, axis_nbounds) ; double time_counter(time_counter) ; time_counter:axis = "T" ; time_counter:standard_name = "time" ; time_counter:long_name = "Time axis" ; time_counter:calendar = "noleap" ; time_counter:units = "seconds since 1900-01-01 00:00:00" ; time_counter:time_origin = "1900-01-01 00:00:00" ; time_counter:bounds = "time_counter_bounds" ; double time_counter_bounds(time_counter, axis_nbounds) ; float uo(time_counter, depthu, y, x) ; uo:standard_name = "sea_water_x_velocity" ; uo:long_name = "ocean current along i-axis" ; uo:units = "m/s" ; uo:online_operation = "average" ; uo:interval_operation = "240 s" ; uo:interval_write = "1 d" ; uo:cell_methods = "time: mean (interval: 240 s)" ; uo:_FillValue = 1.e+20f ; uo:missing_value = 1.e+20f ; uo:coordinates = "time_centered nav_lat nav_lon" ; float depthv(depthv) ; depthv:name = "depthv" ; depthv:long_name = "Vertical V levels" ; depthv:units = "m" ; depthv:positive = "down" ; depthv:bounds = "depthv_bounds" ; float depthv_bounds(depthv, axis_nbounds) ; depthv_bounds:units = "m" ; float vo(time_counter, depthv, y, x) ; vo:standard_name = "sea_water_y_velocity" ; vo:long_name = "ocean current along j-axis" ; vo:units = "m/s" ; vo:online_operation = "average" ; vo:interval_operation = "240 s" ; vo:interval_write = "1 d" ; vo:cell_methods = "time: mean (interval: 240 s)" ; vo:_FillValue = 1.e+20f ; vo:missing_value = 1.e+20f ; vo:coordinates = "time_centered nav_lat nav_lon" ;

// global attributes: :name = "Caribbean_RUN2_1d_20100101_20100331_grid_V" ; :description = "ocean V grid variables" ; :title = "ocean V grid variables" ; :Conventions = "CF-1.6" ; :timeStamp = "2021-Jan-11 18:07:11 GMT" ; :uuid = "66bf4e53-b0c2-4d88-be73-ccfbded54f91" ; :ibegin = 0 ; :ni = 544 ; :jbegin = 0 ; :nj = 86 ; :file_name = "Caribbean_RUN2_1d_20100101_20100331_grid_V.nc" ; :TimeStamp = "12/01/2021 16:45:12 -0000" ; :history = "Thu Feb 18 19:39:31 2021: ncks -v vo ../3DCaribbeanNEMO/CollabVG/Caribbean_RUN2_1d_20100101_20100331_grid_V.nc Caribbean_RUN2_1d_20100101_20100331_grid_UV.nc\n", "Thu Feb 18 18:51:22 2021: ncks -v uo ../3DCaribbeanNEMO/CollabVG/Caribbean_RUN2_1d_20100101_20100331_grid_U.nc Caribbean_RUN2_1d_20100101_20100331_grid_UV.nc" ; :NCO = "\"4.5.5\"" ;

knutfrode commented 3 years ago

The structure seems ok, but perhaps there is something wrong with your lon- and lat- arrays, since the coverage is reported as:

Corners (lon, lat):
( -1.00, -1.00) (-54.93, 31.60)
( -1.00, -1.00) (-54.92, 4.95)

Can you check/plot the lon/lat arrays? The "eastern" of these coordinates seems perhaps meaningful, but the (-1, -1) values must be wrong.

ocgabs commented 3 years ago

You are right, the fill in value for the masked land is -1 for both lat and lon. Is it possible for OpenDrift to get different variables from different files? image

knutfrode commented 3 years ago

Since there are no x- and y-coordinates in your file (only x- and y-dimensions), and no projection information, OpenDrift needs to use 2D arrays of lon/lat for the geolocalization. And then these have to have full coverage, without mask. However, there is a slight chance that interpolation may anyway work well over the ocean area, so you could try to do a simulation with this reader.

Btw, your plot of latitude shows horizontally aligned values, indicating that the projection here is lon/lat. This means that lon/lat-arrays could (should) have been 1D arrays in this case.

Yes, OpenDrift may obtain different variables from different files - you can simply create and add several readers. However, vectors (wind, current) from datasets which are not east/north-oriented (lonlat or mercator projection) will not be rotated correctly if components are in separate files. This is however normally not a problem.

IGanch commented 2 years ago

Hi Knut and team, I am also using CMEMS as forcing data for the currents (thus from the NEMO model) and I'm having the same problem, which I can't resolve. When I add the files for the u and v components of the current velocity, I use the standard_name_mapping option to give information to the reader about which variable is which. I also give the 'nav_lon':'longitude' and 'nav_lat':'latitude', which is the variable notation for lon and lat, however the model still doesn't read the file correctly. The readerinfo.py gives me:

12:53:23 WARNING opendrift.readers.basereader.structured: No proj string or projection could be derived, using 'fakeproj'. This assumes that the variables are structured and gridded approximately equidistantly on the surface (i.e. in meters). This must be guaranteed by the user. You can get rid of this warning by suppling a valid projection to the reader. 12:53:23 INFO opendrift.readers.basereader.structured: Making interpolator for lon,lat to x,y conversion...

Reader: \OpenDrift_new_simulations\new_currents07072018\ASIS1_1h_20180707_20180707_grid_U.nc Projection: None Coverage: [pixels] xmin: 0.000000 xmax: 590.000000 step: 1 numx: 591 ymin: 0.000000 ymax: 260.000000 step: 1 numy: 261 Corners (lon, lat): ( -1.00, -1.00) ( -1.00, -1.00) ( 27.26, 40.50) ( -1.00, -1.00) Vertical levels [m]: Not specified Available time range: start: 2018-07-07 00:30:00 end: 2018-07-07 23:30:00 step: 1:00:00 24 times (0 missing) Variables: cell_area latitude longitude x_sea_water_velocity

and the coverage is obviously wrong, given that corner values: image

How can I resolve this? I assumed assigning values for longitude and latitude is enough, but OpenDrift continues dealing with x and y. Many thanks in advance.