Commit 5180bb0d authored by Uwe Schulzweida's avatar Uwe Schulzweida
Browse files

added single precision support: streamWriteVarFloat, streamWriteVarSliceFloat

parent 4f67a78e
......@@ -3,6 +3,10 @@
* Version 1.5.5 released
* using CGRIBEX library version 1.5.2
2012-03-24 Uwe Schulzweida <Uwe.Schulzweida@zmaw.de>
* added single precision support: streamWriteVarFloat, streamWriteVarSliceFloat
2012-02-15 Uwe Schulzweida <Uwe.Schulzweida@zmaw.de>
* stream_cdf::cdfDefDatatype: bug fix for DATATYPE_UINT8
......
CDI NEWS
--------
Version 1.5.5 (?? May 2012):
New features:
* added single precision support: streamWriteVarFloat, streamWriteVarSliceFloat
Version 1.5.4 (30 January 2012):
New features:
......
......@@ -985,7 +985,7 @@ int main(int argc, char *argv[])
if ( Move )
streamCopyRecord(streamID2, streamID1);
else
streamWriteRecord(streamID2, data, nmiss);
streamWriteRecordDouble(streamID2, data, nmiss);
}
}
}
......
......@@ -446,8 +446,8 @@ void cdf_put_var_float(int ncid, int varid, const float *fp)
}
void cdf_put_vara_double (int ncid, int varid, const size_t start[],
const size_t count[], const double *dp)
void cdf_put_vara_double(int ncid, int varid, const size_t start[],
const size_t count[], const double *dp)
{
int status;
......@@ -461,8 +461,23 @@ void cdf_put_vara_double (int ncid, int varid, const size_t start[],
}
void cdf_get_vara_int (int ncid, int varid, const size_t start[],
const size_t count[], int *dp)
void cdf_put_vara_float(int ncid, int varid, const size_t start[],
const size_t count[], const float *fp)
{
int status;
status = nc_put_vara_float(ncid, varid, start, count, fp);
if ( CDF_Debug || status != NC_NOERR )
Message("ncid = %d varid = %d val0 = %f", ncid, varid, *fp);
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)
{
int status;
......@@ -476,8 +491,8 @@ void cdf_get_vara_int (int ncid, int varid, const size_t start[],
}
void cdf_get_vara_double (int ncid, int varid, const size_t start[],
const size_t count[], double *dp)
void cdf_get_vara_double(int ncid, int varid, const size_t start[],
const size_t count[], double *dp)
{
int status;
......@@ -491,6 +506,21 @@ void cdf_get_vara_double (int ncid, int varid, const size_t start[],
}
void cdf_get_vara_float(int ncid, int varid, const size_t start[],
const size_t count[], float *fp)
{
int status;
status = nc_get_vara_float(ncid, varid, start, count, fp);
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_text(int ncid, int varid, const size_t start[],
const size_t count[], char *tp)
{
......
......@@ -64,6 +64,11 @@ void cdf_get_vara_double(int ncid, int varid, const size_t start[],
void cdf_put_vara_double(int ncid, int varid, const size_t start[],
const size_t count[], const double *dp);
void cdf_get_vara_float(int ncid, int varid, const size_t start[],
const size_t count[], float *fp);
void cdf_put_vara_float(int ncid, int varid, const size_t start[],
const size_t count[], const float *fp);
void cdf_put_att_text (int ncid, int varid, const char *name, size_t len,
const char *tp);
void cdf_put_att_int (int ncid, int varid, const char *name, nc_type xtype,
......
......@@ -291,12 +291,16 @@ void streamReadVar(int streamID, int varID, double *data_vec, int *nmiss);
/* streamWriteVar: Write a variable */
void streamWriteVar(int streamID, int varID, const double *data_vec, int nmiss);
void streamWriteVarDouble(int streamID, int varID, const double *data_vec, int nmiss);
void streamWriteVarFloat(int streamID, int varID, const float *data_vec, int nmiss);
/* streamReadVarSlice: Read a horizontal slice of a variable */
void streamReadVarSlice(int streamID, int varID, int levelID, double *data_vec, int *nmiss);
/* streamWriteVarSlice: Write a horizontal slice of a variable */
void streamWriteVarSlice(int streamID, int varID, int levelID, const double *data_vec, int nmiss);
void streamWriteVarSliceDouble(int streamID, int varID, int levelID, const double *data_vec, int nmiss);
void streamWriteVarSliceFloat(int streamID, int varID, int levelID, const float *data_vec, int nmiss);
/* STREAM record I/O routines */
......@@ -305,6 +309,8 @@ void streamInqRecord(int streamID, int *varID, int *levelID);
void streamDefRecord(int streamID, int varID, int levelID);
void streamReadRecord(int streamID, double *data_vec, int *nmiss);
void streamWriteRecord(int streamID, const double *data_vec, int nmiss);
void streamWriteRecordDouble(int streamID, const double *data_vec, int nmiss);
void streamWriteRecordFloat(int streamID, const float *data_vec, int nmiss);
void streamCopyRecord(int streamIDdest, int streamIDsrc);
void streamInqGinfo(int streamID, int *intnum, float *fltnum);
......
......@@ -1532,23 +1532,8 @@ void streamReadVar(int streamID, int varID, double *data, int *nmiss)
}
}
/*
@Function streamWriteVar
@Title Write a variable
@Prototype void streamWriteVar(int streamID, int varID, const double *data, int nmiss)
@Parameter
@Item streamID Stream ID, from a previous call to @fref{streamOpenRead} or @fref{streamOpenWrite}.
@Item varID Variable identifier.
@Item data Pointer to a block of data values to be written.
@Item nmiss Number of missing values.
@Description
The function streamWriteVar writes the values of one time step of a variable
to an open dataset.
@EndFunction
*/
void streamWriteVar(int streamID, int varID, const double *data, int nmiss)
void stream_write_var(int streamID, int varID, int memtype, const void *data, int nmiss)
{
int filetype;
stream_t *streamptr;
......@@ -1571,6 +1556,7 @@ void streamWriteVar(int streamID, int varID, const double *data, int nmiss)
case FILETYPE_GRB:
case FILETYPE_GRB2:
{
if ( memtype == MEMTYPE_FLOAT ) Error("grbWriteVar not implemented for memtype float!");
grbWriteVarDP(streamID, varID, data, nmiss);
break;
}
......@@ -1578,6 +1564,7 @@ void streamWriteVar(int streamID, int varID, const double *data, int nmiss)
#if defined (HAVE_LIBSERVICE)
case FILETYPE_SRV:
{
if ( memtype == MEMTYPE_FLOAT ) Error("srvWriteVar not implemented for memtype float!");
srvWriteVarDP(streamID, varID, data);
break;
}
......@@ -1585,6 +1572,7 @@ void streamWriteVar(int streamID, int varID, const double *data, int nmiss)
#if defined (HAVE_LIBEXTRA)
case FILETYPE_EXT:
{
if ( memtype == MEMTYPE_FLOAT ) Error("extWriteVar not implemented for memtype float!");
extWriteVarDP(streamID, varID, data);
break;
}
......@@ -1592,6 +1580,7 @@ void streamWriteVar(int streamID, int varID, const double *data, int nmiss)
#if defined (HAVE_LIBIEG)
case FILETYPE_IEG:
{
if ( memtype == MEMTYPE_FLOAT ) Error("iegWriteVar not implemented for memtype float!");
iegWriteVarDP(streamID, varID, data);
break;
}
......@@ -1603,7 +1592,7 @@ void streamWriteVar(int streamID, int varID, const double *data, int nmiss)
case FILETYPE_NC4C:
{
if ( streamptr->accessmode == 0 ) cdfEndDef(streamID);
cdfWriteVarDP(streamID, varID, data, nmiss);
cdf_write_var(streamID, varID, memtype, data, nmiss);
break;
}
#endif
......@@ -1615,6 +1604,36 @@ void streamWriteVar(int streamID, int varID, const double *data, int nmiss)
}
}
/*
@Function streamWriteVar
@Title Write a variable
@Prototype void streamWriteVar(int streamID, int varID, const double *data, int nmiss)
@Parameter
@Item streamID Stream ID, from a previous call to @fref{streamOpenRead} or @fref{streamOpenWrite}.
@Item varID Variable identifier.
@Item data Pointer to a block of data values to be written.
@Item nmiss Number of missing values.
@Description
The function streamWriteVar writes the values of one time step of a variable to an open dataset.
@EndFunction
*/
void streamWriteVar(int streamID, int varID, const double *data, int nmiss)
{
stream_write_var(streamID, varID, MEMTYPE_DOUBLE, data, nmiss);
}
void streamWriteVarDouble(int streamID, int varID, const double *data, int nmiss)
{
stream_write_var(streamID, varID, MEMTYPE_DOUBLE, data, nmiss);
}
void streamWriteVarFloat(int streamID, int varID, const float *data, int nmiss)
{
stream_write_var(streamID, varID, MEMTYPE_FLOAT, data, nmiss);
}
/*
@Function streamReadVarSlice
@Title Read a horizontal slice of a variable
......@@ -1701,24 +1720,8 @@ void streamReadVarSlice(int streamID, int varID, int levelID, double *data, int
}
}
/*
@Function streamWriteVarSlice
@Title Write a horizontal slice of a variable
@Prototype void streamWriteVarSlice(int streamID, int varID, int levelID, const double *data, int nmiss)
@Parameter
@Item streamID Stream ID, from a previous call to @fref{streamOpenRead} or @fref{streamOpenWrite}.
@Item varID Variable identifier.
@Item levelID Level identifier.
@Item data Pointer to a block of data values to be written.
@Item nmiss Number of missing values.
@Description
The function streamWriteVarSlice writes the values of a horizontal slice of a
variable to an open dataset.
@EndFunction
*/
void streamWriteVarSlice(int streamID, int varID, int levelID, const double *data, int nmiss)
void stream_write_var_slice(int streamID, int varID, int levelID, int memtype, const void *data, int nmiss)
{
int filetype;
int ierr = 0;
......@@ -1740,6 +1743,7 @@ void streamWriteVarSlice(int streamID, int varID, int levelID, const double *dat
case FILETYPE_GRB:
case FILETYPE_GRB2:
{
if ( memtype == MEMTYPE_FLOAT ) Error("grbWriteVarSlice not implemented for memtype float!");
grbWriteVarSliceDP(streamID, varID, levelID, data, nmiss);
break;
}
......@@ -1747,6 +1751,7 @@ void streamWriteVarSlice(int streamID, int varID, int levelID, const double *dat
#if defined (HAVE_LIBSERVICE)
case FILETYPE_SRV:
{
if ( memtype == MEMTYPE_FLOAT ) Error("srvWriteVarSlice not implemented for memtype float!");
srvWriteVarSliceDP(streamID, varID, levelID, data);
break;
}
......@@ -1754,6 +1759,7 @@ void streamWriteVarSlice(int streamID, int varID, int levelID, const double *dat
#if defined (HAVE_LIBEXTRA)
case FILETYPE_EXT:
{
if ( memtype == MEMTYPE_FLOAT ) Error("extWriteVarSlice not implemented for memtype float!");
extWriteVarSliceDP(streamID, varID, levelID, data);
break;
}
......@@ -1761,6 +1767,7 @@ void streamWriteVarSlice(int streamID, int varID, int levelID, const double *dat
#if defined (HAVE_LIBIEG)
case FILETYPE_IEG:
{
if ( memtype == MEMTYPE_FLOAT ) Error("iegWriteVarSlice not implemented for memtype float!");
iegWriteVarSliceDP(streamID, varID, levelID, data);
break;
}
......@@ -1772,7 +1779,7 @@ void streamWriteVarSlice(int streamID, int varID, int levelID, const double *dat
case FILETYPE_NC4C:
{
if ( streamptr->accessmode == 0 ) cdfEndDef(streamID);
ierr = cdfWriteVarSliceDP(streamID, varID, levelID, data, nmiss);
ierr = cdf_write_var_slice(streamID, varID, levelID, memtype, data, nmiss);
break;
}
#endif
......@@ -1784,6 +1791,37 @@ void streamWriteVarSlice(int streamID, int varID, int levelID, const double *dat
}
}
/*
@Function streamWriteVarSlice
@Title Write a horizontal slice of a variable
@Prototype void streamWriteVarSlice(int streamID, int varID, int levelID, const double *data, int nmiss)
@Parameter
@Item streamID Stream ID, from a previous call to @fref{streamOpenRead} or @fref{streamOpenWrite}.
@Item varID Variable identifier.
@Item levelID Level identifier.
@Item data Pointer to a block of data values to be written.
@Item nmiss Number of missing values.
@Description
The function streamWriteVarSlice writes the values of a horizontal slice of a variable to an open dataset.
@EndFunction
*/
void streamWriteVarSlice(int streamID, int varID, int levelID, const double *data, int nmiss)
{
stream_write_var_slice(streamID, varID, levelID, MEMTYPE_DOUBLE, data, nmiss);
}
void streamWriteVarSliceDouble(int streamID, int varID, int levelID, const double *data, int nmiss)
{
stream_write_var_slice(streamID, varID, levelID, MEMTYPE_DOUBLE, data, nmiss);
}
void streamWriteVarSliceFloat(int streamID, int varID, int levelID, const float *data, int nmiss)
{
stream_write_var_slice(streamID, varID, levelID, MEMTYPE_FLOAT, data, nmiss);
}
void streamWriteContents(int streamID, char *cname)
{
......
......@@ -501,6 +501,7 @@ int cdfCopyRecord(int streamID2, int streamID1)
int ivarID, gridID;
int nmiss;
int ierr = 0;
int memtype = MEMTYPE_DOUBLE;
int vlistID1, vlistID2;
stream_t *streamptr1;
stream_t *streamptr2;
......@@ -531,7 +532,7 @@ int cdfCopyRecord(int streamID2, int streamID1)
data = (double *) malloc(datasize*sizeof(double));
streamReadRecord(streamID1, data, &nmiss);
streamWriteRecord(streamID2, data, nmiss);
stream_write_record(streamID2, memtype, data, nmiss);
free(data);
......@@ -747,7 +748,7 @@ void cdfDefVarMissval(int streamID, int varID, int dtype, int lcheck)
}
#endif
void cdfWriteRecord(int streamID, const double *data, int nmiss)
void cdf_write_record(int streamID, int memtype, const void *data, int nmiss)
{
#if defined (HAVE_LIBNETCDF)
int varID;
......@@ -762,7 +763,7 @@ void cdfWriteRecord(int streamID, const double *data, int nmiss)
if ( CDI_Debug )
Message("streamID = %d varID = %d", streamID, varID);
cdfWriteVarSliceDP(streamID, varID, levelID, data, nmiss);
cdf_write_var_slice(streamID, varID, levelID, memtype, data, nmiss);
#endif
}
......@@ -3247,8 +3248,182 @@ void cdfReadVarDP(int streamID, int varID, double *data, int *nmiss)
#endif
}
static
int cdf_write_var_data(int fileID, int vlistID, int varID, int ncvarid, int dtype, long nvals, size_t xsize, size_t ysize, int swapxy, size_t *start, size_t *count, int memtype, const void *data, int nmiss)
{
#if defined (HAVE_LIBNETCDF)
long i, j;
const double *data_dp = (const double *) data;
const double *pdata_dp = data;
double *mdata_dp = NULL;
double *sdata_dp = NULL;
const float *data_sp = (const float *) data;
const float *pdata_sp = data;
float *mdata_sp = NULL;
float *sdata_sp = NULL;
extern int CDF_Debug;
/* if ( dtype == DATATYPE_INT8 || dtype == DATATYPE_INT16 || dtype == DATATYPE_INT32 ) */
{
int laddoffset, lscalefactor;
double addoffset, scalefactor;
double missval;
addoffset = vlistInqVarAddoffset(vlistID, varID);
scalefactor = vlistInqVarScalefactor(vlistID, varID);
laddoffset = IS_NOT_EQUAL(addoffset, 0);
lscalefactor = IS_NOT_EQUAL(scalefactor, 1);
missval = vlistInqVarMissval(vlistID, varID);
if ( laddoffset || lscalefactor )
{
if ( memtype == MEMTYPE_FLOAT )
{
mdata_sp = (float *) malloc(nvals*sizeof(float));
memcpy(mdata_sp, data_sp, nvals*sizeof(float));
if ( nmiss > 0 )
{
for ( i = 0; i < nvals; i++ )
{
if ( !DBL_IS_EQUAL(mdata_sp[i], missval) )
{
if ( laddoffset ) mdata_sp[i] -= addoffset;
if ( lscalefactor ) mdata_sp[i] /= scalefactor;
}
}
}
else
{
for ( i = 0; i < nvals; i++ )
{
if ( laddoffset ) mdata_sp[i] -= addoffset;
if ( lscalefactor ) mdata_sp[i] /= scalefactor;
}
}
}
else
{
mdata_dp = (double *) malloc(nvals*sizeof(double));
memcpy(mdata_dp, data_dp, nvals*sizeof(double));
if ( nmiss > 0 )
{
for ( i = 0; i < nvals; i++ )
{
if ( !DBL_IS_EQUAL(mdata_dp[i], missval) )
{
if ( laddoffset ) mdata_dp[i] -= addoffset;
if ( lscalefactor ) mdata_dp[i] /= scalefactor;
}
}
}
else
{
for ( i = 0; i < nvals; i++ )
{
if ( laddoffset ) mdata_dp[i] -= addoffset;
if ( lscalefactor ) mdata_dp[i] /= scalefactor;
}
}
}
}
if ( dtype == DATATYPE_UINT8 || dtype == DATATYPE_INT8 ||
dtype == DATATYPE_INT16 || dtype == DATATYPE_INT32 )
{
if ( memtype == MEMTYPE_FLOAT )
{
if ( mdata_sp == NULL ) mdata_sp = (float *) malloc(nvals*sizeof(float));
for ( i = 0; i < nvals; i++ ) mdata_sp[i] = NINT(mdata_sp[i]);
if ( dtype == DATATYPE_UINT8 )
{
nc_type xtype;
cdf_inq_vartype(fileID, ncvarid, &xtype);
if ( xtype == NC_BYTE )
{
for ( i = 0; i < nvals; ++i )
if ( mdata_sp[i] > 127 ) mdata_sp[i] -= 256;
}
}
}
else
{
if ( mdata_dp == NULL ) mdata_dp = (double *) malloc(nvals*sizeof(double));
for ( i = 0; i < nvals; i++ ) mdata_dp[i] = NINT(mdata_dp[i]);
if ( dtype == DATATYPE_UINT8 )
{
nc_type xtype;
cdf_inq_vartype(fileID, ncvarid, &xtype);
if ( xtype == NC_BYTE )
{
for ( i = 0; i < nvals; ++i )
if ( mdata_dp[i] > 127 ) mdata_dp[i] -= 256;
}
}
}
}
if ( CDF_Debug )
{
double fmin, fmax;
fmin = 1.0e200;
fmax = -1.0e200;
for ( i = 0; i < nvals; ++i )
{
if ( !DBL_IS_EQUAL(data_dp[i], missval) )
{
if ( data_dp[i] < fmin ) fmin = data_dp[i];
if ( data_dp[i] > fmax ) fmax = data_dp[i];
}
}
Message("nvals = %d, nmiss = %d, missval = %g, minval = %g, maxval = %g",
nvals, nmiss, missval, fmin, fmax);
}
if ( mdata_dp ) pdata_dp = mdata_dp;
}
void cdfWriteVarDP(int streamID, int varID, const double *data, int nmiss)
if ( swapxy )
{
if ( memtype == MEMTYPE_FLOAT )
{
sdata_sp = (float *) malloc(nvals*sizeof(float));
for ( j = 0; j < (long)ysize; ++j )
for ( i = 0; i < (long)xsize; ++i )
sdata_sp[i*ysize+j] = pdata_sp[j*xsize+i];
pdata_sp = sdata_sp;
}
else
{
sdata_dp = (double *) malloc(nvals*sizeof(double));
for ( j = 0; j < (long)ysize; ++j )
for ( i = 0; i < (long)xsize; ++i )
sdata_dp[i*ysize+j] = pdata_dp[j*xsize+i];
pdata_dp = sdata_dp;
}
}
if ( memtype == MEMTYPE_FLOAT )
cdf_put_vara_float(fileID, ncvarid, start, count, pdata_sp);
else
cdf_put_vara_double(fileID, ncvarid, start, count, pdata_dp);
if ( mdata_dp ) free(mdata_dp);
if ( sdata_dp ) free(sdata_dp);
if ( mdata_sp ) free(mdata_sp);
if ( sdata_sp ) free(sdata_sp);
#endif
return (0);
}
void cdf_write_var(int streamID, int varID, int memtype, const void *data, int nmiss)
{
#if defined (HAVE_LIBNETCDF)
int fileID;
......@@ -3257,17 +3432,18 @@ void cdfWriteVarDP(int streamID, int varID, const double *data, int nmiss)
int xid = UNDEFID, yid = UNDEFID, zid = UNDEFID;
int ncvarid;
int ntsteps;
size_t xsize = 0, ysize = 0;
size_t size;
size_t start[4];
size_t count[4];
long nvals;
int swapxy = FALSE;
int ndims = 0;
int idim;
int timeID;
int gridindex, zaxisindex;
int i;
int dtype;
int vlistID;
double *mdata = NULL;
stream_t *streamptr;
streamptr = stream_to_pointer(streamID);
......@@ -3347,69 +3523,10 @@ void cdfWriteVarDP(int streamID, int varID, const double *data, int nmiss)
if ( nmiss > 0 ) cdfDefVarMissval(streamID, varID, dtype, 1);
/* if ( dtype == DATATYPE_INT8 || dtype == DATATYPE_INT16 || dtype == DATATYPE_INT32 ) */
{
int nvals;
int laddoffset, lscalefactor;
double addoffset, scalefactor;
double missval;
addoffset = vlistInqVarAddoffset(vlistID, varID);
scalefactor = vlistInqVarScalefactor(vlistID, varID);
laddoffset = IS_NOT_EQUAL(addoffset, 0);
lscalefactor = IS_NOT_EQUAL(scalefactor, 1);
missval = vlistInqVarMissval(vlistID, varID);
nvals = gridInqSize(gridID)*zaxisInqSize(zaxisID);
if ( laddoffset || lscalefactor )
{
mdata = (double *) malloc(nvals*sizeof(double));
memcpy(mdata, data, nvals*sizeof(double));
if ( nmiss > 0 )
{
for ( i = 0; i < nvals; i++ )
{
if ( !DBL_IS_EQUAL(data[i], missval) )
{