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

Added streamReadVarPart() and streamReadVarSlicePart().

parent 3f08ceee
......@@ -2,6 +2,10 @@
* Version 1.9.4 released
2018-04-03 Uwe Schulzweida
* Added streamReadVarPart() and streamReadVarSlicePart() [patch from: Niklas Rber]
2018-03-16 Uwe Schulzweida
* Set default data type for grids to CDI_DATATYPE_FLT64
......
......@@ -699,4 +699,329 @@ void cdf_read_record(stream_t *streamptr, int memtype, void *data, size_t *nmiss
cdfReadVarSliceSP(streamptr, varID, levelID, (float*) data, nmiss);
}
//----------------------------------------------------------------------------
// Parallel Version
//----------------------------------------------------------------------------
void cdfReadVarSliceDPPart(stream_t *streamptr, int varID, int levelID, int varType, int startpoint, size_t length, double *data, size_t *nmiss)
{
(void)(varType);
size_t start[4];
size_t count[4];
if ( CDI_Debug )
Message("streamID = %d varID = %d levelID = %d", streamptr->self, varID, levelID);
int vlistID = streamptr->vlistID;
int fileID = streamptr->fileID;
bool swapxy;
cdfGetSliceSlapDescription(streamptr, varID, levelID, &swapxy, &start, &count);
int ncvarid = streamptr->vars[varID].ncvarid;
int gridId = vlistInqVarGrid(vlistID, varID);
//int time = vlistInqVarTsteptype(vlistID, varID);
size_t gridsize = (size_t)gridInqSize(gridId);
size_t xsize = (size_t)gridInqXsize(gridId);
size_t ysize = (size_t)gridInqYsize(gridId);
unsigned int position = 0;
for (int i=0 ; i<4 ; i++)
if (count[i] == gridsize)
position = i;
start[position] = start[position]+startpoint;
count[position] = length;
if ( vlistInqVarDatatype(vlistID, varID) == DATATYPE_FLT32 )
{
float *data_fp = (float *) Malloc(length*sizeof(*data_fp));
cdf_get_vara_float(fileID, ncvarid, start, count, data_fp);
for ( size_t i = 0; i < length; i++ )
data[i] = (double) data_fp[i];
Free(data_fp);
}
else if ( vlistInqVarDatatype(vlistID, varID) == CDI_DATATYPE_UINT8 )
{
nc_type xtype;
cdf_inq_vartype(fileID, ncvarid, &xtype);
if ( xtype == NC_BYTE )
{
for ( size_t i = 0; i < length; i++ )
if ( data[i] < 0 ) data[i] += 256;
}
}
else
{
cdf_get_vara_double(fileID, ncvarid, start, count, data);
}
if ( swapxy ) transpose2dArrayDP(ysize, xsize, data);
double missval = vlistInqVarMissval(vlistID, varID);
const bool haveMissVal = vlistInqVarMissvalUsed(vlistID, varID);
double validRange[2];
if (!(haveMissVal && vlistInqVarValidrange(vlistID, varID, validRange)))
validRange[0] = DBL_MIN, validRange[1] = DBL_MAX;
double addoffset = vlistInqVarAddoffset(vlistID, varID);
double scalefactor = vlistInqVarScalefactor(vlistID, varID);
size_t nmiss_ = cdfDoInputDataTransformationDP(length, data, haveMissVal, missval, scalefactor, addoffset, validRange[0], validRange[1]);
assert(nmiss_ <= INT_MAX);
*nmiss = (size_t)nmiss_;
}
void cdfReadVarSliceSPPart(stream_t *streamptr, int varID, int levelID, int varType, int startpoint, size_t length, float *data, size_t *nmiss)
{
(void)(varType);
size_t start[4];
size_t count[4];
if ( CDI_Debug )
Message("streamID = %d varID = %d levelID = %d", streamptr->self, varID, levelID);
int vlistID = streamptr->vlistID;
int fileID = streamptr->fileID;
bool swapxy;
cdfGetSliceSlapDescription(streamptr, varID, levelID, &swapxy, &start, &count);
int ncvarid = streamptr->vars[varID].ncvarid;
int gridId = vlistInqVarGrid(vlistID, varID);
// int time = vlistInqVarTsteptype(vlistID, varID);
size_t gridsize = (size_t)gridInqSize(gridId);
size_t xsize = (size_t)gridInqXsize(gridId);
size_t ysize = (size_t)gridInqYsize(gridId);
unsigned int position = 0;
for (int i=0 ; i<4 ; i++)
if (count[i] == gridsize)
position = i;
start[position] = start[position]+startpoint;
count[position] = length;
if ( vlistInqVarDatatype(vlistID, varID) == DATATYPE_FLT32 )
{
float *data_fp = (float *) Malloc(length*sizeof(*data_fp));
cdf_get_vara_float(fileID, ncvarid, start, count, data_fp);
for ( size_t i = 0; i < length; i++ )
data[i] = (float) data_fp[i];
Free(data_fp);
}
else if ( vlistInqVarDatatype(vlistID, varID) == CDI_DATATYPE_UINT8 )
{
nc_type xtype;
cdf_inq_vartype(fileID, ncvarid, &xtype);
if ( xtype == NC_BYTE )
{
for ( size_t i = 0; i < length; i++ )
if ( data[i] < 0 ) data[i] += 256;
}
}
else
{
cdf_get_vara_float(fileID, ncvarid, start, count, data);
}
if ( swapxy ) transpose2dArraySP(ysize, xsize, data);
float missval = vlistInqVarMissval(vlistID, varID);
const bool haveMissVal = vlistInqVarMissvalUsed(vlistID, varID);
double validRange[2];
if (!(haveMissVal && vlistInqVarValidrange(vlistID, varID, validRange)))
validRange[0] = DBL_MIN, validRange[1] = DBL_MAX;
float addoffset = vlistInqVarAddoffset(vlistID, varID);
float scalefactor = vlistInqVarScalefactor(vlistID, varID);
size_t nmiss_ = cdfDoInputDataTransformationSP(length, data, haveMissVal, missval, scalefactor, addoffset, validRange[0], validRange[1]);
assert(nmiss_ <= INT_MAX);
*nmiss = (size_t)nmiss_;
}
static
int cdiStreamReadVarSlicePart(int streamID, int varID, int levelID, int varType, int start, size_t size, int memtype, void *data, size_t *nmiss)
{
int status = 0;
if ( CDI_Debug ) Message("streamID = %d varID = %d", streamID, varID);
check_parg(data);
check_parg(nmiss);
stream_t *streamptr = stream_to_pointer(streamID);
int filetype = streamptr->filetype;
*nmiss = 0;
// currently we only care for netcdf data
switch (filetype)
{
#if defined (HAVE_LIBNETCDF)
case FILETYPE_NC:
case FILETYPE_NC2:
case FILETYPE_NC4:
case FILETYPE_NC4C:
{
if ( memtype == MEMTYPE_FLOAT )
cdfReadVarSliceSPPart(streamptr, varID, levelID, varType, start, size, (float *)data, nmiss);
else
cdfReadVarSliceDPPart(streamptr, varID, levelID, varType, start, size, (double *)data, nmiss);
break;
}
#endif
default:
{
Error("%s support not compiled in!", strfiletype(filetype));
status = 2;
break;
}
}
return status;
}
void cdfReadVarDPPart(stream_t *streamptr, int varID, int varType, int startpoint, size_t length, double *data, size_t *nmiss)
{
(void)(varType);
if ( CDI_Debug ) Message("streamID = %d varID = %d", streamptr->self, varID);
int vlistID = streamptr->vlistID;
int fileID = streamptr->fileID;
int ncvarid = streamptr->vars[varID].ncvarid;
int gridID = vlistInqVarGrid(vlistID, varID);
int zaxisID = vlistInqVarZaxis(vlistID, varID);
size_t start[4];
size_t count[4];
cdfGetSlapDescription(streamptr, varID, &start, &count);
int time = vlistInqVarTimetype(vlistID, varID);
if (time)
{
start[2] = start[2]+startpoint;
count[2] = length;
}
else
{
start[1] = start[1]+startpoint;
count[1] = length;
}
cdf_get_vara_double(fileID, ncvarid, start, count, data);
size_t size = (size_t)gridInqSize(gridID)*(size_t)zaxisInqSize(zaxisID);
double missval = vlistInqVarMissval(vlistID, varID);
const bool haveMissVal = vlistInqVarMissvalUsed(vlistID, varID);
double validRange[2];
if (!(haveMissVal && vlistInqVarValidrange(vlistID, varID, validRange)))
validRange[0] = DBL_MIN, validRange[1] = DBL_MAX;
double addoffset = vlistInqVarAddoffset(vlistID, varID);
double scalefactor = vlistInqVarScalefactor(vlistID, varID);
size_t nmiss_ = cdfDoInputDataTransformationDP(size, data, haveMissVal, missval, scalefactor, addoffset, validRange[0], validRange[1]);
assert(nmiss_ <= INT_MAX);
*nmiss = (size_t)nmiss_;
}
void cdfReadVarSPPart(stream_t *streamptr, int varID, int varType, int startpoint, size_t length, float *data, size_t *nmiss)
{
(void)(varType);
if ( CDI_Debug ) Message("streamID = %d varID = %d", streamptr->self, varID);
int vlistID = streamptr->vlistID;
int fileID = streamptr->fileID;
int ncvarid = streamptr->vars[varID].ncvarid;
int gridID = vlistInqVarGrid(vlistID, varID);
int zaxisID = vlistInqVarZaxis(vlistID, varID);
size_t start[4];
size_t count[4];
cdfGetSlapDescription(streamptr, varID, &start, &count);
int time = vlistInqVarTimetype(vlistID, varID);
if (time)
{
start[2] = start[2]+startpoint;
count[2] = length;
}
else
{
start[1] = start[1]+startpoint;
count[1] = length;
}
cdf_get_vara_float(fileID, ncvarid, start, count, data);
size_t size = (size_t)gridInqSize(gridID)*(size_t)zaxisInqSize(zaxisID);
float missval = vlistInqVarMissval(vlistID, varID);
const bool haveMissVal = vlistInqVarMissvalUsed(vlistID, varID);
double validRange[2];
if (!(haveMissVal && vlistInqVarValidrange(vlistID, varID, validRange)))
validRange[0] = DBL_MIN, validRange[1] = DBL_MAX;
float addoffset = vlistInqVarAddoffset(vlistID, varID);
float scalefactor = vlistInqVarScalefactor(vlistID, varID);
size_t nmiss_ = cdfDoInputDataTransformationSP(size, data, haveMissVal, missval, scalefactor, addoffset, validRange[0], validRange[1]);
assert(nmiss_ <= INT_MAX);
*nmiss = (size_t)nmiss_;
}
static
void cdiStreamReadVarPart(int streamID, int varID, int varType, int start, size_t size, int memtype, void *data, size_t *nmiss)
{
(void)(varType);
if ( CDI_Debug ) Message("streamID = %d varID = %d", streamID, varID);
check_parg(data);
check_parg(nmiss);
stream_t *streamptr = stream_to_pointer(streamID);
int filetype = streamptr->filetype;
*nmiss = 0;
// currently we only care for netcdf data
switch (filetype)
{
#if defined (HAVE_LIBNETCDF)
case FILETYPE_NC:
case FILETYPE_NC2:
case FILETYPE_NC4:
case FILETYPE_NC4C:
{
if ( memtype == MEMTYPE_FLOAT )
cdfReadVarSPPart(streamptr, varID, varType, start, size, (float *)data, nmiss);
else
cdfReadVarDPPart(streamptr, varID, varType, start, size, (double *)data, nmiss);
break;
}
#endif
default:
{
Error("%s support not compiled in!", strfiletype(filetype));
break;
}
}
}
void streamReadVarSlicePart(int streamID, int varID, int levelID, int varType, int start, size_t size, void *data, size_t *nmiss, int memtype)
{
if ( cdiStreamReadVarSlicePart(streamID, varID, levelID, varType, start, size, memtype, data, nmiss) )
{
Error("Unexpected error returned from cdiStreamReadVarSlicePart()!");
}
}
void streamReadVarPart(int streamID, int varID, int varType, int start, size_t size, void *data, size_t *nmiss, int memtype)
{
cdiStreamReadVarPart(streamID, varID, varType, start, size, memtype, data, nmiss);
}
#endif
......@@ -399,10 +399,12 @@ void streamWriteVarF(int streamID, int varID, const float data[], size_t nmis
/* streamReadVar: Read a variable */
void streamReadVar(int streamID, int varID, double data[], size_t *nmiss);
void streamReadVarF(int streamID, int varID, float data[], size_t *nmiss);
void streamReadVarPart(int streamID, int varID, int varType, int start, size_t size, void *data, size_t *nmiss, int memtype);
/* streamWriteVarSlice: Write a horizontal slice of a variable */
void streamWriteVarSlice(int streamID, int varID, int levelID, const double data[], size_t nmiss);
void streamWriteVarSliceF(int streamID, int varID, int levelID, const float data[], size_t nmiss);
void streamReadVarSlicePart(int streamID, int varID, int levelID, int varType, int start, size_t size, void *data, size_t *nmiss, int memtype);
/* streamReadVarSlice: Read a horizontal slice of a variable */
void streamReadVarSlice(int streamID, int varID, int levelID, double data[], size_t *nmiss);
......@@ -998,12 +1000,14 @@ void gridDefXbounds(int gridID, const double xbounds[]);
/* gridInqXbounds: Get the bounds of a X-axis */
size_t gridInqXbounds(int gridID, double xbounds[]);
size_t gridInqXboundsPart(int gridID, int start, size_t size, double xbounds[]);
/* gridDefYbounds: Define the bounds of a Y-axis */
void gridDefYbounds(int gridID, const double ybounds[]);
/* gridInqYbounds: Get the bounds of a Y-axis */
size_t gridInqYbounds(int gridID, double ybounds[]);
size_t gridInqYboundsPart(int gridID, int start, size_t size, double ybounds[]);
void gridDefRowlon(int gridID, int nrowlon, const int rowlon[]);
void gridInqRowlon(int gridID, int rowlon[]);
......
......@@ -262,6 +262,11 @@
# endif
#endif
/* Enable large inode numbers on Mac OS X 10.5. */
#ifndef _DARWIN_USE_64_BIT_INODE
# define _DARWIN_USE_64_BIT_INODE 1
#endif
/* Number of bits in a file offset, on hosts where this is settable. */
#undef _FILE_OFFSET_BITS
......
......@@ -3139,6 +3139,32 @@ gridDefYBoundsSerial(grid_t *gridptr, const double *ybounds)
gridDefBoundsGeneric(gridptr, ybounds, gridptr->y.size, &gridptr->y.bounds);
}
//----------------------------------------------------------------------------
// Parallel Version
//----------------------------------------------------------------------------
size_t gridInqXboundsPart(int gridID, int start, size_t size, double *xbounds)
{
grid_t *gridptr = grid_to_pointer(gridID);
const double *gridptr_xbounds = gridptr->vtable->inqXBoundsPtr(gridptr);
if ( gridptr_xbounds )
if ( size && xbounds )
memcpy(xbounds, gridptr_xbounds+start, size * sizeof (double));
return size;
}
size_t gridInqYboundsPart(int gridID, int start, size_t size, double *ybounds)
{
grid_t *gridptr = grid_to_pointer(gridID);
const double *gridptr_ybounds = gridptr->vtable->inqYBoundsPtr(gridptr);
if ( gridptr_ybounds )
if ( size && ybounds )
memcpy(ybounds, gridptr_ybounds+start, size * sizeof (double));
return size;
}
/*
@Function gridDefYbounds
@Title Define the bounds of a Y-axis
......
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