Commit f33b1a8e authored by Uwe Schulzweida's avatar Uwe Schulzweida
Browse files

NetCDF4: added support for reading complex numbers (status: experimental).

parent fd379659
2020-04-21 Uwe Schulzweida
* NetCDF4: added support for reading complex numbers (status: experimental)
2020-04-20 Uwe Schulzweida 2020-04-20 Uwe Schulzweida
* NetCDF4: added support for writting complex numbers (status: experimental) * NetCDF4: added support for writting complex numbers (status: experimental)
......
...@@ -465,6 +465,17 @@ void cdf_put_vara(int ncid, int varid, const size_t start[], const size_t count[ ...@@ -465,6 +465,17 @@ void cdf_put_vara(int ncid, int varid, const size_t start[], const size_t count[
} }
void cdf_get_vara(int ncid, int varid, const size_t start[], const size_t count[], void *cp)
{
int status = nc_get_vara(ncid, varid, start, count, cp);
if ( CDF_Debug || status != NC_NOERR )
Message("ncid = %d varid = %d", ncid, varid);
if ( status != NC_NOERR ) Error("%s", nc_strerror(status));
}
void cdf_get_vara_int(int ncid, int varid, const size_t start[], const size_t count[], int *dp) void cdf_get_vara_int(int ncid, int varid, const size_t start[], const size_t count[], int *dp)
{ {
int status = nc_get_vara_int(ncid, varid, start, count, dp); int status = nc_get_vara_int(ncid, varid, start, count, dp);
......
...@@ -67,6 +67,7 @@ void cdf_put_vara_float(int ncid, int varid, const size_t start[], const size_t ...@@ -67,6 +67,7 @@ void cdf_put_vara_float(int ncid, int varid, const size_t start[], const size_t
void cdf_get_vara_int(int ncid, int varid, const size_t start[], const size_t count[], int *dp); void cdf_get_vara_int(int ncid, int varid, const size_t start[], const size_t count[], int *dp);
void cdf_get_vara(int ncid, int varid, const size_t start[], const size_t count[], void *cp);
void cdf_put_vara(int ncid, int varid, const size_t start[], const size_t count[], const void *cp); void cdf_put_vara(int ncid, int varid, const size_t start[], const size_t count[], const void *cp);
void cdf_put_att_text(int ncid, int varid, const char *name, size_t len, const char *tp); void cdf_put_att_text(int ncid, int varid, const char *name, size_t len, const char *tp);
......
...@@ -571,16 +571,32 @@ void cdfReadDataDP(stream_t *streamptr, int varID, size_t length, size_t start[4 ...@@ -571,16 +571,32 @@ void cdfReadDataDP(stream_t *streamptr, int varID, size_t length, size_t start[4
const int vlistID = streamptr->vlistID; const int vlistID = streamptr->vlistID;
const int fileID = streamptr->fileID; const int fileID = streamptr->fileID;
const int ncvarid = streamptr->vars[varID].ncvarid; const int ncvarid = streamptr->vars[varID].ncvarid;
const int datatype = vlistInqVarDatatype(vlistID, varID);
if ( vlistInqVarDatatype(vlistID, varID) == CDI_DATATYPE_FLT32 ) if (datatype == CDI_DATATYPE_CPX32 || datatype == CDI_DATATYPE_CPX64)
{ {
cdfReadDataSliceSP2DP(fileID, ncvarid, length, start, count, data); cdf_get_vara(fileID, ncvarid, start, count, data);
if (datatype == CDI_DATATYPE_CPX32)
{
for (long i = (long)length-1; i >= 0; i--)
{
data[2*i] = (double)(((float*)data)[2*i]);
data[2*i+1] = (double)(((float*)data)[2*i+1]);
}
}
} }
else else
{ {
cdf_get_vara_double(fileID, ncvarid, start, count, data); if ( datatype == CDI_DATATYPE_FLT32 )
{
cdfReadDataSliceSP2DP(fileID, ncvarid, length, start, count, data);
}
else
{
cdf_get_vara_double(fileID, ncvarid, start, count, data);
cdfCheckDataDP_UINT8(fileID, ncvarid, vlistID, varID, length, data); cdfCheckDataDP_UINT8(fileID, ncvarid, vlistID, varID, length, data);
}
} }
} }
...@@ -590,16 +606,38 @@ void cdfReadDataSP(stream_t *streamptr, int varID, size_t length, size_t start[4 ...@@ -590,16 +606,38 @@ void cdfReadDataSP(stream_t *streamptr, int varID, size_t length, size_t start[4
const int vlistID = streamptr->vlistID; const int vlistID = streamptr->vlistID;
const int fileID = streamptr->fileID; const int fileID = streamptr->fileID;
const int ncvarid = streamptr->vars[varID].ncvarid; const int ncvarid = streamptr->vars[varID].ncvarid;
const int datatype = vlistInqVarDatatype(vlistID, varID);
if ( vlistInqVarDatatype(vlistID, varID) == CDI_DATATYPE_FLT64 ) if (datatype == CDI_DATATYPE_CPX32 || datatype == CDI_DATATYPE_CPX64)
{ {
cdfReadDataSliceDP2SP(fileID, ncvarid, length, start, count, data); if (datatype == CDI_DATATYPE_CPX64)
{
double *cdata = (double *) Malloc(2*length*sizeof(double));
cdf_get_vara(fileID, ncvarid, start, count, cdata);
for (size_t i = 0; i < length; i++)
{
data[2*i] = (float)(cdata[2*i]);
data[2*i+1] = (float)(cdata[2*i+1]);
}
Free(cdata);
}
else
{
cdf_get_vara(fileID, ncvarid, start, count, data);
}
} }
else else
{ {
cdf_get_vara_float(fileID, ncvarid, start, count, data); if ( datatype == CDI_DATATYPE_FLT64 )
{
cdfReadDataSliceDP2SP(fileID, ncvarid, length, start, count, data);
}
else
{
cdf_get_vara_float(fileID, ncvarid, start, count, data);
cdfCheckDataSP_UINT8(fileID, ncvarid, vlistID, varID, length, data); cdfCheckDataSP_UINT8(fileID, ncvarid, vlistID, varID, length, data);
}
} }
} }
......
...@@ -274,7 +274,7 @@ bool xtypeIsInt(nc_type xtype) ...@@ -274,7 +274,7 @@ bool xtypeIsInt(nc_type xtype)
} }
static static
int cdfInqDatatype(int xtype, bool lunsigned) int cdfInqDatatype(stream_t *streamptr, int xtype, bool lunsigned)
{ {
int datatype = -1; int datatype = -1;
...@@ -295,6 +295,36 @@ int cdfInqDatatype(int xtype, bool lunsigned) ...@@ -295,6 +295,36 @@ int cdfInqDatatype(int xtype, bool lunsigned)
else if ( xtype == NC_UINT ) datatype = CDI_DATATYPE_UINT32; else if ( xtype == NC_UINT ) datatype = CDI_DATATYPE_UINT32;
else if ( xtype == NC_INT64 ) datatype = CDI_DATATYPE_FLT64; else if ( xtype == NC_INT64 ) datatype = CDI_DATATYPE_FLT64;
else if ( xtype == NC_UINT64 ) datatype = CDI_DATATYPE_FLT64; else if ( xtype == NC_UINT64 ) datatype = CDI_DATATYPE_FLT64;
else
{
if (xtype != streamptr->nc_complex_float_id && xtype != streamptr->nc_complex_double_id)
{
int isUserDefinedType = false;
#ifdef NC_FIRSTUSERTYPEID
isUserDefinedType = xtype >= NC_FIRSTUSERTYPEID;
#endif
if (isUserDefinedType)
{
int fileID = streamptr->fileID;
size_t nfields = 0, compoundsize = 0;
int status = nc_inq_compound(fileID, xtype, NULL, &compoundsize, &nfields);
if (status == NC_NOERR && nfields == 2 && (compoundsize == 8 || compoundsize == 16))
{
nc_type field_type1 = -1, field_type2 = -1;
int field_dims1 = 0, field_dims2 = 0;
nc_inq_compound_field(fileID, xtype, 0, NULL, NULL, &field_type1, &field_dims1, NULL);
nc_inq_compound_field(fileID, xtype, 1, NULL, NULL, &field_type2, &field_dims2, NULL);
if (field_type1 == field_type2 && field_dims1 == 0 && field_dims2 == 0)
{
if (field_type1 == NC_FLOAT) streamptr->nc_complex_float_id = xtype;
else if (field_type1 == NC_DOUBLE) streamptr->nc_complex_double_id = xtype;
}
}
}
}
if ( xtype == streamptr->nc_complex_float_id ) datatype = CDI_DATATYPE_CPX32;
else if ( xtype == streamptr->nc_complex_double_id ) datatype = CDI_DATATYPE_CPX64;
}
#endif #endif
return datatype; return datatype;
...@@ -1889,7 +1919,7 @@ void verify_coordinate_vars_1(int ncid, int ndims, ncdim_t *ncdims, ncvar_t *ncv ...@@ -1889,7 +1919,7 @@ void verify_coordinate_vars_1(int ncid, int ndims, ncdim_t *ncdims, ncvar_t *ncv
/* verify coordinate vars - second scan (all other variables) */ /* verify coordinate vars - second scan (all other variables) */
static static
void verify_coordinate_vars_2(int nvars, ncvar_t *ncvars) void verify_coordinate_vars_2(stream_t *streamptr, int nvars, ncvar_t *ncvars)
{ {
for ( int ncvarid = 0; ncvarid < nvars; ncvarid++ ) for ( int ncvarid = 0; ncvarid < nvars; ncvarid++ )
{ {
...@@ -1953,7 +1983,7 @@ void verify_coordinate_vars_2(int nvars, ncvar_t *ncvars) ...@@ -1953,7 +1983,7 @@ void verify_coordinate_vars_2(int nvars, ncvar_t *ncvars)
} }
else if ( strcmp(ncvars[ncvarid].stdname, "region") == 0 || else if ( strcmp(ncvars[ncvarid].stdname, "region") == 0 ||
strcmp(ncvars[ncvarid].stdname, "area_type") == 0 || strcmp(ncvars[ncvarid].stdname, "area_type") == 0 ||
cdfInqDatatype(ncvars[ncvarid].xtype, ncvars[ncvarid].lunsigned) == CDI_DATATYPE_UINT8 ) cdfInqDatatype(streamptr, ncvars[ncvarid].xtype, ncvars[ncvarid].lunsigned) == CDI_DATATYPE_UINT8 )
{ {
ncvars[ncvarid].isc = true; ncvars[ncvarid].isc = true;
} }
...@@ -2170,7 +2200,7 @@ void cdf_check_gridtype(int *gridtype, bool islon, bool islat, size_t xsize, siz ...@@ -2170,7 +2200,7 @@ void cdf_check_gridtype(int *gridtype, bool islon, bool islat, size_t xsize, siz
} }
static static
bool cdf_read_xcoord(struct cdfLazyGrid *restrict lazyGrid, ncdim_t *ncdims, ncvar_t *ncvar, int xvarid, ncvar_t *axisvar, bool cdf_read_xcoord(stream_t *streamptr, struct cdfLazyGrid *restrict lazyGrid, ncdim_t *ncdims, ncvar_t *ncvar, int xvarid, ncvar_t *axisvar,
size_t *xsize, size_t ysize, int ntdims, size_t *start, size_t *count, bool *islon) size_t *xsize, size_t ysize, int ntdims, size_t *start, size_t *count, bool *islon)
{ {
grid_t *grid = &lazyGrid->base; grid_t *grid = &lazyGrid->base;
...@@ -2178,7 +2208,7 @@ bool cdf_read_xcoord(struct cdfLazyGrid *restrict lazyGrid, ncdim_t *ncdims, ncv ...@@ -2178,7 +2208,7 @@ bool cdf_read_xcoord(struct cdfLazyGrid *restrict lazyGrid, ncdim_t *ncdims, ncv
*islon = axisvar->islon; *islon = axisvar->islon;
int ndims = axisvar->ndims; int ndims = axisvar->ndims;
size_t size = 0; size_t size = 0;
const int datatype = cdfInqDatatype(axisvar->xtype, axisvar->lunsigned); const int datatype = cdfInqDatatype(streamptr, axisvar->xtype, axisvar->lunsigned);
if ( (ndims - ntdims) == 2 ) if ( (ndims - ntdims) == 2 )
{ {
...@@ -2240,7 +2270,7 @@ bool cdf_read_xcoord(struct cdfLazyGrid *restrict lazyGrid, ncdim_t *ncdims, ncv ...@@ -2240,7 +2270,7 @@ bool cdf_read_xcoord(struct cdfLazyGrid *restrict lazyGrid, ncdim_t *ncdims, ncv
} }
static static
bool cdf_read_ycoord(struct cdfLazyGrid *restrict lazyGrid, ncdim_t *ncdims, ncvar_t *ncvar, int yvarid, ncvar_t *axisvar, bool cdf_read_ycoord(stream_t *streamptr, struct cdfLazyGrid *restrict lazyGrid, ncdim_t *ncdims, ncvar_t *ncvar, int yvarid, ncvar_t *axisvar,
size_t xsize, size_t *ysize, int ntdims, size_t *start, size_t *count, bool *islat) size_t xsize, size_t *ysize, int ntdims, size_t *start, size_t *count, bool *islat)
{ {
grid_t *grid = &lazyGrid->base; grid_t *grid = &lazyGrid->base;
...@@ -2248,7 +2278,7 @@ bool cdf_read_ycoord(struct cdfLazyGrid *restrict lazyGrid, ncdim_t *ncdims, ncv ...@@ -2248,7 +2278,7 @@ bool cdf_read_ycoord(struct cdfLazyGrid *restrict lazyGrid, ncdim_t *ncdims, ncv
*islat = axisvar->islat; *islat = axisvar->islat;
int ndims = axisvar->ndims; int ndims = axisvar->ndims;
size_t size = 0; size_t size = 0;
const int datatype = cdfInqDatatype(axisvar->xtype, axisvar->lunsigned); const int datatype = cdfInqDatatype(streamptr, axisvar->xtype, axisvar->lunsigned);
if ( (ndims - ntdims) == 2 ) if ( (ndims - ntdims) == 2 )
{ {
...@@ -2311,7 +2341,7 @@ bool cdf_read_ycoord(struct cdfLazyGrid *restrict lazyGrid, ncdim_t *ncdims, ncv ...@@ -2311,7 +2341,7 @@ bool cdf_read_ycoord(struct cdfLazyGrid *restrict lazyGrid, ncdim_t *ncdims, ncv
} }
static static
bool cdf_read_coordinates(struct cdfLazyGrid *restrict lazyGrid, ncvar_t *ncvar, ncvar_t *ncvars, ncdim_t *ncdims, bool cdf_read_coordinates(stream_t *streamptr, struct cdfLazyGrid *restrict lazyGrid, ncvar_t *ncvar, ncvar_t *ncvars, ncdim_t *ncdims,
int timedimid, int xvarid, int yvarid, size_t xsize, size_t ysize, int *vdimid) int timedimid, int xvarid, int yvarid, size_t xsize, size_t ysize, int *vdimid)
{ {
grid_t *grid = &lazyGrid->base; grid_t *grid = &lazyGrid->base;
...@@ -2386,12 +2416,12 @@ bool cdf_read_coordinates(struct cdfLazyGrid *restrict lazyGrid, ncvar_t *ncvar, ...@@ -2386,12 +2416,12 @@ bool cdf_read_coordinates(struct cdfLazyGrid *restrict lazyGrid, ncvar_t *ncvar,
bool islon = false, islat = false; bool islon = false, islat = false;
if ( xvarid != CDI_UNDEFID ) if ( xvarid != CDI_UNDEFID )
if ( cdf_read_xcoord(lazyGrid, ncdims, ncvar, xvarid, &ncvars[xvarid], if ( cdf_read_xcoord(streamptr, lazyGrid, ncdims, ncvar, xvarid, &ncvars[xvarid],
&xsize, ysize, ntdims, start, count, &islon) ) &xsize, ysize, ntdims, start, count, &islon) )
return true; return true;
if ( yvarid != CDI_UNDEFID ) if ( yvarid != CDI_UNDEFID )
if ( cdf_read_ycoord(lazyGrid, ncdims, ncvar, yvarid, &ncvars[yvarid], if ( cdf_read_ycoord(streamptr, lazyGrid, ncdims, ncvar, yvarid, &ncvars[yvarid],
xsize, &ysize, ntdims, start, count, &islat) ) xsize, &ysize, ntdims, start, count, &islat) )
return true; return true;
...@@ -2695,7 +2725,7 @@ void cdf_set_grid_to_similar_vars(ncvar_t *ncvar1, ncvar_t *ncvar2, int gridtype ...@@ -2695,7 +2725,7 @@ void cdf_set_grid_to_similar_vars(ncvar_t *ncvar1, ncvar_t *ncvar2, int gridtype
} }
static static
int cdf_define_all_grids(ncgrid_t *ncgrid, int vlistID, ncdim_t *ncdims, int nvars, ncvar_t *ncvars, int cdf_define_all_grids(stream_t *streamptr, ncgrid_t *ncgrid, int vlistID, ncdim_t *ncdims, int nvars, ncvar_t *ncvars,
int timedimid, unsigned char *uuidOfHGrid, char *gridfile, int number_of_grid_used) int timedimid, unsigned char *uuidOfHGrid, char *gridfile, int number_of_grid_used)
{ {
for ( int ncvarid = 0; ncvarid < nvars; ++ncvarid ) for ( int ncvarid = 0; ncvarid < nvars; ++ncvarid )
...@@ -2763,7 +2793,7 @@ int cdf_define_all_grids(ncgrid_t *ncgrid, int vlistID, ncdim_t *ncdims, int nva ...@@ -2763,7 +2793,7 @@ int cdf_define_all_grids(ncgrid_t *ncgrid, int vlistID, ncdim_t *ncdims, int nva
xaxisid = (xdimid != CDI_UNDEFID) ? ncdims[xdimid].ncvarid : CDI_UNDEFID; xaxisid = (xdimid != CDI_UNDEFID) ? ncdims[xdimid].ncvarid : CDI_UNDEFID;
yaxisid = (ydimid != CDI_UNDEFID) ? ncdims[ydimid].ncvarid : CDI_UNDEFID; yaxisid = (ydimid != CDI_UNDEFID) ? ncdims[ydimid].ncvarid : CDI_UNDEFID;
if ( cdf_read_coordinates(lazyGrid, ncvar, ncvars, ncdims, if ( cdf_read_coordinates(streamptr, lazyGrid, ncvar, ncvars, ncdims,
timedimid, xvarid, yvarid, xsize, ysize, &vdimid) ) timedimid, xvarid, yvarid, xsize, ysize, &vdimid) )
continue; continue;
...@@ -2779,7 +2809,7 @@ int cdf_define_all_grids(ncgrid_t *ncgrid, int vlistID, ncdim_t *ncdims, int nva ...@@ -2779,7 +2809,7 @@ int cdf_define_all_grids(ncgrid_t *ncgrid, int vlistID, ncdim_t *ncdims, int nva
if ( lproj && lgrid ) if ( lproj && lgrid )
{ {
int dimid; int dimid;
cdf_read_coordinates(lazyProj, ncvar, ncvars, ncdims, timedimid, cdf_read_coordinates(streamptr, lazyProj, ncvar, ncvars, ncdims, timedimid,
xaxisid, yaxisid, xsize, ysize, &dimid); xaxisid, yaxisid, xsize, ysize, &dimid);
} }
...@@ -3270,7 +3300,7 @@ void cdf_define_all_vars(stream_t *streamptr, int vlistID, int instID, int model ...@@ -3270,7 +3300,7 @@ void cdf_define_all_vars(stream_t *streamptr, int vlistID, int instID, int model
if ( IS_NOT_EQUAL(ncvars[ncvarid].scalefactor, 1) ) if ( IS_NOT_EQUAL(ncvars[ncvarid].scalefactor, 1) )
vlistDefVarScalefactor(vlistID, varID, ncvars[ncvarid].scalefactor); vlistDefVarScalefactor(vlistID, varID, ncvars[ncvarid].scalefactor);
vlistDefVarDatatype(vlistID, varID, cdfInqDatatype(ncvars[ncvarid].xtype, ncvars[ncvarid].lunsigned)); vlistDefVarDatatype(vlistID, varID, cdfInqDatatype(streamptr, ncvars[ncvarid].xtype, ncvars[ncvarid].lunsigned));
vlistDefVarInstitut(vlistID, varID, instID); vlistDefVarInstitut(vlistID, varID, instID);
vlistDefVarModel(vlistID, varID, modelID); vlistDefVarModel(vlistID, varID, modelID);
...@@ -3695,7 +3725,7 @@ void cdf_set_ucla_dimtype(int ndims, ncdim_t *ncdims, ncvar_t *ncvars) ...@@ -3695,7 +3725,7 @@ void cdf_set_ucla_dimtype(int ndims, ncdim_t *ncdims, ncvar_t *ncvars)
} }
static static
int cdfCheckVars(int nvars, ncvar_t *ncvars, size_t ntsteps, int timedimid) int cdfCheckVars(stream_t *streamptr, int nvars, ncvar_t *ncvars, size_t ntsteps, int timedimid)
{ {
for ( int ncvarid = 0; ncvarid < nvars; ncvarid++ ) for ( int ncvarid = 0; ncvarid < nvars; ncvarid++ )
{ {
...@@ -3749,7 +3779,7 @@ int cdfCheckVars(int nvars, ncvar_t *ncvars, size_t ntsteps, int timedimid) ...@@ -3749,7 +3779,7 @@ int cdfCheckVars(int nvars, ncvar_t *ncvars, size_t ntsteps, int timedimid)
continue; continue;
} }
if ( cdfInqDatatype(ncvars[ncvarid].xtype, ncvars[ncvarid].lunsigned) == -1 ) if ( cdfInqDatatype(streamptr, ncvars[ncvarid].xtype, ncvars[ncvarid].lunsigned) == -1 )
{ {
ncvars[ncvarid].isvar = 0; ncvars[ncvarid].isvar = 0;
Warning("Unsupported data type, skipped variable %s!", ncvars[ncvarid].name); Warning("Unsupported data type, skipped variable %s!", ncvars[ncvarid].name);
...@@ -3980,14 +4010,14 @@ int cdfInqContents(stream_t *streamptr) ...@@ -3980,14 +4010,14 @@ int cdfInqContents(stream_t *streamptr)
if ( leadtime_id != CDI_UNDEFID ) ncvars[leadtime_id].isvar = FALSE; if ( leadtime_id != CDI_UNDEFID ) ncvars[leadtime_id].isvar = FALSE;
// check ncvars // check ncvars
timedimid = cdfCheckVars(nvars, ncvars, ntsteps, timedimid); timedimid = cdfCheckVars(streamptr, nvars, ncvars, ntsteps, timedimid);
// verify coordinate vars - first scan (dimname == varname) // verify coordinate vars - first scan (dimname == varname)
bool lhybrid_cf = false; bool lhybrid_cf = false;
verify_coordinate_vars_1(fileID, ndims, ncdims, ncvars, timedimid, &lhybrid_cf); verify_coordinate_vars_1(fileID, ndims, ncdims, ncvars, timedimid, &lhybrid_cf);
// verify coordinate vars - second scan (all other variables) // verify coordinate vars - second scan (all other variables)
verify_coordinate_vars_2(nvars, ncvars); verify_coordinate_vars_2(streamptr, nvars, ncvars);
if ( CDI_Debug ) cdf_print_vars(ncvars, nvars, "verify_coordinate_vars"); if ( CDI_Debug ) cdf_print_vars(ncvars, nvars, "verify_coordinate_vars");
...@@ -4058,7 +4088,7 @@ int cdfInqContents(stream_t *streamptr) ...@@ -4058,7 +4088,7 @@ int cdfInqContents(stream_t *streamptr)
// define all grids // define all grids
int status; int status;
status = cdf_define_all_grids(streamptr->ncgrid, vlistID, ncdims, nvars, ncvars, timedimid, uuidOfHGrid, gridfile, number_of_grid_used); status = cdf_define_all_grids(streamptr, streamptr->ncgrid, vlistID, ncdims, nvars, ncvars, timedimid, uuidOfHGrid, gridfile, number_of_grid_used);
if ( status < 0 ) return status; if ( status < 0 ) return status;
// define all zaxes // define all zaxes
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment