saving gridded data to netCDF

3 views (last 30 days)
Jacquelyn
Jacquelyn on 14 Apr 2025
Commented: Walter Roberson on 14 Apr 2025
I have gridded velocity data (u and v components) for mutliple timesteps saved as a .mat file and need to convert them to .nc. When I save the data using the below code, and then read the saved .nc files into my Python code, the data seemed to have been jumbled somehow (see attached figures). How can I ensure that the data are saved to the netCDF on the correct grid?
function save_to_netcdf(ADT)
% Extract variables
U_all = ADT.u;
V_all = ADT.v;
time_datenum_all = ADT.time; % MATLAB time in datenum format
latitudes = unique(ADT.y3);
longitudes = unique(ADT.x3);
% Define lat/lon
[NbLatitudes, NbLongitudes, numDays] = size(U_all);
GridDepth = 1;
LatLon = 2;
lat_min = min(latitudes(:));
lon_min = min(longitudes(:));
lat_max = max(latitudes(:));
lon_max = max(longitudes(:));
latlon_step = [(lat_max - lat_min) / (NbLatitudes - 1), (lon_max - lon_min) / (NbLongitudes - 1)];
% Define fill values
fill_value_int = int32(2147483647);
fill_value_double = double(1.84467440737096e+19);
fill_value_float = single(1.844674e+19);
for dayIdx = 1:numDays
% Extract daily data
U = U_all(:,:,dayIdx);
V = V_all(:,:,dayIdx);
time_datenum = time_datenum_all(dayIdx);
contourf(U);
% Convert MATLAB datenum to UNIX time (seconds since 1970-01-01)
time_unix = posixtime(datetime(time_datenum, 'ConvertFrom', 'datenum'));
% Format the date as a string for the "date" attribute
date_str = datestr(time_datenum, 'yyyy-mm-dd HH:MM:SS.000000 UTC');
filename = sprintf('ADT_%s.nc', datestr(time_datenum, 'yyyymmdd'));
% Create NetCDF file
ncid = netcdf.create(filename, 'CLOBBER');
netcdf.putAtt(ncid, netcdf.getConstant('NC_GLOBAL'), 'format', 'NETCDF3_CLASSIC');
% Define dimensions
dimLat = netcdf.defDim(ncid, 'NbLatitudes', NbLatitudes);
dimLon = netcdf.defDim(ncid, 'NbLongitudes', NbLongitudes);
dimGridDepth = netcdf.defDim(ncid, 'GridDepth', GridDepth);
dimLatLon = netcdf.defDim(ncid, 'LatLon', LatLon);
% Define variables
varLatLon = netcdf.defVar(ncid, 'LatLon', 'NC_INT', dimLatLon);
netcdf.putAtt(ncid, varLatLon, '_FillValue', fill_value_int);
netcdf.putAtt(ncid, varLatLon, 'long_name', 'No sense but necessary for some automatic tools');
netcdf.putAtt(ncid, varLatLon, 'units', 'count');
varLat = netcdf.defVar(ncid, 'NbLatitudes', 'NC_DOUBLE', dimLat);
netcdf.putAtt(ncid, varLat, '_FillValue', fill_value_double);
netcdf.putAtt(ncid, varLat, 'long_name', 'Latitudes');
netcdf.putAtt(ncid, varLat, 'units', 'degrees_north');
varLon = netcdf.defVar(ncid, 'NbLongitudes', 'NC_DOUBLE', dimLon);
netcdf.putAtt(ncid, varLon, '_FillValue', fill_value_double);
netcdf.putAtt(ncid, varLon, 'long_name', 'Longitudes');
netcdf.putAtt(ncid, varLon, 'units', 'degrees_east');
varLatLonMin = netcdf.defVar(ncid, 'LatLonMin', 'NC_DOUBLE', dimLatLon);
netcdf.putAtt(ncid, varLatLonMin, '_FillValue', fill_value_double);
netcdf.putAtt(ncid, varLatLonMin, 'long_name', 'Latitude/Longitude of south/ouest corner');
netcdf.putAtt(ncid, varLatLonMin, 'units', 'degree');
varLatLonStep = netcdf.defVar(ncid, 'LatLonStep', 'NC_DOUBLE', dimLatLon);
netcdf.putAtt(ncid, varLatLonStep, '_FillValue', fill_value_double);
netcdf.putAtt(ncid, varLatLonStep, 'long_name', 'latitude/longitude steps');
netcdf.putAtt(ncid, varLatLonStep, 'units', 'degree');
varU = netcdf.defVar(ncid, 'Grid_0001', 'NC_FLOAT', [dimLon, dimLat]);
netcdf.putAtt(ncid, varU, '_FillValue', fill_value_float);
netcdf.putAtt(ncid, varU, 'long_name', 'U');
netcdf.putAtt(ncid, varU, 'units', 'cm/s');
netcdf.putAtt(ncid, varU, 'Date_CNES_JD', 21913.0);
netcdf.putAtt(ncid, varU, 'date', date_str);
varV = netcdf.defVar(ncid, 'Grid_0002', 'NC_FLOAT', [dimLon, dimLat]);
netcdf.putAtt(ncid, varV, '_FillValue', fill_value_float);
netcdf.putAtt(ncid, varV, 'long_name', 'V');
netcdf.putAtt(ncid, varV, 'units', 'cm/s');
netcdf.putAtt(ncid, varV, 'Date_CNES_JD', 21913.0);
netcdf.putAtt(ncid, varV, 'date', date_str);
% Global attributes
netcdf.putAtt(ncid, netcdf.getConstant('NC_GLOBAL'), 'FileType', 'GRID_DOTS_MERCATOR');
netcdf.putAtt(ncid, netcdf.getConstant('NC_GLOBAL'), 'OriginalName', filename);
netcdf.putAtt(ncid, netcdf.getConstant('NC_GLOBAL'), 'CreatedBy', 'Generated by MATLAB script, mat2netCDF.m');
netcdf.putAtt(ncid, netcdf.getConstant('NC_GLOBAL'), 'CreatedOn', datestr(now, 'dd-mmm-yyyy HH:MM:SS:000000'));
netcdf.putAtt(ncid, netcdf.getConstant('NC_GLOBAL'), 'title', 'Geostrophic Flow from ADT, 150W');
% End define mode
netcdf.endDef(ncid);
% Write data
netcdf.putVar(ncid, varLatLon, [0 1]);
netcdf.putVar(ncid, varLat, latitudes);
netcdf.putVar(ncid, varLon, longitudes);
netcdf.putVar(ncid, varLatLonMin, [lat_min, lon_min]);
netcdf.putVar(ncid, varLatLonStep, latlon_step);
netcdf.putVar(ncid, varU, U);
netcdf.putVar(ncid, varV, V);
% Close NetCDF file
netcdf.close(ncid);
end
end
  1 Comment
Walter Roberson
Walter Roberson on 14 Apr 2025
I know that .nc files use row-major storage instead of column-major storage. Experiment with transposing all of the 2D arrays that you write.

Sign in to comment.

Answers (0)

Tags

Products


Release

R2019b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!