diff --git a/COPYING b/COPYING deleted file mode 100644 index 8dbf1fb97431cded9cadda09fe8e0f10976ac39c..0000000000000000000000000000000000000000 --- a/COPYING +++ /dev/null @@ -1,14 +0,0 @@ -Copyright 2002-2023, MPI für Meteorologie - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -Copyright notice - ©2002-2023 MPI-M, see list in the AUTHORS file diff --git a/ChangeLog b/ChangeLog index 5c440bcf53d054c838b6ee6d953ae5bc4f7feade..644ade189ad833ab7fdcb0055437a551bf4c728a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,33 @@ +2023-04-17 Uwe Schulzweida + + * Version 2.2.1 released + +2023-04-14 Uwe Schulzweida + + * Add support for NetCDF attribute type NC_INT64 + +2023-04-12 Uwe Schulzweida + + * gribapi decode: add support for single precision float interface (available since ecCodes-2.30.0) + +2023-04-09 Uwe Schulzweida + + * fix Bug #10790 + +2023-03-23 Uwe Schulzweida + + * cgribexDefTime: change relative time to absolute time axis if necessary (bug fix) + +2023-03-13 Uwe Schulzweida + + * set chunkSizeMin to 256k + * change chunkSizeLim from to 1m to 16m + +2023-03-02 Uwe Schulzweida + + * add async_worker support for NCZARR + * query cells: changed to all 1D grids + 2023-02-23 Uwe Schulzweida * using CGRIBEX library version 2.1.0 @@ -6,7 +36,7 @@ 2023-02-05 Uwe Schulzweida - * changed chunkSizeLim from 16777216 to 1048576 + * changed chunkSizeLim from 16m to 1m * NetCDF: added query support for grid cells 2023-02-02 Uwe Schulzweida diff --git a/app/cdi.c b/app/cdi.c index 18df1e676aeb51f4f54822d0ae7b8e491127dacd..0735eec6f08532f7f73a33b140c03bc88f095067 100644 --- a/app/cdi.c +++ b/app/cdi.c @@ -342,7 +342,7 @@ limit_string_length(char *string, size_t maxlen) } static void -printShortinfo(int streamID, int vlistID, int vardis) +print_short_info(int streamID, int vlistID, int vardis) { char tmpname[CDI_MAX_NAME]; char varname[CDI_MAX_NAME]; @@ -981,7 +981,7 @@ main(int argc, char *argv[]) if (Shortinfo) { Info = 0; - printShortinfo(streamID1, vlistID1, Vardis); + print_short_info(streamID1, vlistID1, Vardis); } int tsID = 0; diff --git a/config/default b/config/default index 3d31761c7b6c2958de70cd6c18d30ab30918450b..589653e5711dc6e853c90380eb714e2ba9cef148 100755 --- a/config/default +++ b/config/default @@ -65,12 +65,11 @@ case "${HOSTNAME}" in hama*) CDILIBS="--disable-iso-c-interface \ --enable-maintainer-mode \ - --with-szlib=$HOME/local \ - --with-fdb5=$HOME/src/fdb \ - --with-eccodes=$HOME/local/eccodes-2.27 \ - --with-netcdf=$HOME/local/netcdf-c-4.9.0" + --with-szlib=/opt/local/lib/libaec \ + --with-eccodes=$HOME/local/eccodes-2.30.0 \ + --with-netcdf=$HOME/local/netcdf-c-4.9.1" PREFIX="--prefix=$HOME/local/cdi" - LD_ADD="-Wl,-rpath,$HOME/local/eccodes-2.27/lib -Wl,-rpath,$HOME/src/fdb/lib" + LD_ADD="-Wl,-rpath,$HOME/local/eccodes-2.30.0/lib" if test "$COMP" = clang ; then ${CONFPATH}configure $CONFIG_OPTS $PREFIX $CDILIBS LDFLAGS="$LD_ADD $LDFLAGS" \ CC=clang CFLAGS="-g -pipe -D_REENTRANT -Wall -Wwrite-strings -W -Wfloat-equal -pedantic -O3" diff --git a/configure.ac b/configure.ac index 1b35faae57dda95b2a755bfabf824b416bbcd8f3..9b99859d450c5b9b795a5f05e59aed1ddda86769 100644 --- a/configure.ac +++ b/configure.ac @@ -7,7 +7,7 @@ AC_PREREQ([2.69]) LT_PREREQ([2.4.6]) -AC_INIT([cdi],[2.2.0],[https://mpimet.mpg.de/cdi]) +AC_INIT([cdi],[2.2.1],[https://mpimet.mpg.de/cdi]) AC_DEFINE_UNQUOTED(CDI, ["$PACKAGE_VERSION"], [CDI version]) AC_CONFIG_AUX_DIR([config]) diff --git a/m4/acx_options.m4 b/m4/acx_options.m4 index bd189fce0c864aa76e4c319efef637286e9b2115..9db3fe5a25e02f434da744a9e12389e308df20dd 100644 --- a/m4/acx_options.m4 +++ b/m4/acx_options.m4 @@ -206,10 +206,6 @@ AS_IF([test "x$ENABLE_NC4SZLIB" = "xyes"], [AC_SEARCH_LIBS([nc_def_var_szip], [netcdf], [AC_DEFINE([HAVE_NC_DEF_VAR_SZIP],[1],[Define to 1 for NetCDF4 nc_def_var_szip support])],,)]) -AS_IF([test "x$ENABLE_NC4HDF5" = "xyes"], - [AC_SEARCH_LIBS([H5TS_mutex_lock], [netcdf], - [AC_DEFINE([HAVE_NC4HDF5_THREADSAFE],[1],[Define to 1 for NetCDF4/HDF5 threadsafe support])],,[-lhdf5])]) - AS_IF([test "x$ENABLE_NC4HDF5" = "xyes"], [AC_SEARCH_LIBS([H5get_libversion], [netcdf], [AC_DEFINE([HAVE_H5GET_LIBVERSION],[1],[Define to 1 for H5get_libversion support])],,[-lhdf5])]) diff --git a/src/cdf.c b/src/cdf.c index 6258e26cc65b329a2ab9f7491f061148f9d77e83..6b4f18042040d4cda4ca1c147192c8462b81a675 100644 --- a/src/cdf.c +++ b/src/cdf.c @@ -16,42 +16,7 @@ cdfLibraryVersion(void) return nc_inq_libvers(); } -#ifdef HAVE_H5GET_LIBVERSION -#ifdef __cplusplus -extern "C" -{ -#endif - int H5get_libversion(unsigned *, unsigned *, unsigned *); -#ifdef __cplusplus -} -#endif -#endif - -const char * -hdfLibraryVersion(void) -{ -#ifdef HAVE_H5GET_LIBVERSION - static char hdf_libvers[256]; - static int linit = 0; - if (!linit) - { - linit = 1; - unsigned majnum, minnum, relnum; - H5get_libversion(&majnum, &minnum, &relnum); -#ifdef HAVE_NC4HDF5_THREADSAFE - snprintf(hdf_libvers, sizeof(hdf_libvers), "%u.%u.%u threadsafe", majnum, minnum, relnum); -#else - snprintf(hdf_libvers, sizeof(hdf_libvers), "%u.%u.%u", majnum, minnum, relnum); -#endif - } - - return hdf_libvers; -#else - return "library undefined"; -#endif -} - -int CDF_Debug = 0; /* If set to 1, debugging */ +int CDF_Debug = 0; // If set to 1, debugging void cdfDebug(int debug) @@ -88,7 +53,7 @@ has_uri_scheme(const char *uri) const char *pos = strstr(uri, "://"); if (pos) { - const int len = pos - uri; + int len = pos - uri; if (strncmp(uri, "file", len) == 0 || strncmp(uri, "https", len) == 0 || strncmp(uri, "s3", len) == 0) return true; } @@ -96,64 +61,89 @@ has_uri_scheme(const char *uri) } static int -cdfOpenFile(const char *filename, const char *mode, int *filetype) +cdf_open_read(const char *filename, int *filetype) { int ncid = -1; - const int fmode = tolower(*mode); - int writemode = NC_CLOBBER; int readmode = NC_NOWRITE; - - if (filename == NULL) - ncid = CDI_EINVAL; + int status = cdf_open(filename, readmode, &ncid); + if (status > 0 && ncid < 0) ncid = CDI_ESYSTEM; +#ifdef HAVE_NETCDF4 else { - switch (fmode) - { - case 'r': - { - const int status = cdf_open(filename, readmode, &ncid); - if (status > 0 && ncid < 0) ncid = CDI_ESYSTEM; -#ifdef HAVE_NETCDF4 - else - { - int format = -1; - (void) nc_inq_format(ncid, &format); - if (format == NC_FORMAT_NETCDF4_CLASSIC) *filetype = CDI_FILETYPE_NC4C; - } + int format = -1; + status = nc_inq_format(ncid, &format); + if (status == NC_NOERR && format == NC_FORMAT_NETCDF4_CLASSIC) *filetype = CDI_FILETYPE_NC4C; + +#ifdef NC_FORMATX_NCZARR + int modeNC; + status = nc_inq_format_extended(ncid, &format, &modeNC); + if (status == NC_NOERR && format == NC_FORMATX_NCZARR) *filetype = CDI_FILETYPE_NCZARR; #endif - } - break; - case 'w': + } +#endif + + return ncid; +} + +static int +cdf_open_write(const char *filename, int *filetype) +{ + int ncid = -1; + int writemode = NC_CLOBBER; + #ifdef NC_64BIT_OFFSET - if (*filetype == CDI_FILETYPE_NC2) writemode |= NC_64BIT_OFFSET; + if (*filetype == CDI_FILETYPE_NC2) writemode |= NC_64BIT_OFFSET; #endif #ifdef NC_64BIT_DATA - if (*filetype == CDI_FILETYPE_NC5) writemode |= NC_64BIT_DATA; + if (*filetype == CDI_FILETYPE_NC5) writemode |= NC_64BIT_DATA; #endif #ifdef HAVE_NETCDF4 - if (*filetype == CDI_FILETYPE_NC4C) writemode |= (NC_NETCDF4 | NC_CLASSIC_MODEL); - if (*filetype == CDI_FILETYPE_NC4) writemode |= NC_NETCDF4; - if (*filetype == CDI_FILETYPE_NCZARR) writemode |= NC_NETCDF4; + if (*filetype == CDI_FILETYPE_NC4C) writemode |= (NC_NETCDF4 | NC_CLASSIC_MODEL); + if (*filetype == CDI_FILETYPE_NC4) writemode |= NC_NETCDF4; + if (*filetype == CDI_FILETYPE_NCZARR) writemode |= NC_NETCDF4; #endif - if (*filetype == CDI_FILETYPE_NCZARR) - { - if (!has_uri_scheme(filename)) - { - fprintf(stderr, "URI scheme is missing in NCZarr path!\n"); - return CDI_EINVAL; - } + if (*filetype == CDI_FILETYPE_NCZARR) + { + if (!has_uri_scheme(filename)) + { + fprintf(stderr, "URI scheme is missing in NCZarr path!\n"); + return CDI_EINVAL; + } - cdf_create(filename, writemode, &ncid); - } - else - { - if (has_uri_scheme(filename)) fprintf(stderr, "URI scheme defined for non NCZarr Data Model!\n"); + cdf_create(filename, writemode, &ncid); + } + else + { + if (has_uri_scheme(filename)) fprintf(stderr, "URI scheme defined for non NCZarr Data Model!\n"); - cdf__create(filename, writemode, &ncid); - } + cdf__create(filename, writemode, &ncid); + } + + return ncid; +} + +static int +cdfOpenFile(const char *filename, const char *mode, int *filetype) +{ + int ncid = -1; - if (CDI_Version_Info) cdfComment(ncid); - cdf_put_att_text(ncid, NC_GLOBAL, "Conventions", 6, "CF-1.6"); + if (filename == NULL) + { + ncid = CDI_EINVAL; + } + else + { + int fmode = tolower(*mode); + switch (fmode) + { + case 'r': ncid = cdf_open_read(filename, filetype); break; + case 'w': + ncid = cdf_open_write(filename, filetype); + if (ncid != CDI_EINVAL) + { + if (CDI_Version_Info) cdfComment(ncid); + cdf_put_att_text(ncid, NC_GLOBAL, "Conventions", 6, "CF-1.6"); + } break; case 'a': cdf_open(filename, NC_WRITE, &ncid); break; default: ncid = CDI_EINVAL; @@ -192,55 +182,15 @@ cdfOpen(const char *filename, const char *mode, int filetype) return fileID; } -static int -cdf4CheckLibVersions(void) -{ - int status = 0; -#ifdef HAVE_NETCDF4 -#ifdef HAVE_H5GET_LIBVERSION - static int checked = 0; - if (!checked) - { - checked = 1; - unsigned majnum, minnum, relnum; - - sscanf(nc_inq_libvers(), "%u.%u.%u", &majnum, &minnum, &relnum); - // printf("netCDF %u.%u.%u\n", majnum, minnum, relnum); - const unsigned ncmaxver = 4 * 1000000 + 4 * 1000; - const unsigned nclibver = majnum * 1000000 + minnum * 1000 + relnum; - - if (nclibver <= ncmaxver) - { - H5get_libversion(&majnum, &minnum, &relnum); - const unsigned hdf5maxver = 1 * 1000000 + 10 * 1000; - const unsigned hdf5libver = majnum * 1000000 + minnum * 1000 + relnum; - - if (hdf5libver >= hdf5maxver) - { - fprintf(stderr, "NetCDF library 4.4.0 or earlier, combined with libhdf5 1.10.0 or greater not supported!\n"); - status = 1; - } - } - } -#endif -#endif - return status; -} - int cdf4Open(const char *filename, const char *mode, int *filetype) { if (CDF_Debug) Message("Open %s with mode %c", filename, *mode); #ifdef HAVE_NETCDF4 - if (cdf4CheckLibVersions() == 0) - { - const int fileID = cdfOpenFile(filename, mode, filetype); - if (CDF_Debug) Message("File %s opened with id %d", filename, fileID); - return fileID; - } - - return CDI_EUFTYPE; + int fileID = cdfOpenFile(filename, mode, filetype); + if (CDF_Debug) Message("File %s opened with id %d", filename, fileID); + return fileID; #else return CDI_ELIBNAVAIL; #endif diff --git a/src/cdf.h b/src/cdf.h index b2bb1f21bb02e6f7140de828e2e2251ab155d0ab..1c4d35a98b39c6f4f987c67a1cde86fa2a970993 100644 --- a/src/cdf.h +++ b/src/cdf.h @@ -6,7 +6,6 @@ void cdfDebug(int debug); extern int CDF_Debug; const char *cdfLibraryVersion(void); -const char *hdfLibraryVersion(void); int cdfOpen(const char *filename, const char *mode, int filetype); int cdf4Open(const char *filename, const char *mode, int *filetype); diff --git a/src/cdf_int.c b/src/cdf_int.c index ab04a510ba954d4fcb56447e8b8bbd6e04fee98a..9d19a1c7f2e61eb6c6e69c3a70fb7b650b87a5b7 100644 --- a/src/cdf_int.c +++ b/src/cdf_int.c @@ -718,6 +718,20 @@ cdf_get_att_int(int ncid, int varid, const char *name, int *ip) if (status != NC_NOERR) Error("%s", nc_strerror(status)); } +void +cdf_get_att_int64(int ncid, int varid, const char *name, int64_t *ip) +{ +#ifdef HAVE_NETCDF4 + int status = nc_get_att_longlong(ncid, varid, name, ip); + + if (status == NC_ERANGE) status = NC_NOERR; + + if (CDF_Debug || status != NC_NOERR) Message("ncid=%d varid=%d att=%s val=%lld", ncid, varid, name, *ip); + + if (status != NC_NOERR) Error("%s", nc_strerror(status)); +#endif +} + void cdf_get_att_double(int ncid, int varid, const char *name, double *dp) { diff --git a/src/cdf_int.h b/src/cdf_int.h index 2925d99b6576f4f30479c802f94a2ddc3f66e149..0cbbbb6c2c999086d12ab1a9c0e6440ad402450a 100644 --- a/src/cdf_int.h +++ b/src/cdf_int.h @@ -4,6 +4,7 @@ #ifdef HAVE_LIBNETCDF #include <netcdf.h> +#include <stdint.h> // int64_t void cdf__create(const char *path, int cmode, int *idp); void cdf_create(const char *path, int cmode, int *idp); @@ -79,6 +80,7 @@ void cdf_put_att_double(int ncid, int varid, const char *name, nc_type xtype, si void cdf_get_att_string(int ncid, int varid, const char *name, char **tp); void cdf_get_att_text(int ncid, int varid, const char *name, char *tp); void cdf_get_att_int(int ncid, int varid, const char *name, int *ip); +void cdf_get_att_int64(int ncid, int varid, const char *name, int64_t *ip); void cdf_get_att_double(int ncid, int varid, const char *name, double *dp); void cdf_inq_att(int ncid, int varid, const char *name, nc_type *xtypep, size_t *lenp); diff --git a/src/cdf_read.c b/src/cdf_read.c index cb9e6bf44a454d059df6cfe779cb85505196f065..1ecd04ae56283e01405ad18f4f71eed0b3750ba8 100644 --- a/src/cdf_read.c +++ b/src/cdf_read.c @@ -7,6 +7,7 @@ #include <limits.h> #include <float.h> +#include "async_worker.h" #include "dmemory.h" #include "cdi.h" #include "cdi_int.h" @@ -445,10 +446,9 @@ enum }; static void -cdfGetSliceSlapDescription(stream_t *streamptr, int varID, int levelID, bool *outSwapXY, size_t start[cdfSliceNDim], +cdfGetSliceSlapDescription(stream_t *streamptr, int tsID, int varID, int levelID, bool *outSwapXY, size_t start[cdfSliceNDim], size_t count[cdfSliceNDim]) { - int tsID = streamptr->curTsID; int fileId = streamptr->fileID; int vlistID = streamptr->vlistID; int ncvarid = streamptr->vars[varID].ncvarid; @@ -710,13 +710,13 @@ cdf_read_var(stream_t *streamptr, int varID, int memtype, void *data, size_t *nm } static void -cdfReadVarSliceDP(stream_t *streamptr, int varID, int levelID, double *data, size_t *nmiss) +cdf_read_var_slice_DP(stream_t *streamptr, int tsID, int varID, int levelID, double *data, size_t *nmiss) { - if (CDI_Debug) Message("streamID = %d varID = %d levelID = %d", streamptr->self, varID, levelID); + if (CDI_Debug) Message("streamID=%d tsID=%d varID=%d levelID=%d", streamptr->self, tsID, varID, levelID); bool swapxy = false; size_t start[cdfSliceNDim], count[cdfSliceNDim]; - cdfGetSliceSlapDescription(streamptr, varID, levelID, &swapxy, start, count); + cdfGetSliceSlapDescription(streamptr, tsID, varID, levelID, &swapxy, start, count); int vlistID = streamptr->vlistID; int gridId = vlistInqVarGrid(vlistID, varID); @@ -729,13 +729,19 @@ cdfReadVarSliceDP(stream_t *streamptr, int varID, int levelID, double *data, siz } static void -cdfReadVarSliceSP(stream_t *streamptr, int varID, int levelID, float *data, size_t *nmiss) +cdfReadVarSliceDP(stream_t *streamptr, int varID, int levelID, double *data, size_t *nmiss) { - if (CDI_Debug) Message("streamID = %d varID = %d levelID = %d", streamptr->self, varID, levelID); + cdf_read_var_slice_DP(streamptr, streamptr->curTsID, varID, levelID, data, nmiss); +} + +static void +cdf_read_var_slice_SP(stream_t *streamptr, int tsID, int varID, int levelID, float *data, size_t *nmiss) +{ + if (CDI_Debug) Message("streamID=%d tsID=%d varID=%d levelID=%d", streamptr->self, tsID, varID, levelID); bool swapxy = false; size_t start[cdfSliceNDim], count[cdfSliceNDim]; - cdfGetSliceSlapDescription(streamptr, varID, levelID, &swapxy, start, count); + cdfGetSliceSlapDescription(streamptr, tsID, varID, levelID, &swapxy, start, count); int vlistID = streamptr->vlistID; int gridId = vlistInqVarGrid(vlistID, varID); @@ -747,6 +753,12 @@ cdfReadVarSliceSP(stream_t *streamptr, int varID, int levelID, float *data, size *nmiss = cdfDoInputDataTransformationSP(vlistID, varID, length, data); } +static void +cdfReadVarSliceSP(stream_t *streamptr, int varID, int levelID, float *data, size_t *nmiss) +{ + cdf_read_var_slice_SP(streamptr, streamptr->curTsID, varID, levelID, data, nmiss); +} + void cdf_read_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, void *data, size_t *nmiss) { @@ -756,21 +768,190 @@ cdf_read_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, voi cdfReadVarSliceSP(streamptr, varID, levelID, (float *) data, nmiss); } -void -cdf_read_record(stream_t *streamptr, int memtype, void *data, size_t *nmiss) +typedef struct JobArgs { - if (CDI_Debug) Message("streamID = %d", streamptr->self); + stream_t *streamptr; + int varID, levelID; + int recID, tsID, memtype; + void *data; + size_t gridsize, nmiss; +} JobArgs; + +static int +cdf_read_data_async(void *untypedArgs) +{ + JobArgs *args = (JobArgs *) untypedArgs; + + if (args->memtype == MEMTYPE_DOUBLE) + cdf_read_var_slice_DP(args->streamptr, args->tsID, args->varID, args->levelID, (double *) args->data, &args->nmiss); + else + cdf_read_var_slice_SP(args->streamptr, args->tsID, args->varID, args->levelID, (float *) args->data, &args->nmiss); + + return 0; +} +static size_t +cdf_read_data(stream_t *streamptr, int recID, int memtype, void *data) +{ int tsID = streamptr->curTsID; - int vrecID = streamptr->tsteps[tsID].curRecID; - int recID = streamptr->tsteps[tsID].recIDs[vrecID]; int varID = streamptr->tsteps[tsID].records[recID].varID; int levelID = streamptr->tsteps[tsID].records[recID].levelID; + size_t nmiss = 0; if (memtype == MEMTYPE_DOUBLE) - cdfReadVarSliceDP(streamptr, varID, levelID, (double *) data, nmiss); + cdf_read_var_slice_DP(streamptr, tsID, varID, levelID, (double *) data, &nmiss); else - cdfReadVarSliceSP(streamptr, varID, levelID, (float *) data, nmiss); + cdf_read_var_slice_SP(streamptr, tsID, varID, levelID, (float *) data, &nmiss); + + return nmiss; +} + +typedef struct JobDescriptor +{ + JobArgs args; + AsyncJob *job; +} JobDescriptor; + +static JobArgs +job_args_init(stream_t *streamptr, int tsID, int recID, int memtype, void *data) +{ + int varID = streamptr->tsteps[tsID].records[recID].varID; + int levelID = streamptr->tsteps[tsID].records[recID].levelID; + size_t gridsize = gridInqSize(vlistInqVarGrid(streamptr->vlistID, varID)); + + if (!data) data = Malloc(gridsize * ((memtype == MEMTYPE_FLOAT) ? sizeof(float) : sizeof(double))); + + return (JobArgs){ + .streamptr = streamptr, + .varID = varID, + .levelID = levelID, + .recID = recID, + .tsID = tsID, + .memtype = memtype, + .data = data, + .gridsize = gridsize, + .nmiss = 0, + }; +} + +static void +JobDescriptor_startJob(AsyncManager *jobManager, JobDescriptor *me, stream_t *streamptr, int tsID, int recID, int memtype) +{ + me->args = job_args_init(streamptr, tsID, recID, memtype, NULL); + me->job = AsyncWorker_requestWork(jobManager, cdf_read_data_async, &me->args); + if (!me->job) xabort("error while trying to send job to worker thread"); +} + +static void +JobDescriptor_finishJob(AsyncManager *jobManager, JobDescriptor *me, void *data, size_t *nmiss) +{ + if (AsyncWorker_wait(jobManager, me->job)) xabort("error executing job in worker thread"); + memcpy(data, me->args.data, me->args.gridsize * ((me->args.memtype == MEMTYPE_FLOAT) ? sizeof(float) : sizeof(double))); + *nmiss = me->args.nmiss; + + Free(me->args.data); + me->args.recID = -1; // mark as inactive + me->args.tsID = -1; // mark as inactive +} +/* +static long +get_global_recId(stream_t *streamptr, int tsID, int recID) +{ + const tsteps_t *tsteps = streamptr->tsteps; + long globalRecId = recID; + if (tsID > 0) globalRecId += tsteps[0].nrecs; + if (tsID > 1) globalRecId += tsteps[1].nrecs * (tsID - 1); + return globalRecId; +} +*/ + +static void +get_local_step_and_recId(stream_t *streamptr, long globalRecId, int *tsID, int *recID) +{ + int localTsId = 0; + long numSteps = streamptr->ntsteps; + const tsteps_t *tsteps = streamptr->tsteps; + if (numSteps > 0 && globalRecId >= tsteps[0].nrecs) + { + localTsId++; + globalRecId -= tsteps[0].nrecs; + } + while (globalRecId >= tsteps[1].nrecs) + { + localTsId++; + globalRecId -= tsteps[1].nrecs; + } + + *tsID = localTsId; + *recID = globalRecId; +} + +static void +read_next_record(AsyncManager *jobManager, JobDescriptor *jd, stream_t *streamptr, int memtype) +{ + int tsId = -1, recId = -1; + get_local_step_and_recId(streamptr, streamptr->nextGlobalRecId, &tsId, &recId); + int xRecId = streamptr->tsteps[tsId].recIDs[recId]; + JobDescriptor_startJob(jobManager, jd, streamptr, tsId, xRecId, memtype); + streamptr->nextGlobalRecId++; +} + +static void +cdf_read_next_record(stream_t *streamptr, int recID, int memtype, void *data, size_t *nmiss) +{ + bool jobFound = false; + + int workerCount = streamptr->numWorker; + if (workerCount > 0) + { + int tsID = streamptr->curTsID; + + AsyncManager *jobManager = (AsyncManager *) streamptr->jobManager; + JobDescriptor *jobs = (JobDescriptor *) streamptr->jobs; + + // if this is the first call, init and start worker threads + if (!jobs) + { + jobs = (JobDescriptor *) malloc(workerCount * sizeof(*jobs)); + streamptr->jobs = jobs; + for (int i = 0; i < workerCount; i++) jobs[i].args.recID = -1; + for (int i = 0; i < workerCount; i++) jobs[i].args.tsID = -1; + if (AsyncWorker_init(&jobManager, workerCount)) xabort("error while trying to start worker threads"); + streamptr->jobManager = jobManager; + + // Start as many new jobs as possible. + for (int i = 0; streamptr->nextGlobalRecId < streamptr->maxGlobalRecs && i < workerCount; i++) + { + JobDescriptor *jd = &jobs[i]; + if (jd->args.recID < 0 && jd->args.tsID < 0) read_next_record(jobManager, jd, streamptr, memtype); + } + } + + // search for a job descriptor with the given tsID and recID, and use its results if it exists + for (int i = 0; !jobFound && i < workerCount; i++) + { + JobDescriptor *jd = &jobs[i]; + if (jd->args.recID == recID && jd->args.tsID == tsID) + { + jobFound = true; + JobDescriptor_finishJob(jobManager, jd, data, nmiss); + if (streamptr->nextGlobalRecId < streamptr->maxGlobalRecs) read_next_record(jobManager, jd, streamptr, memtype); + } + } + } + + // perform the work synchronously if we didn't start a job for it yet + if (!jobFound) *nmiss = cdf_read_data(streamptr, recID, memtype, data); +} + +void +cdf_read_record(stream_t *streamptr, int memtype, void *data, size_t *nmiss) +{ + int tsID = streamptr->curTsID; + int vrecID = streamptr->tsteps[tsID].curRecID; + int recID = streamptr->tsteps[tsID].recIDs[vrecID]; + + cdf_read_next_record(streamptr, recID, memtype, data, nmiss); } //---------------------------------------------------------------------------- @@ -789,7 +970,7 @@ cdfReadVarSliceDPPart(stream_t *streamptr, int varID, int levelID, int varType, bool swapxy = false; size_t start[cdfSliceNDim], count[cdfSliceNDim]; - cdfGetSliceSlapDescription(streamptr, varID, levelID, &swapxy, start, count); + cdfGetSliceSlapDescription(streamptr, streamptr->curTsID, varID, levelID, &swapxy, start, count); int gridId = vlistInqVarGrid(vlistID, varID); size_t gridsize = gridInqSize(gridId); @@ -820,7 +1001,7 @@ cdfReadVarSliceSPPart(stream_t *streamptr, int varID, int levelID, int varType, bool swapxy = false; size_t start[cdfSliceNDim], count[cdfSliceNDim]; - cdfGetSliceSlapDescription(streamptr, varID, levelID, &swapxy, start, count); + cdfGetSliceSlapDescription(streamptr, streamptr->curTsID, varID, levelID, &swapxy, start, count); int gridId = vlistInqVarGrid(vlistID, varID); size_t gridsize = gridInqSize(gridId); @@ -859,8 +1040,7 @@ cdiStreamReadVarSlicePart(int streamID, int varID, int levelID, int varType, int switch (cdiBaseFiletype(filetype)) { #ifdef HAVE_LIBGRIB - case CDI_FILETYPE_GRB: - case CDI_FILETYPE_GRB2: + case CDI_FILETYPE_GRIB: { grb_read_var_slice(streamptr, varID, levelID, memtype, data, nmiss); break; @@ -947,8 +1127,7 @@ cdiStreamReadVarPart(int streamID, int varID, int varType, int start, size_t siz switch (cdiBaseFiletype(filetype)) { #ifdef HAVE_LIBGRIB - case CDI_FILETYPE_GRB: - case CDI_FILETYPE_GRB2: + case CDI_FILETYPE_GRIB: { grb_read_var(streamptr, varID, memtype, data, nmiss); break; diff --git a/src/cdf_util.c b/src/cdf_util.c index 73cd87caddeade3aff8620f8b072c25a2246401e..6740781643e100955aa3725d7cdcc752107f7819 100644 --- a/src/cdf_util.c +++ b/src/cdf_util.c @@ -22,8 +22,8 @@ strStartsWith(const char *vstr, const char *cstr) bool is_equal = false; if (vstr && cstr) { - const size_t clen = strlen(cstr); - const size_t vlen = strlen(vstr); + size_t clen = strlen(cstr); + size_t vlen = strlen(vstr); if (clen <= vlen) is_equal = (memcmp(vstr, cstr, clen) == 0); } return is_equal; @@ -78,7 +78,7 @@ is_timeaxis_units(const char *timeunits) { bool status = false; - const size_t len = strlen(timeunits); + size_t len = strlen(timeunits); char *tu = (char *) malloc((len + 1) * sizeof(char)); for (size_t i = 0; i < len; i++) tu[i] = (char) tolower((int) timeunits[i]); @@ -124,6 +124,7 @@ is_pressure_units(const char *units) || strStartsWith(units, "mb") || strStartsWith(units, "hectopas") || strStartsWith(units, "hPa") + || strStartsWith(units, "pa") || strStartsWith(units, "Pa")); // clang-format on } diff --git a/src/cdf_write.c b/src/cdf_write.c index fc55629327f24ce937de6220b3d79e5955db2263..47baef5c3b26fbe58ae2fe4a0190622b0a64a7a9 100644 --- a/src/cdf_write.c +++ b/src/cdf_write.c @@ -13,7 +13,7 @@ #include "vlist.h" #include "vlist_var.h" -//#include <netcdf_filter.h> +// #include <netcdf_filter.h> void cdf_def_var_filter(int ncid, int ncvarID, unsigned int id, size_t nparams, const unsigned int *params) @@ -22,6 +22,7 @@ cdf_def_var_filter(int ncid, int ncvarID, unsigned int id, size_t nparams, const int status; if ((status = nc_def_var_filter(ncid, ncvarID, id, nparams, params))) { + Message("filterId=%u numParams=%zu", id, nparams); Error("nc_def_var_filter failed; %s", nc_strerror(status)); } #else @@ -75,6 +76,9 @@ cdfDefVarSzip(int ncid, int ncvarID, int pixels_per_block) if ((status = nc_def_var_szip(ncid, ncvarID, options_mask, pixels_per_block))) Error("nc_def_var_szip failed; %s", nc_strerror(status)); #else + (void) ncid; + (void) ncvarID; + (void) pixels_per_block; static bool lwarn = true; if (lwarn) { @@ -702,14 +706,14 @@ calc_chunksize(size_t chunkSizeLim, size_t size) return chunkSize; } -static const size_t chunkSizeMax = 65536; -static const size_t chunkSizeLim = 1048576; +static const size_t chunkSizeMin = 262144; // 256k +static const size_t chunkSizeLim = 16777216; // 16m size_t calc_chunksize_y(int chunkType, size_t gridsize, size_t xsize, size_t ysize) { if (chunkType == CDI_CHUNK_AUTO) - return (gridsize <= chunkSizeMax) ? ysize : chunkSizeMax / xsize; + return (gridsize <= chunkSizeMin) ? ysize : chunkSizeMin / xsize; else return (chunkType == CDI_CHUNK_LINES) ? 1 : ysize; } @@ -718,7 +722,7 @@ size_t calc_chunksize_x(int chunkType, int chunkSize, size_t xsize, bool yIsUndefined) { if (chunkType == CDI_CHUNK_AUTO && yIsUndefined) - return (chunkSize > 0) ? (size_t) chunkSize : ((xsize <= chunkSizeMax) ? xsize : chunkSizeMax); + return (chunkSize > 0) ? (size_t) chunkSize : ((xsize <= chunkSizeMin) ? xsize : chunkSizeMin); else return calc_chunksize(chunkSizeLim, xsize); } diff --git a/src/cdi_int.c b/src/cdi_int.c index 70459872b617d98a45be178cab66ed8b7a360c23..befd869165e4a4a5082947e8229dfb508ad38c6d 100644 --- a/src/cdi_int.c +++ b/src/cdi_int.c @@ -40,6 +40,7 @@ int CDI_Read_Cell_Corners = 1; int CDI_CMOR_Mode = 0; int CDI_Reduce_Dim = 0; int CDI_Shuffle = 0; +int CDI_Test = 0; size_t CDI_Netcdf_Hdr_Pad = 0UL; size_t CDI_Chunk_Cache = 0UL; size_t CDI_Chunk_Cache_Max = 0UL; @@ -145,9 +146,6 @@ cdiPrintVersion(void) #ifdef HAVE_LIBNETCDF fprintf(stdout, " NetCDF library version : %s\n", cdfLibraryVersion()); #endif -#ifdef HAVE_NC4HDF5 - // fprintf(stdout, " HDF5 library version : %s\n", hdfLibraryVersion()); -#endif #ifdef HAVE_LIBSERVICE fprintf(stdout, " exse library version : %s\n", srvLibraryVersion()); #endif @@ -209,18 +207,13 @@ cdiPrintDatatypes(void) void cdiDebug(int level) { - if (level < 0) return; - unsigned ulevel = (unsigned) level; - - if (ulevel == 1 || (ulevel & 2)) CDI_Debug = 1; - - if (CDI_Debug) Message("debug level %d", level); + unsigned ulevel = (level == 1) ? (1U << 16) : (unsigned) level; - if (ulevel == 1 || (ulevel & 4)) memDebug(1); + if (ulevel & 2) CDI_Debug = 1; + if (ulevel & 4) memDebug(1); + if (ulevel & 8) fileDebug(1); - if (ulevel == 1 || (ulevel & 8)) fileDebug(1); - - if (ulevel == 1 || (ulevel & 16)) + if (ulevel & 16) { #ifdef HAVE_LIBCGRIBEX gribSetDebug(1); @@ -374,6 +367,9 @@ cdiInitialize(void) value = cdi_getenv_int("CDI_CHUNK_CACHE_MAX"); if (value >= 0) CDI_Chunk_Cache_Max = (size_t) value; + value = cdi_getenv_int("CDI_TEST"); + if (value >= 0) CDI_Test = (size_t) value; + envstr = getenv("CDI_GRIB1_TEMPLATE"); if (envstr) CDI_GRIB1_Template = envstr; @@ -544,6 +540,8 @@ cdiBaseFiletype(int filetype) { switch (filetype) { + case CDI_FILETYPE_GRB: + case CDI_FILETYPE_GRB2: return CDI_FILETYPE_GRIB; case CDI_FILETYPE_NC: case CDI_FILETYPE_NC2: case CDI_FILETYPE_NC4: diff --git a/src/cdi_int.h b/src/cdi_int.h index e430405334f631b72ca0fba146506788670ea9a2..7612e7dd46be958768a02a24990196cb674e2dfa 100644 --- a/src/cdi_int.h +++ b/src/cdi_int.h @@ -293,7 +293,10 @@ typedef struct int ncDimID[MAX_DIMS_PS]; size_t ncDimLen[MAX_DIMS_PS]; VCT vct; + size_t chunkSizeTdim; + size_t chunkSizeZdim; #endif + long maxGlobalRecs; int globalatts; int localatts; int unreduced; @@ -372,6 +375,7 @@ extern int CDI_Default_Calendar; // extern int cdiNcMissingValue; extern int CDI_Netcdf_Chunksizehint; extern int CDI_ChunkType; +extern int CDI_Test; extern int CDI_Split_Ltype105; extern int cdiDataUnreduced; extern int cdiSortName; diff --git a/src/cdi_query.c b/src/cdi_query.c index 48a7a20ec7703b5811dd95b74fd0888f7ed3b11e..35bb0eefbe6a6924599825ff0cdff5db6ab66871 100644 --- a/src/cdi_query.c +++ b/src/cdi_query.c @@ -179,6 +179,24 @@ cdiQueryClone(const CdiQuery *query) return queryOut; } +static void +print_list_compact_int(int n, const int *list) +{ + for (int i = 0; i < n; ++i) + { + int value = list[i]; + printf(" %d", value); + if ((i + 2) < n && (value + 1) == list[i + 1] && (value + 2) == list[i + 2]) + { + printf("/to/"); + int last = list[++i]; + while ((i + 1) < n && (last + 1) == list[i + 1]) last = list[++i]; + printf("%d", last); + } + } + printf("\n"); +} + void cdiQueryPrint(const CdiQuery *query) { @@ -201,15 +219,13 @@ cdiQueryPrint(const CdiQuery *query) if (query->numLevidx) { printf("Levidx:"); - for (int i = 0; i < query->numLevidx; ++i) printf(" %d", query->levidx[i]); - printf("\n"); + print_list_compact_int(query->numLevidx, query->levidx); } if (query->numStepidx) { printf("Stepidx:"); - for (int i = 0; i < query->numStepidx; ++i) printf(" %d", query->stepidx[i]); - printf("\n"); + print_list_compact_int(query->numStepidx, query->stepidx); } } } diff --git a/src/dmemory.c b/src/dmemory.c index 854a61cfa14efe9c84054211f1550b3c74cb85bb..1d89ff6d2efaaff6272f14b53c15d372c7f4ddc1 100644 --- a/src/dmemory.c +++ b/src/dmemory.c @@ -13,7 +13,7 @@ #define HAVE_MALLOC_H #endif -#if defined(HAVE_MALLOC_H) +#ifdef HAVE_MALLOC_H #include <malloc.h> #endif @@ -26,6 +26,7 @@ enum REALLOC_FUNC, FREE_FUNC }; + static const char *const memfunc[] = { "Malloc", "Calloc", "Realloc", "Free" }; #undef MEM_UNDEFID @@ -75,6 +76,7 @@ void memDebug(int debug) { MEM_Debug = debug; + if (MEM_Debug && !MEM_Info) MEM_Info = 1; } // If we're not using GNU C, elide __attribute__ @@ -346,7 +348,7 @@ memListChangeEntry(void *ptrold, void *ptr, size_t size, const char *functionnam { item = memTable[memID].item; - const size_t sizeold = memTable[memID].size * memTable[memID].nobj; + size_t sizeold = memTable[memID].size * memTable[memID].nobj; memTable[memID].ptr = ptr; memTable[memID].size = size; @@ -464,7 +466,7 @@ memFree(void *ptr, const char *file, const char *functionname, int line) if (MEM_Info) { size_t size = 0; - const int item = memListDeleteEntry(ptr, &size); + int item = memListDeleteEntry(ptr, &size); if (item >= 0) { if (MEM_Debug) memListPrintEntry(FREE_FUNC, item, size, ptr, functionname, file, line); @@ -502,6 +504,7 @@ memTotal(void) // malloc_stats(); } + memtotal = (size_t) meminfo.arena; #endif diff --git a/src/grb_read.c b/src/grb_read.c index ad4b71c3fc4f11acbe34e8c09d5683c765c5dc57..771ad2618375fe241e652ad97422949d73508838 100644 --- a/src/grb_read.c +++ b/src/grb_read.c @@ -19,8 +19,8 @@ #include "cgribex.h" /* gribZip gribGetZip gribGinfo */ static int -grb_decode(int filetype, int memtype, void *cgribexp, void *gribbuffer, size_t gribsize, void *data, size_t datasize, int unreduced, - size_t *nmiss, double missval) +grb_decode(int filetype, int memType, int datatype, void *cgribexp, void *gribbuffer, size_t gribsize, void *data, size_t datasize, + int unreduced, size_t *nmiss, double missval) { int status = 0; @@ -31,17 +31,20 @@ grb_decode(int filetype, int memtype, void *cgribexp, void *gribbuffer, size_t g extern int cdiNAdditionalGRIBKeys; if (cdiNAdditionalGRIBKeys > 0) Error("CGRIBEX decode does not support reading of additional GRIB keys!"); #endif - status = cgribexDecode(memtype, cgribexp, gribbuffer, gribsize, data, datasize, unreduced, nmiss, missval); + status = cgribexDecode(memType, cgribexp, gribbuffer, gribsize, data, datasize, unreduced, nmiss, missval); } else #endif #ifdef HAVE_LIBGRIB_API { - void *datap = (memtype == MEMTYPE_FLOAT) ? Malloc(datasize * sizeof(double)) : data; + void *datap = data; + bool useFloatInterface = (have_gribapi_float_interface() && datatype != CDI_DATATYPE_FLT32 && datatype != CDI_DATATYPE_FLT64); + int memTypeX = useFloatInterface ? memType : MEMTYPE_DOUBLE; + if (!useFloatInterface && memType == MEMTYPE_FLOAT) datap = Malloc(datasize * sizeof(double)); - status = gribapiDecode(gribbuffer, gribsize, datap, datasize, unreduced, nmiss, missval); + status = gribapiDecode(memTypeX, gribbuffer, gribsize, datap, datasize, unreduced, nmiss, missval); - if (memtype == MEMTYPE_FLOAT) + if (!useFloatInterface && memType == MEMTYPE_FLOAT) { float *dataf = (float *) data; double *datad = (double *) datap; @@ -103,26 +106,26 @@ grib1_unzip_record(void *gribbuffer, size_t *gribsize) return zip; } -typedef struct DecodeArgs +typedef struct JobArgs { - int recID, tsID, *outZip, filetype, memtype, unreduced; + int recID, tsID, *outZip, filetype, memType, datatype, unreduced; void *cgribexp, *gribbuffer, *data; size_t recsize, gridsize, nmiss; double missval; -} DecodeArgs; +} JobArgs; static int grb_decode_record(void *untypedArgs) { - DecodeArgs *args = (DecodeArgs *) untypedArgs; + JobArgs *args = (JobArgs *) untypedArgs; *args->outZip = grib1_unzip_record(args->gribbuffer, &args->recsize); - grb_decode(args->filetype, args->memtype, args->cgribexp, args->gribbuffer, args->recsize, args->data, args->gridsize, - args->unreduced, &args->nmiss, args->missval); + grb_decode(args->filetype, args->memType, args->datatype, args->cgribexp, args->gribbuffer, args->recsize, args->data, + args->gridsize, args->unreduced, &args->nmiss, args->missval); return 0; } -static DecodeArgs -grb_read_raw_data(stream_t *streamptr, int tsID, int recID, int memtype, void *gribbuffer, void *data, bool resetFilePos) +static JobArgs +grb_read_raw_data(stream_t *streamptr, int tsID, int recID, int memType, void *gribbuffer, void *data, bool resetFilePos) { int vlistID = streamptr->vlistID; int varID = streamptr->tsteps[tsID].records[recID].varID; @@ -134,7 +137,7 @@ grb_read_raw_data(stream_t *streamptr, int tsID, int recID, int memtype, void *g void *cgribexp = (gribbuffer && streamptr->record->objectp) ? streamptr->record->objectp : NULL; if (!gribbuffer) gribbuffer = Malloc(streamptr->record->buffersize); - if (!data) data = Malloc(gridsize * ((memtype == MEMTYPE_FLOAT) ? sizeof(float) : sizeof(double))); + if (!data) data = Malloc(gridsize * ((memType == MEMTYPE_FLOAT) ? sizeof(float) : sizeof(double))); if (streamptr->protocol == CDI_PROTOCOL_FDB) { @@ -160,12 +163,12 @@ grb_read_raw_data(stream_t *streamptr, int tsID, int recID, int memtype, void *g if (!resetFilePos) streamptr->numvals += gridsize; } - return (DecodeArgs){ + return (JobArgs){ .recID = recID, .tsID = tsID, .outZip = &streamptr->tsteps[tsID].records[recID].zip, .filetype = streamptr->filetype, - .memtype = memtype, + .memType = memType, .unreduced = streamptr->unreduced, .cgribexp = cgribexp, .gribbuffer = gribbuffer, @@ -174,27 +177,28 @@ grb_read_raw_data(stream_t *streamptr, int tsID, int recID, int memtype, void *g .gridsize = gridsize, .nmiss = 0, .missval = vlistInqVarMissval(vlistID, varID), + .datatype = vlistInqVarDatatype(vlistID, varID), }; } static size_t -grb_read_and_decode_record(stream_t *streamptr, int recID, int memtype, void *data, bool resetFilePos) +grb_read_and_decode_record(stream_t *streamptr, int recID, int memType, void *data, bool resetFilePos) { - DecodeArgs args = grb_read_raw_data(streamptr, streamptr->curTsID, recID, memtype, streamptr->record->buffer, data, resetFilePos); + JobArgs args = grb_read_raw_data(streamptr, streamptr->curTsID, recID, memType, streamptr->record->buffer, data, resetFilePos); grb_decode_record(&args); return args.nmiss; } typedef struct JobDescriptor { - DecodeArgs args; + JobArgs args; AsyncJob *job; } JobDescriptor; static void -JobDescriptor_startJob(AsyncManager *jobManager, JobDescriptor *me, stream_t *streamptr, int tsID, int recID, int memtype) +JobDescriptor_startJob(AsyncManager *jobManager, JobDescriptor *me, stream_t *streamptr, int tsID, int recID, int memType) { - me->args = grb_read_raw_data(streamptr, tsID, recID, memtype, NULL, NULL, false); + me->args = grb_read_raw_data(streamptr, tsID, recID, memType, NULL, NULL, false); me->job = AsyncWorker_requestWork(jobManager, grb_decode_record, &me->args); if (!me->job) xabort("error while trying to send job to worker thread"); } @@ -203,7 +207,7 @@ static void JobDescriptor_finishJob(AsyncManager *jobManager, JobDescriptor *me, void *data, size_t *nmiss) { if (AsyncWorker_wait(jobManager, me->job)) xabort("error executing job in worker thread"); - memcpy(data, me->args.data, me->args.gridsize * ((me->args.memtype == MEMTYPE_FLOAT) ? sizeof(float) : sizeof(double))); + memcpy(data, me->args.data, me->args.gridsize * ((me->args.memType == MEMTYPE_FLOAT) ? sizeof(float) : sizeof(double))); *nmiss = me->args.nmiss; Free(me->args.gribbuffer); @@ -222,19 +226,6 @@ get_global_recId(stream_t *streamptr, int tsID, int recID) return globalRecId; } */ -static long -get_max_global_recs(stream_t *streamptr) -{ - long maxGlobalRecs = -1; - long numSteps = streamptr->ntsteps; - if (numSteps > 0) - { - const tsteps_t *tsteps = streamptr->tsteps; - maxGlobalRecs = tsteps[0].nrecs; - if (numSteps > 1) maxGlobalRecs += tsteps[1].nrecs * (numSteps - 1); - } - return maxGlobalRecs; -} static void get_local_step_and_recId(stream_t *streamptr, long globalRecId, int *tsID, int *recID) @@ -258,17 +249,17 @@ get_local_step_and_recId(stream_t *streamptr, long globalRecId, int *tsID, int * } static void -read_next_record(AsyncManager *jobManager, JobDescriptor *jd, stream_t *streamptr, int memtype) +read_next_record(AsyncManager *jobManager, JobDescriptor *jd, stream_t *streamptr, int memType) { int tsId = -1, recId = -1; get_local_step_and_recId(streamptr, streamptr->nextGlobalRecId, &tsId, &recId); int xRecId = streamptr->tsteps[tsId].recIDs[recId]; - JobDescriptor_startJob(jobManager, jd, streamptr, tsId, xRecId, memtype); + JobDescriptor_startJob(jobManager, jd, streamptr, tsId, xRecId, memType); streamptr->nextGlobalRecId++; } static void -grb_read_next_record(stream_t *streamptr, int recID, int memtype, void *data, size_t *nmiss) +grb_read_next_record(stream_t *streamptr, int recID, int memType, void *data, size_t *nmiss) { bool jobFound = false; @@ -276,17 +267,11 @@ grb_read_next_record(stream_t *streamptr, int recID, int memtype, void *data, si if (workerCount > 0) { int tsID = streamptr->curTsID; - long maxGlobalRecs = get_max_global_recs(streamptr); - // long globalRecId = get_global_recId(streamptr, streamptr->curTsID, recID); - if (maxGlobalRecs == -1) xabort("Internal error: number of timesteps missing!"); - - if (workerCount > maxGlobalRecs) workerCount = maxGlobalRecs; AsyncManager *jobManager = (AsyncManager *) streamptr->jobManager; JobDescriptor *jobs = (JobDescriptor *) streamptr->jobs; // if this is the first call, init and start worker threads - if (!jobs) { jobs = (JobDescriptor *) malloc(workerCount * sizeof(*jobs)); @@ -297,10 +282,10 @@ grb_read_next_record(stream_t *streamptr, int recID, int memtype, void *data, si streamptr->jobManager = jobManager; // Start as many new jobs as possible. - for (int i = 0; streamptr->nextGlobalRecId < maxGlobalRecs && i < workerCount; i++) + for (int i = 0; streamptr->nextGlobalRecId < streamptr->maxGlobalRecs && i < workerCount; i++) { JobDescriptor *jd = &jobs[i]; - if (jd->args.recID < 0 && jd->args.tsID < 0) read_next_record(jobManager, jd, streamptr, memtype); + if (jd->args.recID < 0 && jd->args.tsID < 0) read_next_record(jobManager, jd, streamptr, memType); } } @@ -312,36 +297,36 @@ grb_read_next_record(stream_t *streamptr, int recID, int memtype, void *data, si { jobFound = true; JobDescriptor_finishJob(jobManager, jd, data, nmiss); - if (streamptr->nextGlobalRecId < maxGlobalRecs) read_next_record(jobManager, jd, streamptr, memtype); + if (streamptr->nextGlobalRecId < streamptr->maxGlobalRecs) read_next_record(jobManager, jd, streamptr, memType); } } } // perform the work synchronously if we didn't start a job for it yet - if (!jobFound) *nmiss = grb_read_and_decode_record(streamptr, recID, memtype, data, false); + if (!jobFound) *nmiss = grb_read_and_decode_record(streamptr, recID, memType, data, false); } void -grb_read_record(stream_t *streamptr, int memtype, void *data, size_t *nmiss) +grb_read_record(stream_t *streamptr, int memType, void *data, size_t *nmiss) { int tsID = streamptr->curTsID; int vrecID = streamptr->tsteps[tsID].curRecID; int recID = streamptr->tsteps[tsID].recIDs[vrecID]; - grb_read_next_record(streamptr, recID, memtype, data, nmiss); + grb_read_next_record(streamptr, recID, memType, data, nmiss); } void -grb_read_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, void *data, size_t *nmiss) +grb_read_var_slice(stream_t *streamptr, int varID, int levelID, int memType, void *data, size_t *nmiss) { int isub = subtypeInqActiveIndex(streamptr->vars[varID].subtypeID); int recID = streamptr->vars[varID].recordTable[isub].recordID[levelID]; - *nmiss = grb_read_and_decode_record(streamptr, recID, memtype, data, true); + *nmiss = grb_read_and_decode_record(streamptr, recID, memType, data, true); } void -grb_read_var(stream_t *streamptr, int varID, int memtype, void *data, size_t *nmiss) +grb_read_var(stream_t *streamptr, int varID, int memType, void *data, size_t *nmiss) { int vlistID = streamptr->vlistID; int fileID = streamptr->fileID; @@ -361,9 +346,9 @@ grb_read_var(stream_t *streamptr, int varID, int memtype, void *data, size_t *nm { int recID = streamptr->vars[varID].recordTable[isub].recordID[levelID]; size_t offset = levelID * gridsize; - void *datap = (memtype == MEMTYPE_FLOAT) ? (void *) ((float *) data + offset) : (void *) ((double *) data + offset); + void *datap = (memType == MEMTYPE_FLOAT) ? (void *) ((float *) data + offset) : (void *) ((double *) data + offset); - *nmiss += grb_read_and_decode_record(streamptr, recID, memtype, datap, false); + *nmiss += grb_read_and_decode_record(streamptr, recID, memType, datap, false); } fileSetPos(fileID, currentfilepos, SEEK_SET); diff --git a/src/grb_write.c b/src/grb_write.c index 433e693ccdcad6b4af540eb9c6717d2beecd3bcd..818ac30f262fb22317a902e3fb3b93c07e3bdc41 100644 --- a/src/grb_write.c +++ b/src/grb_write.c @@ -24,9 +24,9 @@ #include "namespace.h" static size_t -grbEncode(int filetype, int memtype, int varID, int levelID, int vlistID, int gridID, int zaxisID, CdiDateTime vDateTime, - int tsteptype, int numavg, size_t datasize, const void *data, size_t nmiss, void **gribbuffer, int comptype, - void *gribContainers) +grb_encode(int filetype, int memType, int varID, int levelID, int vlistID, int gridID, int zaxisID, CdiDateTime vDateTime, + int tsteptype, int numavg, size_t datasize, const void *data, size_t nmiss, void **gribbuffer, int comptype, + void *gribContainers) { size_t nbytes = 0; @@ -36,7 +36,7 @@ grbEncode(int filetype, int memtype, int varID, int levelID, int vlistID, int gr size_t gribbuffersize = datasize * 4 + 3000; *gribbuffer = Malloc(gribbuffersize); - nbytes = cgribexEncode(memtype, varID, levelID, vlistID, gridID, zaxisID, vDateTime, tsteptype, numavg, datasize, data, nmiss, + nbytes = cgribexEncode(memType, varID, levelID, vlistID, gridID, zaxisID, vDateTime, tsteptype, numavg, datasize, data, nmiss, *gribbuffer, gribbuffersize); } else @@ -49,7 +49,8 @@ grbEncode(int filetype, int memtype, int varID, int levelID, int vlistID, int gr void *gribContainer = (void *) &((gribContainer_t *) gribContainers)[varID]; #endif const void *datap = data; - if (memtype == MEMTYPE_FLOAT) + int memTypeX = /*have_gribapi_float_interface() ? memType :*/ MEMTYPE_DOUBLE; + if (/*!have_gribapi_float_interface() &&*/ memType == MEMTYPE_FLOAT) { const float *dataf = (const float *) data; double *datad = (double *) Malloc(datasize * sizeof(double)); @@ -58,10 +59,10 @@ grbEncode(int filetype, int memtype, int varID, int levelID, int vlistID, int gr } size_t gribbuffersize; - nbytes = gribapiEncode(varID, levelID, vlistID, gridID, zaxisID, vDateTime, tsteptype, numavg, (long) datasize, datap, nmiss, - gribbuffer, &gribbuffersize, comptype, gribContainer); + nbytes = gribapiEncode(memTypeX, varID, levelID, vlistID, gridID, zaxisID, vDateTime, tsteptype, numavg, (long) datasize, + datap, nmiss, gribbuffer, &gribbuffersize, comptype, gribContainer); - if (memtype == MEMTYPE_FLOAT) Free((void *) datap); + if (/*!have_gribapi_float_interface() &&*/ memType == MEMTYPE_FLOAT) Free((void *) datap); } #else { @@ -77,7 +78,7 @@ grbEncode(int filetype, int memtype, int varID, int levelID, int vlistID, int gr static size_t grbSzip(int filetype, void *gribbuffer, size_t gribbuffersize) { - size_t buffersize = gribbuffersize + 1000; /* compressed record can be greater than source record */ + size_t buffersize = gribbuffersize + 1000; // compressed record can be greater than source record void *buffer = Malloc(buffersize); // memcpy(buffer, gribbuffer, gribbuffersize); @@ -393,8 +394,8 @@ grb_write_var_slice(stream_t *streamptr, int varID, int levelID, int memtype, co } void *gribbuffer = NULL; - size_t nbytes = grbEncode(filetype, memtype, varID, levelID, vlistID, gridID, zaxisID, vDateTime, tsteptype, numavg, datasize, - data, nmiss, &gribbuffer, comptype, streamptr->gribContainers); + size_t nbytes = grb_encode(filetype, memtype, varID, levelID, vlistID, gridID, zaxisID, vDateTime, tsteptype, numavg, datasize, + data, nmiss, &gribbuffer, comptype, streamptr->gribContainers); if (filetype == CDI_FILETYPE_GRB && (comptype == CDI_COMPRESS_SZIP || comptype == CDI_COMPRESS_AEC)) nbytes = grbSzip(filetype, gribbuffer, nbytes); diff --git a/src/gribapi.h b/src/gribapi.h index 34561b7f65c39d1d1ed8ce3a2bf693b6a2fb5b6c..8ffc777521e97bf98dfc0a6a2a2bf81296d7e852 100644 --- a/src/gribapi.h +++ b/src/gribapi.h @@ -62,12 +62,28 @@ void gribContainersNew(stream_t *streamptr); void gribContainersDelete(stream_t *streamptr); #ifdef HAVE_LIBGRIB_API + +#ifdef ECCODES_VERSION +#if ECCODES_VERSION >= 23000 +#define HAVE_GRIBAPI_FLOAT_INTERFACE 1 +#endif +#endif + +static inline int have_gribapi_float_interface() +{ +#ifdef HAVE_GRIBAPI_FLOAT_INTERFACE + return 1; +#else + return 0; +#endif +} + static inline int my_grib_set_double(grib_handle* h, const char* key, double val) { if (CDI_gribapi_debug) fprintf(stderr, "grib_set_double(\tgrib_handle* h, \"%s\", %f)\n", key, val); - const int retVal = grib_set_double(h, key, val); + int retVal = grib_set_double(h, key, val); if (retVal != 0) fprintf(stderr, "!!! failed call to grib_set_double(\tgrib_handle* h, \"%s\", %f) !!!\n", key, val); return retVal; @@ -78,7 +94,7 @@ static inline int my_grib_set_long(grib_handle* h, const char* key, long val) if (CDI_gribapi_debug) fprintf(stderr, "grib_set_long( \tgrib_handle* h, \"%s\", %ld)\n", key, val); - const int retVal = grib_set_long(h, key, val); + int retVal = grib_set_long(h, key, val); if (retVal != 0) fprintf(stderr, "!!! failed call to grib_set_long( \tgrib_handle* h, \"%s\", %ld) !!!\n", key, val); return retVal; diff --git a/src/grid.c b/src/grid.c index bb3ab3de8fddf5d69b6ac8d5e38c0e0b9f300e14..9ac8cf138734237bb68956919c0eecb0d12a689c 100644 --- a/src/grid.c +++ b/src/grid.c @@ -85,8 +85,8 @@ cdiInqAttConvertedToFloat(int gridID, int atttype, const char *attname, int attl if (atttype == CDI_DATATYPE_INT32) { - int attint; - int *pattint = attlen > 1 ? (int *) malloc(attlen * sizeof(int)) : &attint; + int attint = 0; + int *pattint = (attlen > 1) ? (int *) malloc(attlen * sizeof(int)) : &attint; cdiInqAttInt(gridID, CDI_GLOBAL, attname, attlen, pattint); for (int i = 0; i < attlen; ++i) attflt[i] = (double) pattint[i]; if (attlen > 1) free(pattint); @@ -3825,7 +3825,7 @@ gridVerifyProjParamsSTERE(struct CDI_GridProjParams *gpp) if (lwarn) { // lwarn = false; - const char *projection = "lambert_conformal_conic"; + const char *projection = "polar_stereographic"; if (IS_EQUAL(gpp->lon_0, gpp->mv)) Warning("%s mapping parameter %s missing!", projection, "straight_vertical_longitude_from_pole"); if (IS_EQUAL(gpp->lat_0, gpp->mv)) Warning("%s mapping parameter %s missing!", projection, "latitude_of_projection_origin"); diff --git a/src/iterator.c b/src/iterator.c index 1a04de05195e7618b8cecd236fcb10e64f5e624b..9825f62c4f0a4c74dcd78ef440709a25b5bd47b6 100644 --- a/src/iterator.c +++ b/src/iterator.c @@ -114,8 +114,7 @@ cdiIterator_new(const char *path) case CDI_FILETYPE_UNDEF: Warning("Can't open file \"%s\": unknown format\n", path); return NULL; #ifdef HAVE_LIBGRIB_API - case CDI_FILETYPE_GRB: - case CDI_FILETYPE_GRB2: return cdiGribIterator_new(path, filetype); + case CDI_FILETYPE_GRIB: return cdiGribIterator_new(path, filetype); #endif #ifdef HAVE_LIBNETCDF @@ -207,8 +206,7 @@ cdiIterator_clone(CdiIterator *me) switch (cdiBaseFiletype(me->filetype)) { #ifdef HAVE_LIBGRIB_API - case CDI_FILETYPE_GRB: - case CDI_FILETYPE_GRB2: return cdiGribIterator_getSuper(cdiGribIterator_clone(me)); + case CDI_FILETYPE_GRIB: return cdiGribIterator_getSuper(cdiGribIterator_clone(me)); #endif #ifdef HAVE_LIBNETCDF @@ -250,11 +248,10 @@ CdiGribIterator * cdiGribIterator_clone(CdiIterator *me) { sanityCheck(me); - switch (me->filetype) + switch (cdiBaseFiletype(me->filetype)) { #ifdef HAVE_LIBGRIB_API - case CDI_FILETYPE_GRB: - case CDI_FILETYPE_GRB2: return cdiGribIterator_makeClone(me); + case CDI_FILETYPE_GRIB: return cdiGribIterator_makeClone(me); #endif default: return NULL; @@ -282,8 +279,7 @@ cdiIterator_serialize(CdiIterator *me) switch (cdiBaseFiletype(me->filetype)) { #ifdef HAVE_LIBGRIB_API - case CDI_FILETYPE_GRB: - case CDI_FILETYPE_GRB2: subclassDescription = cdiGribIterator_serialize(me); break; + case CDI_FILETYPE_GRIB: subclassDescription = cdiGribIterator_serialize(me); break; #endif #ifdef HAVE_LIBNETCDF @@ -334,8 +330,7 @@ cdiIterator_deserialize(const char *description) switch (cdiBaseFiletype(string2FileType(description, NULL))) { #ifdef HAVE_LIBGRIB_API - case CDI_FILETYPE_GRB: - case CDI_FILETYPE_GRB2: return cdiGribIterator_getSuper(cdiGribIterator_deserialize(description)); + case CDI_FILETYPE_GRIB: return cdiGribIterator_getSuper(cdiGribIterator_deserialize(description)); #endif #ifdef HAVE_LIBNETCDF @@ -400,8 +395,7 @@ cdiIterator_nextField(CdiIterator *me) switch (cdiBaseFiletype(me->filetype)) { #ifdef HAVE_LIBGRIB_API - case CDI_FILETYPE_GRB: - case CDI_FILETYPE_GRB2: return cdiGribIterator_nextField(me); + case CDI_FILETYPE_GRIB: return cdiGribIterator_nextField(me); #endif #ifdef HAVE_LIBNETCDF @@ -429,8 +423,7 @@ cdiIterator_inqTime(CdiIterator *me, CdiTimeType timeType) switch (cdiBaseFiletype(me->filetype)) { #ifdef HAVE_LIBGRIB_API - case CDI_FILETYPE_GRB: - case CDI_FILETYPE_GRB2: return cdiGribIterator_inqTime(me, timeType); + case CDI_FILETYPE_GRIB: return cdiGribIterator_inqTime(me, timeType); #endif #ifdef HAVE_LIBNETCDF @@ -590,8 +583,7 @@ cdiIterator_inqLevelType(CdiIterator *me, int levelSelector, char **outName, cha switch (cdiBaseFiletype(me->filetype)) { #ifdef HAVE_LIBGRIB_API - case CDI_FILETYPE_GRB: - case CDI_FILETYPE_GRB2: return cdiGribIterator_levelType(me, levelSelector, outName, outLongName, outStdName, outUnit); + case CDI_FILETYPE_GRIB: return cdiGribIterator_levelType(me, levelSelector, outName, outLongName, outStdName, outUnit); #endif #ifdef HAVE_LIBNETCDF @@ -637,8 +629,7 @@ cdiIterator_inqLevel(CdiIterator *me, int levelSelector, double *outValue1, doub switch (cdiBaseFiletype(me->filetype)) { #ifdef HAVE_LIBGRIB_API - case CDI_FILETYPE_GRB: - case CDI_FILETYPE_GRB2: return cdiGribIterator_level(me, levelSelector, outValue1, outValue2); + case CDI_FILETYPE_GRIB: return cdiGribIterator_level(me, levelSelector, outValue1, outValue2); #endif #ifdef HAVE_LIBNETCDF @@ -682,8 +673,7 @@ cdiIterator_inqLevelUuid(CdiIterator *me, int *outVgridNumber, int *outLevelCoun switch (cdiBaseFiletype(me->filetype)) { #ifdef HAVE_LIBGRIB_API - case CDI_FILETYPE_GRB: - case CDI_FILETYPE_GRB2: return cdiGribIterator_zaxisUuid(me, outVgridNumber, outLevelCount, outUuid); + case CDI_FILETYPE_GRIB: return cdiGribIterator_zaxisUuid(me, outVgridNumber, outLevelCount, outUuid); #endif #ifdef HAVE_LIBNETCDF @@ -726,8 +716,7 @@ cdiIterator_inqTile(CdiIterator *me, int *outTileIndex, int *outTileAttribute) switch (cdiBaseFiletype(me->filetype)) { #ifdef HAVE_LIBGRIB_API - case CDI_FILETYPE_GRB: - case CDI_FILETYPE_GRB2: return cdiGribIterator_inqTile(me, outTileIndex, outTileAttribute); + case CDI_FILETYPE_GRIB: return cdiGribIterator_inqTile(me, outTileIndex, outTileAttribute); #endif #ifdef HAVE_LIBNETCDF @@ -772,8 +761,7 @@ cdiIterator_inqTileCount(CdiIterator *me, int *outTileCount, int *outTileAttribu switch (cdiBaseFiletype(me->filetype)) { #ifdef HAVE_LIBGRIB_API - case CDI_FILETYPE_GRB: - case CDI_FILETYPE_GRB2: return cdiGribIterator_inqTileCount(me, outTileCount, outTileAttributeCount); + case CDI_FILETYPE_GRIB: return cdiGribIterator_inqTileCount(me, outTileCount, outTileAttributeCount); #endif #ifdef HAVE_LIBNETCDF @@ -921,8 +909,7 @@ cdiIterator_inqVariableName(CdiIterator *me) switch (cdiBaseFiletype(me->filetype)) { #ifdef HAVE_LIBGRIB_API - case CDI_FILETYPE_GRB: - case CDI_FILETYPE_GRB2: return cdiGribIterator_copyVariableName(me); + case CDI_FILETYPE_GRIB: return cdiGribIterator_copyVariableName(me); #endif #ifdef HAVE_LIBNETCDF @@ -987,8 +974,7 @@ cdiIterator_readField(CdiIterator *me, double *buffer, SizeType *nmiss) switch (cdiBaseFiletype(me->filetype)) { #ifdef HAVE_LIBGRIB_API - case CDI_FILETYPE_GRB: - case CDI_FILETYPE_GRB2: cdiGribIterator_readField(me, buffer, &numMiss); return; + case CDI_FILETYPE_GRIB: cdiGribIterator_readField(me, buffer, &numMiss); return; #endif #ifdef HAVE_LIBNETCDF @@ -1034,8 +1020,7 @@ cdiIterator_readFieldF(CdiIterator *me, float *buffer, SizeType *nmiss) switch (cdiBaseFiletype(me->filetype)) { #ifdef HAVE_LIBGRIB_API - case CDI_FILETYPE_GRB: - case CDI_FILETYPE_GRB2: cdiGribIterator_readFieldF(me, buffer, &numMiss); return; + case CDI_FILETYPE_GRIB: cdiGribIterator_readFieldF(me, buffer, &numMiss); return; #endif #ifdef HAVE_LIBNETCDF @@ -1076,8 +1061,7 @@ cdiIterator_delete(CdiIterator *me) switch (cdiBaseFiletype(me->filetype)) { #ifdef HAVE_LIBGRIB_API - case CDI_FILETYPE_GRB: - case CDI_FILETYPE_GRB2: cdiGribIterator_delete((CdiGribIterator *) me); break; + case CDI_FILETYPE_GRIB: cdiGribIterator_delete((CdiGribIterator *) me); break; #endif #ifdef HAVE_LIBNETCDF diff --git a/src/pio_server.c b/src/pio_server.c index 208996fc6a7f8e0f89eee50a3dc63f586eb3e4d3..c3888db345bc4c16c94a168dd3d6b6bbff11fa27 100644 --- a/src/pio_server.c +++ b/src/pio_server.c @@ -1582,8 +1582,7 @@ readGetBuffers(size_t streamIdx, const struct cdiPioConf *conf) switch (cdiBaseFiletype(filetype)) { - case CDI_FILETYPE_GRB: - case CDI_FILETYPE_GRB2: writeGribStream(streamIdx, map, &data, ¤tDataBufSize, conf); break; + case CDI_FILETYPE_GRIB: writeGribStream(streamIdx, map, &data, ¤tDataBufSize, conf); break; #ifdef HAVE_LIBNETCDF case CDI_FILETYPE_NETCDF: writeNetCDFStream(streamIdx, map, &data, ¤tDataBufSize, conf); break; #endif diff --git a/src/stream.c b/src/stream.c index f182e2aa9378f1316c738805a9f71e155b1e6877..cbf82fb09f1d32a88bbd4b4a8c87ca896361419e 100644 --- a/src/stream.c +++ b/src/stream.c @@ -82,7 +82,7 @@ cdiGetFiletype(const char *uri, int *byteorder) { case CDI_PROTOCOL_ACROSS: return CDI_FILETYPE_GRB2; case CDI_PROTOCOL_FDB: return CDI_FILETYPE_UNDEF; - case CDI_PROTOCOL_OTHER: return CDI_FILETYPE_NC; // support for NetCDF remote types and ESDM + case CDI_PROTOCOL_OTHER: return CDI_FILETYPE_NC4; // support for NetCDF remote types and ESDM case CDI_PROTOCOL_FILE: // handled below; break; @@ -213,17 +213,57 @@ cdiInqTimeSize(int streamID) return ntsteps; } +static long +get_max_global_recs(stream_t *streamptr) +{ + long maxGlobalRecs = -1; + const tsteps_t *tsteps = streamptr->tsteps; + if (tsteps) + { + maxGlobalRecs = tsteps[0].nrecs; + long numSteps = streamptr->ntsteps; + if (numSteps > 1) maxGlobalRecs += tsteps[1].nrecs * (numSteps - 1); + } + return maxGlobalRecs; +} + void streamDefNumWorker(int streamID, int numWorker) { if (numWorker > 0) { stream_t *streamptr = stream_to_pointer(streamID); - streamptr->numWorker = numWorker; - int filetype = streamptr->filetype; - bool filetypeIsGrib = (filetype == CDI_FILETYPE_GRB || filetype == CDI_FILETYPE_GRB2); - if (streamptr->filemode == 'r' && filetypeIsGrib) (void) cdiInqTimeSize(streamID); + + if (streamptr->filemode == 'r') + { + if (cdiBaseFiletype(filetype) == CDI_FILETYPE_GRIB) + { + (void) cdiInqTimeSize(streamID); + streamptr->maxGlobalRecs = get_max_global_recs(streamptr); + } +#ifdef HAVE_LIBNETCDF + else if (filetype == CDI_FILETYPE_NCZARR || (CDI_Test && cdiBaseFiletype(filetype) == CDI_FILETYPE_NETCDF)) + { + streamptr->maxGlobalRecs = get_max_global_recs(streamptr); + if (CDI_Test) Message("numWorker=%d", numWorker); + if (CDI_Test) Message("maxGlobalRecs=%ld", streamptr->maxGlobalRecs); + if (streamptr->maxGlobalRecs == -1) xabort("Internal error: number of timesteps missing!"); + if (streamptr->maxGlobalRecs == 1) numWorker = 0; + if (numWorker > streamptr->maxGlobalRecs) numWorker = streamptr->maxGlobalRecs; + if (streamptr->chunkSizeTdim > 1 && numWorker > streamptr->nvars) numWorker = streamptr->nvars; + if (streamptr->chunkSizeZdim > 1) numWorker = 0; + if (CDI_Test) Message("chunkSizeTdim=%d chunkSizeZdim=%d", streamptr->chunkSizeTdim, streamptr->chunkSizeZdim); + } +#endif + else + { + numWorker = 0; + } + + streamptr->numWorker = numWorker; + if (CDI_Debug || CDI_Test) Message("Number of asynchronous worker: %d", numWorker); + } } } @@ -321,8 +361,7 @@ streamFilesuffix(int filetype) switch (cdiBaseFiletype(filetype)) { - case CDI_FILETYPE_GRB: - case CDI_FILETYPE_GRB2: return grbSuffix; + case CDI_FILETYPE_GRIB: return grbSuffix; case CDI_FILETYPE_SRV: return srvSuffix; case CDI_FILETYPE_EXT: return extSuffix; case CDI_FILETYPE_IEG: return iegSuffix; @@ -347,8 +386,7 @@ cdiInqContents(stream_t *streamptr) switch (cdiBaseFiletype(filetype)) { #ifdef HAVE_LIBGRIB - case CDI_FILETYPE_GRB: - case CDI_FILETYPE_GRB2: + case CDI_FILETYPE_GRIB: { switch (streamptr->protocol) { @@ -999,7 +1037,11 @@ streamDefaultValue(stream_t *streamptr) streamptr->vct.mlev = 0; streamptr->vct.ilevID = CDI_UNDEFID; streamptr->vct.mlevID = CDI_UNDEFID; + + streamptr->chunkSizeTdim = 0; + streamptr->chunkSizeZdim = 0; #endif + streamptr->maxGlobalRecs = CDI_UNDEFID; streamptr->gribContainers = NULL; @@ -1073,21 +1115,21 @@ cdiStreamCloseDefaultDelegate(stream_t *streamptr, int recordBufIsToBeDeleted) switch (cdiBaseFiletype(filetype)) { #if defined(HAVE_LIBGRIB) && (defined(HAVE_LIBCGRIBEX) || defined(HAVE_LIBGRIB_API)) - case CDI_FILETYPE_GRB: - { - gribClose(fileID); - if (recordBufIsToBeDeleted) gribContainersDelete(streamptr); + case CDI_FILETYPE_GRIB: + if (filetype == CDI_FILETYPE_GRB) + { + gribClose(fileID); + if (recordBufIsToBeDeleted) gribContainersDelete(streamptr); #ifdef HAVE_LIBCGRIBEX - if (recordBufIsToBeDeleted) cgribexDelete(streamptr->record->objectp); + if (recordBufIsToBeDeleted) cgribexDelete(streamptr->record->objectp); #endif - break; - } - case CDI_FILETYPE_GRB2: - { - gribClose(fileID); - if (recordBufIsToBeDeleted) gribContainersDelete(streamptr); - break; - } + } + else if (filetype == CDI_FILETYPE_GRB2) + { + gribClose(fileID); + if (recordBufIsToBeDeleted) gribContainersDelete(streamptr); + } + break; #endif #ifdef HAVE_LIBSERVICE case CDI_FILETYPE_SRV: @@ -1445,8 +1487,7 @@ streamInqTimestep(int streamID, int tsID) switch (cdiBaseFiletype(filetype)) { #ifdef HAVE_LIBGRIB - case CDI_FILETYPE_GRB: - case CDI_FILETYPE_GRB2: + case CDI_FILETYPE_GRIB: { switch (streamptr->protocol) { @@ -1726,8 +1767,7 @@ cdiStreamSetupVlist_(stream_t *streamptr, int vlistID) break; #endif #ifdef HAVE_LIBGRIB - case CDI_FILETYPE_GRB: - case CDI_FILETYPE_GRB2: gribContainersNew(streamptr); break; + case CDI_FILETYPE_GRIB: gribContainersNew(streamptr); break; #endif default:; } diff --git a/src/stream_cdf_i.c b/src/stream_cdf_i.c index 46f85998a468380ca9c9da6741335fc448f26bce..4504849cfecf409ad1caff37d0222fbb39acf3ea 100644 --- a/src/stream_cdf_i.c +++ b/src/stream_cdf_i.c @@ -307,6 +307,16 @@ xtypeIsInt(nc_type xtype) return isInt; } +static bool +xtypeIsInt64(nc_type xtype) +{ +#ifdef HAVE_NETCDF4 + return (xtype == NC_INT64 || xtype == NC_UINT64); +#else + return false; +#endif +} + static int cdfInqDatatype(stream_t *streamptr, int xtype, bool isUnsigned) { @@ -379,12 +389,35 @@ cdfGetAttInt(int fileID, int ncvarid, const char *attname, size_t attlen, int *a if (xtypeIsFloat(atttype) || xtypeIsInt(atttype)) { bool needAlloc = (nc_attlen > attlen); - int *pintatt = needAlloc ? (int *) (Malloc(nc_attlen * sizeof(int))) : attint; + int *pintatt = needAlloc ? (int *) (malloc(nc_attlen * sizeof(int))) : attint; cdf_get_att_int(fileID, ncvarid, attname, pintatt); if (needAlloc) { memcpy(attint, pintatt, attlen * sizeof(int)); - Free(pintatt); + free(pintatt); + } + } +} + +static void +cdfGetAttInt64(int fileID, int ncvarid, const char *attname, size_t attlen, int64_t *attint) +{ + *attint = 0; + + nc_type atttype; + size_t nc_attlen; + cdf_inq_atttype(fileID, ncvarid, attname, &atttype); + cdf_inq_attlen(fileID, ncvarid, attname, &nc_attlen); + + if (xtypeIsFloat(atttype) || xtypeIsInt(atttype) || xtypeIsInt64(atttype)) + { + bool needAlloc = (nc_attlen > attlen); + int64_t *pintatt = needAlloc ? (int64_t *) (malloc(nc_attlen * sizeof(int64_t))) : attint; + cdf_get_att_int64(fileID, ncvarid, attname, pintatt); + if (needAlloc) + { + memcpy(attint, pintatt, attlen * sizeof(int64_t)); + free(pintatt); } } } @@ -825,7 +858,7 @@ cdf_set_cdi_attr(int ncid, int ncvarid, int attnum, int cdiID, int varID, bool r if (xtypeIsInt(atttype)) { - int attint; + int attint = 0; int *pattint = (attlen > 1) ? (int *) malloc(attlen * sizeof(int)) : &attint; cdfGetAttInt(ncid, ncvarid, attname, attlen, pattint); // clang-format off @@ -841,9 +874,27 @@ cdf_set_cdi_attr(int ncid, int ncvarid, int attnum, int cdiID, int varID, bool r cdiDefAttInt(cdiID, varID, attname, datatype, (int) attlen, pattint); if (attlen > 1) free(pattint); } + else if (xtypeIsInt64(atttype)) + { + int64_t attint64 = 0; + int64_t *pattint64 = (attlen > 1) ? (int64_t *) malloc(attlen * sizeof(int64_t)) : &attint64; + cdfGetAttInt64(ncid, ncvarid, attname, attlen, pattint64); + bool defineAtts = true; + for (size_t i = 0; i < attlen; ++i) + if (pattint64[i] > INT_MAX) defineAtts = false; + if (defineAtts) + { + int attint = 0; + int *pattint = (attlen > 1) ? (int *) malloc(attlen * sizeof(int)) : &attint; + for (size_t i = 0; i < attlen; ++i) pattint[i] = pattint64[i]; + cdiDefAttInt(cdiID, varID, attname, CDI_DATATYPE_INT32, (int) attlen, pattint); + if (attlen > 1) free(pattint); + } + if (attlen > 1) free(pattint64); + } else if (xtypeIsFloat(atttype)) { - double attflt; + double attflt = 0.0; double *pattflt = (attlen > 1) ? (double *) malloc(attlen * sizeof(double)) : &attflt; cdfGetAttDouble(ncid, ncvarid, attname, attlen, pattflt); int datatype = (atttype == NC_FLOAT) ? CDI_DATATYPE_FLT32 : CDI_DATATYPE_FLT64; @@ -1534,6 +1585,32 @@ cdfScanVarAttr(int nvars, ncvar_t *ncvars, int ndims, ncdim_t *ncdims, int timed if (checked_vars[i]) Free(checked_vars[i]); } +static void +cdf_set_chunk_info(stream_t *streamptr, int nvars, ncvar_t *ncvars) +{ + for (int ncvarid = 0; ncvarid < nvars; ncvarid++) + { + ncvar_t *ncvar = &ncvars[ncvarid]; + if (ncvar->varStatus == DataVar) + { + int ndims = ncvar->ndims; + ncvar->isChunked = true; + for (int i = 0; i < ndims; ++i) + { + size_t chunkSize = ncvar->chunks[i]; + if (chunkSize > 1) + { + int dimType = ncvar->dimtype[i]; + // clang-format off + if (dimType == T_AXIS && chunkSize > streamptr->chunkSizeTdim) streamptr->chunkSizeTdim = chunkSize; + else if (dimType == Z_AXIS && chunkSize > streamptr->chunkSizeZdim) streamptr->chunkSizeZdim = chunkSize; + // clang-format on + } + } + } + } +} + static void cdfVerifyVarAttr(int nvars, ncvar_t *ncvars, ncdim_t *ncdims) { @@ -2928,16 +3005,17 @@ cdf_define_all_grids(stream_t *streamptr, ncgrid_t *ncgrid, int vlistID, ncdim_t CdiQuery *query = streamptr->query; if (query) { - if (ncvar->gridtype != GRID_UNSTRUCTURED) - { - Warning("Query parameter cell is only available for unstructured grids, skipped variable %s!", ncvar->name); - ncvar->varStatus = UndefVar; - continue; - } - int numCellidx = cdiQueryNumCellidx(query); if (numCellidx > 0) { + // if (ncvar->gridtype != GRID_UNSTRUCTURED) + if (xdimid != CDI_UNDEFID && ydimid != CDI_UNDEFID) + { + Warning("Query parameter cell is only available for 1D grids, skipped variable %s!", ncvar->name); + ncvar->varStatus = UndefVar; + continue; + } + size_t start = cdiQueryGetCellidx(query, 0); size_t count = (numCellidx == 2) ? cdiQueryGetCellidx(query, 1) : 1; if ((start + count) <= xsize) @@ -4561,15 +4639,15 @@ cdfInqContents(stream_t *streamptr) cdfVerifyVars(nvars, ncvars, ncdims); // select vars - int nvars_data = 0; + int nvarsData = 0; for (int ncvarid = 0; ncvarid < nvars; ncvarid++) - if (ncvars[ncvarid].varStatus == DataVar) nvars_data++; + if (ncvars[ncvarid].varStatus == DataVar) nvarsData++; if (CDI_Debug) Message("time varid = %d", streamptr->basetime.ncvarid); if (CDI_Debug) Message("ntsteps = %zu", ntsteps); - if (CDI_Debug) Message("nvars_data = %d", nvars_data); + if (CDI_Debug) Message("nvarsData = %d", nvarsData); - if (nvars_data == 0) + if (nvarsData == 0) { streamptr->ntsteps = 0; Warning("No data arrays found!"); @@ -4579,7 +4657,9 @@ cdfInqContents(stream_t *streamptr) if (ntsteps == 0 && streamptr->basetime.ncdimid == CDI_UNDEFID && streamptr->basetime.ncvarid != CDI_UNDEFID) ntsteps = 1; // define all data variables - cdf_define_all_vars(streamptr, vlistID, instID, modelID, nvars_data, nvars, ncvars, ncdims, timedimid); + cdf_define_all_vars(streamptr, vlistID, instID, modelID, nvarsData, nvars, ncvars, ncdims, timedimid); + + cdf_set_chunk_info(streamptr, nvars, ncvars); // time varID int nctimevarid = streamptr->basetime.ncvarid; diff --git a/src/stream_cdf_o.c b/src/stream_cdf_o.c index c9359a13abccd82c339a8f8ac82a5d246ac4a81e..ee148433df58e6f15abd900d204d89459f2ae5c5 100644 --- a/src/stream_cdf_o.c +++ b/src/stream_cdf_o.c @@ -98,7 +98,7 @@ struct idSearch }; static inline struct idSearch -cdfSearchIDBySize(size_t startIdx, size_t numIDs, const ncgrid_t ncgrid[/*numIDs*/], int ncIDType, int searchType, int searchSize, +cdfSearchIDBySize(size_t startIdx, size_t numIDs, ncgrid_t ncgrid[/*numIDs*/], int ncIDType, int searchType, int searchSize, int (*typeInq)(int id), SizeType (*sizeInq)(int id)) { int numNonMatching = 0, foundID = CDI_UNDEFID; @@ -869,11 +869,7 @@ cdfDefIrregularGridCommon(stream_t *streamptr, int gridID, size_t xsize, size_t cdiInqKeyString(gridID, CDI_GLOBAL, CDI_KEY_VDIMNAME, vdimname, &length); if (vdimname[0] == 0) strcpy(vdimname, vdimname_default); nvdimID = dimIDs[ndims - 1] = checkDimName(fileID, nvertex, vdimname); - if (nvdimID == CDI_UNDEFID) - { - cdf_def_dim(fileID, vdimname, nvertex, dimIDs + ndims - 1); - nvdimID = dimIDs[ndims - 1]; - } + if (nvdimID == CDI_UNDEFID) cdf_def_dim(fileID, vdimname, nvertex, dimIDs + ndims - 1); } size_t gridsize = xsize * ysize; @@ -1643,10 +1639,7 @@ cdfDefZaxisChar(stream_t *streamptr, int zaxisID, char *axisname, int *dimID, si cdf_enddef(fileID, streamptr->self); // Write Stringvalues - size_t start[2], count[2]; - start[1] = 0; - count[0] = 1; - count[1] = clen; + size_t start[2] = { 0, 0 }, count[2] = { 1, clen }; for (size_t i = 0; i < dimlen; i++) { start[0] = i; @@ -1732,7 +1725,7 @@ cdfDefZaxis(stream_t *streamptr, int zaxisID) if (type == ZAXIS_REFERENCE) cdfDefZaxisUUID(streamptr, zaxisID); - int dimID; + int dimID = CDI_UNDEFID; if (type == ZAXIS_HYBRID || type == ZAXIS_HYBRID_HALF) { delayed = cdf_def_zaxis_hybrid(streamptr, type, &ncvarid, zaxisID, zaxisindex, xtype, dimlen, &dimID, axisname); @@ -1749,7 +1742,7 @@ cdfDefZaxis(stream_t *streamptr, int zaxisID) { dimID = checkDimName(fileID, dimlen, dimname); - bool switchNCMode = streamptr->ncmode == 2; + bool switchNCMode = (streamptr->ncmode == 2); if (switchNCMode) { streamptr->ncmode = 1; @@ -1848,7 +1841,7 @@ cdf_def_mapping(stream_t *streamptr, int gridID) if (!gmapvarname[0]) strcpy(gmapvarname, "crs"); int fileID = streamptr->fileID; - bool switchNCMode = streamptr->ncmode == 2; + bool switchNCMode = (streamptr->ncmode == 2); if (switchNCMode) { streamptr->ncmode = 1; @@ -1944,14 +1937,11 @@ cdfDefCharacter(stream_t *streamptr, int gridID, int gridIndex, int cdiAxisID, i // Write Var - size_t start[2], count[2]; - start[1] = 0; - count[0] = 1; - count[1] = strlen; + size_t start[2] = { 0, 0 }, count[2] = { 1, strlen }; for (size_t i = 0; i < dimlen; i++) { start[0] = i; - status = nc_put_vara_text(fileID, ncaxisid, start, count, cvals[i]); + (void) nc_put_vara_text(fileID, ncaxisid, start, count, cvals[i]); } ncgrid[gridIndex].gridID = gridID; @@ -1986,7 +1976,7 @@ cdfDefRgrid(stream_t *streamptr, int gridID, int gridIndex) else sprintf(&axisname[5], "%1d", iz + 1); - bool switchNCMode = streamptr->ncmode == 2; + bool switchNCMode = (streamptr->ncmode == 2); if (switchNCMode) { streamptr->ncmode = 1; @@ -2023,7 +2013,7 @@ cdfDefRgrid(stream_t *streamptr, int gridID, int gridIndex) else sprintf(&axisname[14], "%1d", iz + 1); - bool switchNCMode = streamptr->ncmode == 2; + bool switchNCMode = (streamptr->ncmode == 2); if (switchNCMode) { streamptr->ncmode = 1; @@ -2033,12 +2023,9 @@ cdfDefRgrid(stream_t *streamptr, int gridID, int gridIndex) cdf_def_dim(fileID, axisname, dimlen, &dimID); int ncvarid = CDI_UNDEFID; + cdf_def_var(fileID, axisname, NC_INT, 1, &dimID, &ncvarid); - int ndims = 1; - nc_type xtype = NC_INT; - cdf_def_var(fileID, axisname, xtype, ndims, &dimID, &ncvarid); - - if (switchNCMode) + if (switchNCMode || streamptr->ncmode == 1) { cdf_enddef(fileID, streamptr->self); streamptr->ncmode = 2; diff --git a/src/stream_cdf_time.c b/src/stream_cdf_time.c index 602394d383697fa7c7928dcac79f9461acc6a731..84c699535ccd0163f070d455ee97f17c18ccab30 100644 --- a/src/stream_cdf_time.c +++ b/src/stream_cdf_time.c @@ -72,12 +72,12 @@ cdfGetTimeUnits(taxis_t *taxis) } else { - const int year = taxis->rDateTime.date.year; - const int month = taxis->rDateTime.date.month; - const int day = taxis->rDateTime.date.day; - const int hour = taxis->rDateTime.time.hour; - const int minute = taxis->rDateTime.time.minute; - const int second = taxis->rDateTime.time.second; + int year = taxis->rDateTime.date.year; + int month = taxis->rDateTime.date.month; + int day = taxis->rDateTime.date.day; + int hour = taxis->rDateTime.time.hour; + int minute = taxis->rDateTime.time.minute; + int second = taxis->rDateTime.time.second; int timeunit = (taxis->unit != -1) ? taxis->unit : TUNIT_HOUR; if (timeunit == TUNIT_QUARTER) @@ -144,7 +144,7 @@ cdfDefTime(stream_t *streamptr) if (streamptr->basetime.ncvarid != CDI_UNDEFID) return; - const int fileID = streamptr->fileID; + int fileID = streamptr->fileID; if (streamptr->ncmode == 0) streamptr->ncmode = 1; if (streamptr->ncmode == 2) cdf_redef(fileID); @@ -166,8 +166,8 @@ cdfDefTime(stream_t *streamptr) cdf_def_dim(fileID, taxisName, timeDimLen, &timeDimId); streamptr->basetime.ncdimid = timeDimId; - const int datatype = taxis->datatype; - const nc_type xtype = (datatype == CDI_DATATYPE_INT32) ? NC_INT : ((datatype == CDI_DATATYPE_FLT32) ? NC_FLOAT : NC_DOUBLE); + int datatype = taxis->datatype; + nc_type xtype = (datatype == CDI_DATATYPE_INT32) ? NC_INT : ((datatype == CDI_DATATYPE_FLT32) ? NC_FLOAT : NC_DOUBLE); int timeVarId; cdf_def_var(fileID, taxisName, xtype, 1, &timeDimId, &timeVarId); @@ -240,17 +240,17 @@ cdfDefTime(stream_t *streamptr) void cdfDefTimestep(stream_t *streamptr, int tsID, size_t valCount) { - const int time_varid = streamptr->basetime.ncvarid; + int time_varid = streamptr->basetime.ncvarid; if (time_varid != CDI_UNDEFID && tsID == 0) { taxis_t *taxis = taxisPtr(vlistInqTaxis(streamptr->vlistID)); - const int fileID = streamptr->fileID; + int fileID = streamptr->fileID; const char *unitstr = cdfGetTimeUnits(taxis); - const size_t len = strlen(unitstr); + size_t len = strlen(unitstr); if (len) cdf_put_att_text(fileID, time_varid, "units", len, unitstr); } - const int fileID = streamptr->fileID; + int fileID = streamptr->fileID; if (CDI_Debug) Message("streamID = %d, fileID = %d, tsID = %d", streamptr->self, fileID, tsID); diff --git a/src/stream_cgribex.c b/src/stream_cgribex.c index 0d0dde101c555358e8954928f84727325a9e46e1..6e4b533d3cc2cc958dc0f85d7492ac2f9fe9cb70 100644 --- a/src/stream_cgribex.c +++ b/src/stream_cgribex.c @@ -250,12 +250,12 @@ cgribexGetTsteptype(int timerange) static bool cgribexGetGridRegular(int *isec2, int *isec4, grid_t *grid, int gridtype, bool compyinc) { - const bool ijDirectionIncrementGiven = gribbyte_get_bit(ISEC2_ResFlag, 1); - const bool uvRelativeToGrid = gribbyte_get_bit(ISEC2_ResFlag, 5); + bool ijDirectionIncrementGiven = gribbyte_get_bit(ISEC2_ResFlag, 1); + bool uvRelativeToGrid = gribbyte_get_bit(ISEC2_ResFlag, 5); - const size_t nvalues = (size_t) ISEC4_NumValues; - const size_t nlon = (size_t) ISEC2_NumLon; - const size_t nlat = (size_t) ISEC2_NumLat; + size_t nvalues = (size_t) ISEC4_NumValues; + size_t nlon = (size_t) ISEC2_NumLon; + size_t nlat = (size_t) ISEC2_NumLat; if (nvalues != nlon * nlat) Error("numberOfPoints (%zu) and gridSize (%zu) differ!", nvalues, nlon * nlat); grid->size = nvalues; @@ -336,12 +336,16 @@ cgribexGetGridRegular(int *isec2, int *isec4, grid_t *grid, int gridtype, bool c static bool cgribexGetGridReduced(int *isec2, int *isec4, grid_t *grid) { - const bool ijDirectionIncrementGiven = gribbyte_get_bit(ISEC2_ResFlag, 1); - const bool uvRelativeToGrid = gribbyte_get_bit(ISEC2_ResFlag, 5); + bool ijDirectionIncrementGiven = gribbyte_get_bit(ISEC2_ResFlag, 1); + bool uvRelativeToGrid = gribbyte_get_bit(ISEC2_ResFlag, 5); grid->np = ISEC2_NumPar; grid->size = (size_t) ISEC4_NumValues; - grid->reducedPoints = ISEC2_ReducedPointsPtr; - grid->reducedPointsSize = (size_t) ISEC2_NumLat; + + size_t reducedPointsSize = (size_t) ISEC2_NumLat; + grid->reducedPointsSize = reducedPointsSize; + grid->reducedPoints = (int *) Malloc(reducedPointsSize * sizeof(int)); + memcpy(grid->reducedPoints, ISEC2_ReducedPointsPtr, reducedPointsSize * sizeof(int)); + grid->y.size = (size_t) ISEC2_NumLat; grid->x.inc = 0; grid->y.inc = 0; @@ -381,11 +385,11 @@ cgribexGetGridReduced(int *isec2, int *isec4, grid_t *grid) static bool cgribexGetGridLCC(int *isec2, int *isec4, grid_t *grid) { - const bool uvRelativeToGrid = gribbyte_get_bit(ISEC2_ResFlag, 5); + bool uvRelativeToGrid = gribbyte_get_bit(ISEC2_ResFlag, 5); - const size_t nvalues = (size_t) ISEC4_NumValues; - const size_t nlon = (size_t) ISEC2_NumLon; - const size_t nlat = (size_t) ISEC2_NumLat; + size_t nvalues = (size_t) ISEC4_NumValues; + size_t nlon = (size_t) ISEC2_NumLon; + size_t nlat = (size_t) ISEC2_NumLat; if (nvalues != nlon * nlat) Error("numberOfPoints (%zu) and gridSize (%zu) differ!", nvalues, nlon * nlat); grid->size = nvalues; @@ -492,7 +496,7 @@ cgribexDefProjLCC(int *isec2, int gridID) struct CDI_GridProjParams gpp; gridProjParamsInit(&gpp); - const bool earthIsOblate = gribbyte_get_bit(ISEC2_ResFlag, 2); + bool earthIsOblate = gribbyte_get_bit(ISEC2_ResFlag, 2); if (earthIsOblate) { gpp.a = 6378160.0; @@ -509,7 +513,7 @@ cgribexDefProjLCC(int *isec2, int gridID) gpp.lon_0 = ISEC2_Lambert_Lov * 0.001; gpp.lat_1 = ISEC2_Lambert_LatS1 * 0.001; gpp.lat_2 = ISEC2_Lambert_LatS2 * 0.001; - const bool lsouth = gribbyte_get_bit(ISEC2_Lambert_ProjFlag, 1); + bool lsouth = gribbyte_get_bit(ISEC2_Lambert_ProjFlag, 1); if (lsouth) { gpp.lat_1 = -gpp.lat_1; @@ -546,12 +550,12 @@ cgribexAddRecord(stream_t *streamptr, cgribexrec_t *cgribexp, int param, size_t if (datatype > 32) datatype = CDI_DATATYPE_PACK32; if (datatype < 0) datatype = CDI_DATATYPE_PACK; - const int vlistID = streamptr->vlistID; - const int tsID = streamptr->curTsID; - const int recID = recordNewEntry(streamptr, tsID); + int vlistID = streamptr->vlistID; + int tsID = streamptr->curTsID; + int recID = recordNewEntry(streamptr, tsID); record_t *record = &streamptr->tsteps[tsID].records[recID]; - const int tsteptype = cgribexGetTsteptype(ISEC1_TimeRange); + int tsteptype = cgribexGetTsteptype(ISEC1_TimeRange); int leveltype, level1, level2; cgribexGetLevel(isec1, &leveltype, &level1, &level2); @@ -567,46 +571,36 @@ cgribexAddRecord(stream_t *streamptr, cgribexrec_t *cgribexp, int param, size_t record->tsteptype = (short) tsteptype; grid_t *gridptr = (grid_t *) Malloc(sizeof(*gridptr)); - const bool uvRelativeToGrid = cgribexGetGrid(streamptr, isec2, isec4, gridptr, iret); + bool uvRelativeToGrid = cgribexGetGrid(streamptr, isec2, isec4, gridptr, iret); struct addIfNewRes gridAdded = cdiVlistAddGridIfNew(vlistID, gridptr, 0); int gridID = gridAdded.Id; - if (gridAdded.isNew) - { - if (gridptr->reducedPointsSize) - { - const size_t reducedPointsSize = (size_t) gridptr->reducedPointsSize; - int *reducedPoints = gridptr->reducedPoints; - gridptr->reducedPoints = (int *) Malloc(reducedPointsSize * sizeof(int)); - memcpy(gridptr->reducedPoints, reducedPoints, reducedPointsSize * sizeof(int)); - } - else if (gridptr->projtype == CDI_PROJ_RLL) - { - const double xpole = ISEC2_LonSP * 0.001 - 180; - const double ypole = -ISEC2_LatSP * 0.001; - const double angle = -FSEC2_RotAngle; - gridDefParamRLL(gridID, xpole, ypole, angle); - } - else if (gridptr->projtype == CDI_PROJ_LCC) - { - cgribexDefProjLCC(isec2, gridID); - } - } - else + if (!gridAdded.isNew) { grid_free(gridptr); Free(gridptr); } + else if (gridptr->projtype == CDI_PROJ_RLL) + { + double xpole = ISEC2_LonSP * 0.001 - 180; + double ypole = -ISEC2_LatSP * 0.001; + double angle = -FSEC2_RotAngle; + gridDefParamRLL(gridID, xpole, ypole, angle); + } + else if (gridptr->projtype == CDI_PROJ_LCC) + { + cgribexDefProjLCC(isec2, gridID); + } - const int zaxistype = grib1ltypeToZaxisType(leveltype); + int zaxistype = grib1ltypeToZaxisType(leveltype); if (zaxistype == ZAXIS_HYBRID || zaxistype == ZAXIS_HYBRID_HALF) { - const size_t vctsize = (size_t) ISEC2_NumVCP; + size_t vctsize = (size_t) ISEC2_NumVCP; double *vctptr = &fsec2[10]; varDefVCT(vctsize, vctptr); } - const bool lbounds = cgribexGetZaxisHasBounds(leveltype); + bool lbounds = cgribexGetZaxisHasBounds(leveltype); int varID = 0, levelID = 0; varAddRecord(recID, param, gridID, zaxistype, lbounds, level1, level2, 0, 0, datatype, &varID, &levelID, tsteptype, leveltype, -1, @@ -639,8 +633,8 @@ cgribexAddRecord(stream_t *streamptr, cgribexrec_t *cgribexp, int param, size_t if (varInqInst(varID) == CDI_UNDEFID) { - const int center = ISEC1_CenterID; - const int subcenter = ISEC1_SubCenterID; + int center = ISEC1_CenterID; + int subcenter = ISEC1_SubCenterID; int instID = institutInq(center, subcenter, NULL, NULL); if (instID == CDI_UNDEFID) instID = institutDef(center, subcenter, NULL, NULL); varDefInst(varID, instID); @@ -734,13 +728,14 @@ cgribexVarSet(int param, int level1, int level2, int leveltype, int trange) } static inline int -cgribexVarCompare(compvar_t compVar, record_t record, int flag) +cgribexVarCompare(const compvar_t *compVar, const record_t *record, int flag) { - bool vinst = compVar.tsteptype == TSTEP_INSTANT || compVar.tsteptype == TSTEP_INSTANT2 || compVar.tsteptype == TSTEP_INSTANT3; - bool rinst = record.tsteptype == TSTEP_INSTANT || record.tsteptype == TSTEP_INSTANT2 || record.tsteptype == TSTEP_INSTANT3; - int tstepDiff = (!((flag == 0) & (vinst && rinst))) & (compVar.tsteptype != record.tsteptype); - int rstatus = (compVar.param != record.param) | (compVar.level1 != record.ilevel) | (compVar.level2 != record.ilevel2) - | (compVar.ltype != record.ltype) | tstepDiff; + bool vinst + = (compVar->tsteptype == TSTEP_INSTANT || compVar->tsteptype == TSTEP_INSTANT2 || compVar->tsteptype == TSTEP_INSTANT3); + bool rinst = (record->tsteptype == TSTEP_INSTANT || record->tsteptype == TSTEP_INSTANT2 || record->tsteptype == TSTEP_INSTANT3); + int tstepDiff = (!((flag == 0) & (vinst && rinst))) & (compVar->tsteptype != record->tsteptype); + int rstatus = (compVar->param != record->param) | (compVar->level1 != record->ilevel) | (compVar->level2 != record->ilevel2) + | (compVar->ltype != record->ltype) | tstepDiff; return rstatus; } @@ -748,15 +743,15 @@ cgribexVarCompare(compvar_t compVar, record_t record, int flag) Warning("Record %2d (id=%s lev1=%d lev2=%d) timestep %d: %s", nrecs, paramstr, level1, level2, timestep, text) static void -cgribexSkipRecords(const int fileID) +cgribexSkipRecords(int fileID) { int nskip = CDI_Skip_Records; while (nskip-- > 0) { - const size_t recsize = gribGetSize(fileID); + size_t recsize = gribGetSize(fileID); if (recsize == 0) Error("Skipping of %d records failed!", CDI_Skip_Records); - const off_t recpos = fileGetPos(fileID); + off_t recpos = fileGetPos(fileID); fileSetPos(fileID, recpos, SEEK_CUR); } } @@ -794,19 +789,19 @@ cgribexScanTimestep1(stream_t *streamptr) cgribexrec_t *cgribexp = (cgribexrec_t *) streamptr->record->objectp; - const int tsID = tstepsNewEntry(streamptr); + int tsID = tstepsNewEntry(streamptr); if (tsID != 0) Error("Internal problem! tstepsNewEntry returns %d", tsID); taxis_t *taxis = &streamptr->tsteps[tsID].taxis; - const int fileID = streamptr->fileID; + int fileID = streamptr->fileID; if (CDI_Skip_Records) cgribexSkipRecords(fileID); unsigned nrecs = 0; while (true) { - const size_t recsize = gribGetSize(fileID); + size_t recsize = gribGetSize(fileID); recpos = fileGetPos(fileID); if (recsize == 0) @@ -822,9 +817,9 @@ cgribexScanTimestep1(stream_t *streamptr) // Search for next 'GRIB', read the following record, and position file offset after it. if (gribRead(fileID, gribbuffer, &readsize)) break; - const int comptype = grbDecompress(recsize, &buffersize, &gribbuffer); + int comptype = grbDecompress(recsize, &buffersize, &gribbuffer); - const size_t sec2len = cgribexSection2Length(gribbuffer, buffersize); + size_t sec2len = cgribexSection2Length(gribbuffer, buffersize); if (sec2len > cgribexp->sec2len) { cgribexp->sec2len = sec2len; @@ -836,13 +831,13 @@ cgribexScanTimestep1(stream_t *streamptr) nrecsScanned++; cgribexDecodeHeader(cgribexp, (int *) gribbuffer, (int) recsize, &lmv, &iret); - const int param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255); + int param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255); cdiParamToString(param, paramstr, sizeof(paramstr)); cgribexGetLevel(isec1, &leveltype, &level1, &level2); CdiDateTime sDateTime; - const CdiDateTime vDateTime = cgribexDateTimeX(isec1, &sDateTime); + CdiDateTime vDateTime = cgribexDateTimeX(isec1, &sDateTime); if (nrecs == 0) { @@ -861,7 +856,7 @@ cgribexScanTimestep1(stream_t *streamptr) record_t *records = streamptr->tsteps[tsID].records; for (recID = 0; recID < nrecs; recID++) { - if (cgribexVarCompare(compVar, records[recID], 0) == 0) break; + if (cgribexVarCompare(&compVar, &records[recID], 0) == 0) break; } if (CDI_Inventory_Mode == 1) @@ -915,9 +910,9 @@ cgribexScanTimestep1(stream_t *streamptr) cdi_generate_vars(streamptr); taxis->type = fcast ? TAXIS_RELATIVE : TAXIS_ABSOLUTE; - const int taxisID = taxisCreate(taxis->type); + int taxisID = taxisCreate(taxis->type); - const int vlistID = streamptr->vlistID; + int vlistID = streamptr->vlistID; vlistDefTaxis(vlistID, taxisID); streamScanResizeRecords1(streamptr); @@ -949,8 +944,8 @@ cgribexScanTimestep2(stream_t *streamptr) int *isec1 = cgribexp->sec1; int *isec2 = cgribexp->sec2; - const int fileID = streamptr->fileID; - const int vlistID = streamptr->vlistID; + int fileID = streamptr->fileID; + int vlistID = streamptr->vlistID; void *gribbuffer = streamptr->record->buffer; size_t buffersize = streamptr->record->buffersize; @@ -965,7 +960,7 @@ cgribexScanTimestep2(stream_t *streamptr) cdi_create_records(streamptr, tsID); record_t *records = streamptr->tsteps[tsID].records; - const int nrecords = streamScanInitRecords2(streamptr); + int nrecords = streamScanInitRecords2(streamptr); int nrecsScanned = nrecords; int rindex = 0; @@ -973,7 +968,7 @@ cgribexScanTimestep2(stream_t *streamptr) { if (rindex > nrecords) break; - const size_t recsize = gribGetSize(fileID); + size_t recsize = gribGetSize(fileID); recpos = fileGetPos(fileID); if (recsize == 0) { @@ -991,18 +986,18 @@ cgribexScanTimestep2(stream_t *streamptr) nrecsScanned++; cgribexDecodeHeader(cgribexp, (int *) gribbuffer, (int) recsize, &lmv, &iret); - const int param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255); + int param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255); cdiParamToString(param, paramstr, sizeof(paramstr)); cgribexGetLevel(isec1, &leveltype, &level1, &level2); CdiDateTime sDateTime; - const CdiDateTime vDateTime = cgribexDateTimeX(isec1, &sDateTime); + CdiDateTime vDateTime = cgribexDateTimeX(isec1, &sDateTime); if (rindex == 0) { vDateTime0 = vDateTime; - const int taxisID = vlistInqTaxis(vlistID); + int taxisID = vlistInqTaxis(vlistID); if (taxisInqType(taxisID) == TAXIS_RELATIVE) { taxis->type = TAXIS_RELATIVE; @@ -1021,7 +1016,7 @@ cgribexScanTimestep2(stream_t *streamptr) if (cdiDateTime_isLT(sDateTime, taxis->sDateTime)) taxis->sDateTime = sDateTime; } - const int tsteptype = cgribexGetTsteptype(ISEC1_TimeRange); + int tsteptype = cgribexGetTsteptype(ISEC1_TimeRange); if (ISEC1_AvgNum) { @@ -1035,7 +1030,7 @@ cgribexScanTimestep2(stream_t *streamptr) for (recID = 0; recID < nrecords; recID++) { - if (cgribexVarCompare(compVar, records[recID], 0) == 0) break; + if (cgribexVarCompare(&compVar, &records[recID], 0) == 0) break; } if (recID == nrecords) @@ -1076,7 +1071,7 @@ cgribexScanTimestep2(stream_t *streamptr) Message("Read record %2d (id=%s lev1=%d lev2=%d) %s", nrecsScanned, paramstr, level1, level2, CdiDateTime_string(vDateTime)); - if (cgribexVarCompare(compVar, streamptr->tsteps[tsID].records[recID], 0) != 0) + if (cgribexVarCompare(&compVar, &streamptr->tsteps[tsID].records[recID], 0) != 0) { Message("tsID = %d recID = %d param = %3d new %3d level = %3d new %3d", tsID, recID, records[recID].param, param, records[recID].ilevel, level1); @@ -1086,8 +1081,8 @@ cgribexScanTimestep2(stream_t *streamptr) records[recID].position = recpos; records[recID].size = recsize; - const int varID = records[recID].varID; - const int gridID = vlistInqVarGrid(vlistID, varID); + int varID = records[recID].varID; + int gridID = vlistInqVarGrid(vlistID, varID); if (gridInqSize(gridID) == 1 && gridInqType(gridID) == GRID_LONLAT) { if (IS_NOT_EQUAL(gridInqXval(gridID, 0), ISEC2_FirstLon * 0.001) @@ -1150,7 +1145,7 @@ cgribexScanTimestep(stream_t *streamptr) nrecs = streamScanInitRecords(streamptr, tsID); - const int fileID = streamptr->fileID; + int fileID = streamptr->fileID; fileSetPos(fileID, streamptr->tsteps[tsID].position, SEEK_SET); @@ -1160,7 +1155,7 @@ cgribexScanTimestep(stream_t *streamptr) { if (rindex > nrecs) break; - const size_t recsize = gribGetSize(fileID); + size_t recsize = gribGetSize(fileID); recpos = fileGetPos(fileID); if (recsize == 0) { @@ -1182,21 +1177,21 @@ cgribexScanTimestep(stream_t *streamptr) nrecsScanned++; cgribexDecodeHeader(cgribexp, (int *) gribbuffer, (int) recsize, &lmv, &iret); - const int param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255); + int param = cdiEncodeParam(ISEC1_Parameter, ISEC1_CodeTable, 255); cdiParamToString(param, paramstr, sizeof(paramstr)); cgribexGetLevel(isec1, &leveltype, &level1, &level2); CdiDateTime sDateTime; - const CdiDateTime vDateTime = cgribexDateTimeX(isec1, &sDateTime); + CdiDateTime vDateTime = cgribexDateTimeX(isec1, &sDateTime); if (rindex == nrecs) break; if (rindex == 0) { vDateTime0 = vDateTime; - const int vlistID = streamptr->vlistID; - const int taxisID = vlistInqTaxis(vlistID); + int vlistID = streamptr->vlistID; + int taxisID = vlistInqTaxis(vlistID); if (taxisInqType(taxisID) == TAXIS_RELATIVE) { taxis->type = TAXIS_RELATIVE; @@ -1228,7 +1223,7 @@ cgribexScanTimestep(stream_t *streamptr) for (vrecID = 0; vrecID < nrecs; vrecID++) { recID = streamptr->tsteps[1].recIDs[vrecID]; - if (cgribexVarCompare(compVar, records[recID], 0) == 0) break; + if (cgribexVarCompare(&compVar, &records[recID], 0) == 0) break; } if (vrecID == nrecs) @@ -1271,7 +1266,7 @@ cgribexScanTimestep(stream_t *streamptr) Message("Read record %2d (id=%s lev1=%d lev2=%d) %s", nrecsScanned, paramstr, level1, level2, CdiDateTime_string(vDateTime)); - if (cgribexVarCompare(compVar, records[recID], 0) != 0) + if (cgribexVarCompare(&compVar, &records[recID], 0) != 0) { Message("tsID = %d recID = %d param = %3d new %3d level = %3d new %3d", tsID, recID, records[recID].param, param, records[recID].ilevel, level1); @@ -1447,13 +1442,13 @@ cgribexDefTimerange(int tsteptype, int factor, int calendar, CdiDateTime rDateTi { JulianDate julianDate1 = julianDate_encode(calendar, rDateTime); JulianDate julianDate2 = julianDate_encode(calendar, vDateTime); - const JulianDate julianDate = julianDate_sub(julianDate2, julianDate1); + JulianDate julianDate = julianDate_sub(julianDate2, julianDate1); int timerange = -1; int ip1 = 0, ip2 = 0; if (!(int) (fmod(julianDate_to_seconds(julianDate), factor))) { - const int ip = (int) lround(julianDate_to_seconds(julianDate) / factor); + int ip = (int) lround(julianDate_to_seconds(julianDate) / factor); if ((ip > 255) && (tsteptype == TSTEP_INSTANT)) tsteptype = TSTEP_INSTANT3; int ipx = 0; @@ -1493,7 +1488,6 @@ cgribexDefDateTime(int *isec1, int timeunit, CdiDateTime dt) cdiTime_decode(dt.time, &hour, &minute, &second, &ms); int century = year / 100; - ISEC1_Year = year - century * 100; if (year < 0) @@ -1551,7 +1545,8 @@ cgribexDefTime(int *isec1, CdiDateTime vDateTime, int tsteptype, int numavg, int if (timetype == TAXIS_RELATIVE) { - const int calendar = taxisInqCalendar(taxisID); + int ip1 = 0, ip2 = 0; + int calendar = taxisInqCalendar(taxisID); CdiDateTime rDateTime = taxisInqRdatetime(taxisID); if (cdiDateTime_isLT(vDateTime, rDateTime)) rDateTime = vDateTime; @@ -1559,22 +1554,28 @@ cgribexDefTime(int *isec1, CdiDateTime vDateTime, int tsteptype, int numavg, int CdiDateTime sDateTime = taxisInqSdatetime(taxisID); int factor = cgribexDefDateTime(isec1, timeunit, rDateTime); - int ip1 = 0, ip2 = 0; int timerange = cgribexDefTimerange(tsteptype, factor, calendar, rDateTime, vDateTime, sDateTime, &ip1, &ip2); + if (ip2 > 0xFF) + { + rDateTime = vDateTime; + factor = cgribexDefDateTime(isec1, timeunit, rDateTime); + timerange = cgribexDefTimerange(tsteptype, factor, calendar, rDateTime, vDateTime, sDateTime, &ip1, &ip2); + } + /* if (ip2 > 0xFF && timeunit < TUNIT_YEAR) { timeunit++; factor = cgribexDefDateTime(isec1, timeunit, rDateTime); timerange = cgribexDefTimerange(tsteptype, factor, calendar, rDateTime, vDateTime, sDateTime, &ip1, &ip2); } - + */ if (timerange == -1 || timerange == 1 || timerange == 3) timetype = TAXIS_ABSOLUTE; /* - else if ( timerange == 10 ) + else if (timerange == 10) { - if ( ip1 < 0 || ip1 > 0xFFFF ) timetype = TAXIS_ABSOLUTE; - if ( ip2 < 0 || ip2 > 0xFFFF ) timetype = TAXIS_ABSOLUTE; + if (ip1 < 0 || ip1 > 0xFFFF) timetype = TAXIS_ABSOLUTE; + if (ip2 < 0 || ip2 > 0xFFFF) timetype = TAXIS_ABSOLUTE; } */ else @@ -1582,17 +1583,13 @@ cgribexDefTime(int *isec1, CdiDateTime vDateTime, int tsteptype, int numavg, int if (ip1 < 0 || ip1 > 0xFF) timetype = TAXIS_ABSOLUTE; if (ip2 < 0 || ip2 > 0xFF) timetype = TAXIS_ABSOLUTE; } - /* - static bool lwarn = true; - if ( lwarn && timetype == TAXIS_ABSOLUTE ) + + if (timetype != TAXIS_ABSOLUTE) { - lwarn = false; - Warning("Can't store forecast time %d %d relative to %d %d, converted to absolute time!", vdate, vtime, rdate, rtime); + ISEC1_TimeRange = timerange; + ISEC1_TimePeriod1 = ip1; + ISEC1_TimePeriod2 = ip2; } - */ - ISEC1_TimeRange = timerange; - ISEC1_TimePeriod1 = ip1; - ISEC1_TimePeriod2 = ip2; } if (timetype == TAXIS_ABSOLUTE) @@ -1600,7 +1597,7 @@ cgribexDefTime(int *isec1, CdiDateTime vDateTime, int tsteptype, int numavg, int (void) cgribexDefDateTime(isec1, timeunit, vDateTime); /* - if ( numavg > 0 ) + if (numavg > 0) ISEC1_TimeRange = 0; else */ @@ -1718,8 +1715,8 @@ cgribexDefGridRegular(int *isec2, double *fsec2, int gridID, int gridtype, bool static void cgribexDefGridLambert(int *isec2, int gridID, int uvRelativeToGrid) { - const int xsize = (int) gridInqXsize(gridID); - const int ysize = (int) gridInqYsize(gridID); + int xsize = (int) gridInqXsize(gridID); + int ysize = (int) gridInqYsize(gridID); struct CDI_GridProjParams gpp; gridInqParamsLCC(gridID, &gpp); @@ -1730,7 +1727,7 @@ cgribexDefGridLambert(int *isec2, int gridID, int uvRelativeToGrid) } gridVerifyProjParamsLCC(&gpp); - const bool lsouth = (gpp.lat_1 < 0); + bool lsouth = (gpp.lat_1 < 0); if (lsouth) { gpp.lat_1 = -gpp.lat_2; @@ -1757,7 +1754,7 @@ cgribexDefGridLambert(int *isec2, int gridID, int uvRelativeToGrid) ISEC2_Lambert_ProjFlag = 0; if (lsouth) gribbyte_set_bit(&ISEC2_Lambert_ProjFlag, 1); - const bool earthIsOblate = (IS_EQUAL(gpp.a, 6378160.0) && IS_EQUAL(gpp.rf, 297.0)); + bool earthIsOblate = (IS_EQUAL(gpp.a, 6378160.0) && IS_EQUAL(gpp.rf, 297.0)); ISEC2_ResFlag = 0; if (ISEC2_Lambert_dx && ISEC2_Lambert_dy) gribbyte_set_bit(&ISEC2_ResFlag, 1); if (earthIsOblate) gribbyte_set_bit(&ISEC2_ResFlag, 2); @@ -1818,10 +1815,10 @@ cgribexDefGrid(int *isec1, int *isec2, double *fsec2, int *isec4, int gridID, in ISEC2_Reduced = false; ISEC2_ScanFlag = 0; - const int gridsize = (int) gridInqSize(gridID); + int gridsize = (int) gridInqSize(gridID); bool gridIsRotated = false; bool gridIsCurvilinear = false; - const int gridtype = grbGetGridtype(&gridID, gridsize, &gridIsRotated, &gridIsCurvilinear); + int gridtype = grbGetGridtype(&gridID, gridsize, &gridIsRotated, &gridIsCurvilinear); switch (gridtype) { @@ -1885,10 +1882,10 @@ cgribexDefLevel(int *isec1, int *isec2, double *fsec2, int zaxisID, int levelID) int ltype = 0; cdiInqKeyInt(zaxisID, CDI_GLOBAL, CDI_KEY_TYPEOFFIRSTFIXEDSURFACE, <ype); - const bool hasBounds = (zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL)); + bool hasBounds = (zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL)); double level = zaxisInqLevels(zaxisID, NULL) ? zaxisInqLevel(zaxisID, levelID) : levelID + 1; - const double dlevel1 = hasBounds ? zaxisInqLbound(zaxisID, levelID) : level; - const double dlevel2 = hasBounds ? zaxisInqUbound(zaxisID, levelID) : 0.0; + double dlevel1 = hasBounds ? zaxisInqLbound(zaxisID, levelID) : level; + double dlevel2 = hasBounds ? zaxisInqUbound(zaxisID, levelID) : 0.0; if (zaxistype == ZAXIS_GENERIC && ltype == 0) { @@ -2027,9 +2024,9 @@ cgribexDefEnsembleVar(int *isec1, int vlistID, int varID) // Put2Byte(isec1[39]); // number of forecasts in ensemble int perturbationNumber, numberOfForecastsInEnsemble, typeOfEnsembleForecast; - const int r1 = cdiInqKeyInt(vlistID, varID, CDI_KEY_PERTURBATIONNUMBER, &perturbationNumber); - const int r2 = cdiInqKeyInt(vlistID, varID, CDI_KEY_NUMBEROFFORECASTSINENSEMBLE, &numberOfForecastsInEnsemble); - const int r3 = cdiInqKeyInt(vlistID, varID, CDI_KEY_TYPEOFENSEMBLEFORECAST, &typeOfEnsembleForecast); + int r1 = cdiInqKeyInt(vlistID, varID, CDI_KEY_PERTURBATIONNUMBER, &perturbationNumber); + int r2 = cdiInqKeyInt(vlistID, varID, CDI_KEY_NUMBEROFFORECASTSINENSEMBLE, &numberOfForecastsInEnsemble); + int r3 = cdiInqKeyInt(vlistID, varID, CDI_KEY_TYPEOFENSEMBLEFORECAST, &typeOfEnsembleForecast); if (r1 == 0 && r2 == 0 && r3 == 0) { @@ -2050,7 +2047,7 @@ cgribexEncode(int memtype, int varID, int levelID, int vlistID, int gridID, int { cgribexrec_t *cgribexp = (cgribexrec_t *) cgribexNew(); - const size_t sec2len = 1024 + 2 * gridInqYsize(gridID); // Gaussian reduced grid + size_t sec2len = 1024 + 2 * gridInqYsize(gridID); // Gaussian reduced grid if (sec2len > cgribexp->sec2len) { cgribexp->sec2len = sec2len; @@ -2073,8 +2070,8 @@ cgribexEncode(int memtype, int varID, int levelID, int vlistID, int gridID, int fsec2f[0] = 0; fsec2f[1] = 0; - const int gribsize = (int) (gribbuffersize / sizeof(int)); - const int param = vlistInqVarParam(vlistID, varID); + int gribsize = (int) (gribbuffersize / sizeof(int)); + int param = vlistInqVarParam(vlistID, varID); cgribexDefaultSec0(isec0); cgribexDefaultSec1(isec1); @@ -2083,7 +2080,7 @@ cgribexEncode(int memtype, int varID, int levelID, int vlistID, int gridID, int cgribexDefInstitut(isec1, vlistID, varID); cgribexDefModel(isec1, vlistID, varID); - const int datatype = vlistInqVarDatatype(vlistID, varID); + int datatype = vlistInqVarDatatype(vlistID, varID); int uvRelativeToGrid = -1; cdiInqKeyInt(vlistID, varID, CDI_KEY_UVRELATIVETOGRID, &uvRelativeToGrid); @@ -2136,7 +2133,7 @@ cgribexEncode(int memtype, int varID, int levelID, int vlistID, int gridID, int if (iret) Error("Problem during GRIB encode (errno = %d)!", iret); - const size_t nbytes = (size_t) iword * sizeof(int); + size_t nbytes = (size_t) iword * sizeof(int); return nbytes; } diff --git a/src/stream_grb.c b/src/stream_grb.c index 616ec15b5651a7afcf78906820364ef957c20aaa..09d664f5cdead9985a670786afd0d29cd3376bf8 100644 --- a/src/stream_grb.c +++ b/src/stream_grb.c @@ -32,8 +32,8 @@ zaxis_units_to_centimeter(int zaxisID) if (units[1] == 'm' && !units[2]) { if (units[0] == 'm') sf = 0.1; - else if (units[0] == 'c') sf = 1; - else if (units[0] == 'd') sf = 10; + else if (units[0] == 'c') sf = 1.0; + else if (units[0] == 'd') sf = 10.0; } // clang-format on @@ -64,11 +64,11 @@ zaxis_units_to_meter(int zaxisID) bool zaxis_units_is_Pa(int zaxisID) { - char units[CDI_MAX_NAME]; + char units[CDI_MAX_NAME] = { 0 }; int length = CDI_MAX_NAME; cdiInqKeyString(zaxisID, CDI_GLOBAL, CDI_KEY_UNITS, units, &length); - return (units[0] && (units[0] == 'P') && (units[1] == 'a')); + return (units[0] == 'P' && units[1] == 'a'); } void @@ -90,7 +90,7 @@ grbDecompress(size_t recsize, size_t *buffersize, void **gribbuffer) if (gribGetZip(recsize, (unsigned char *) *gribbuffer, &unzipsize) > 0) { comptype = CDI_COMPRESS_SZIP; - unzipsize += 100; /* need 0 to 1 bytes for rounding of bds */ + unzipsize += 100; // need 0 to 1 bytes for rounding of bds ensureBufferSize(unzipsize, buffersize, gribbuffer); } @@ -273,7 +273,7 @@ grbScanTimestep1(stream_t *streamptr) int status = CDI_EUFTYPE; #ifdef HAVE_LIBCGRIBEX - const int filetype = streamptr->filetype; + int filetype = streamptr->filetype; if (filetype == CDI_FILETYPE_GRB && !CDI_gribapi_grib1) status = cgribexScanTimestep1(streamptr); @@ -294,7 +294,7 @@ grbScanTimestep2(stream_t *streamptr) int status = CDI_EUFTYPE; #ifdef HAVE_LIBCGRIBEX - const int filetype = streamptr->filetype; + int filetype = streamptr->filetype; if (filetype == CDI_FILETYPE_GRB && !CDI_gribapi_grib1) status = cgribexScanTimestep2(streamptr); @@ -315,7 +315,7 @@ grbScanTimestep(stream_t *streamptr) int status = CDI_EUFTYPE; #ifdef HAVE_LIBCGRIBEX - const int filetype = streamptr->filetype; + int filetype = streamptr->filetype; if (filetype == CDI_FILETYPE_GRB && !CDI_gribapi_grib1) status = cgribexScanTimestep(streamptr); @@ -339,7 +339,7 @@ grbInqContents(stream_t *streamptr) int status = grbScanTimestep1(streamptr); if (status == 0 && streamptr->ntsteps == -1) status = grbScanTimestep2(streamptr); - const int fileID = streamptr->fileID; + int fileID = streamptr->fileID; fileSetPos(fileID, 0, SEEK_SET); return status; diff --git a/src/stream_gribapi.c b/src/stream_gribapi.c index f880196d55d19b2030c289ad328fdb69ef0d160b..d236779b4394ac977b14f86bb632952494efa8da 100644 --- a/src/stream_gribapi.c +++ b/src/stream_gribapi.c @@ -870,31 +870,31 @@ gribapiVarSet(int param, int level1, int level2, int leveltype, int tsteptype, s } static int -gribapiVarCompare(compvar2_t compVar, record_t record, int flag) +gribapiVarCompare(const compvar2_t *compVar, const record_t *record, int flag) { compvar2_t compVar0; memset(&compVar0, 0, sizeof(compvar2_t)); - compVar0.param = record.param; - compVar0.level1 = record.ilevel; - compVar0.level2 = record.ilevel2; - compVar0.ltype = record.ltype; - compVar0.tsteptype = record.tsteptype; - compVar0.gridsize = record.gridsize; - memcpy(compVar0.name, record.varname, sizeof(compVar.name)); + compVar0.param = record->param; + compVar0.level1 = record->ilevel; + compVar0.level2 = record->ilevel2; + compVar0.ltype = record->ltype; + compVar0.tsteptype = record->tsteptype; + compVar0.gridsize = record->gridsize; + memcpy(compVar0.name, record->varname, sizeof(compVar->name)); if (flag == 0) { - if (compVar0.tsteptype == TSTEP_INSTANT && compVar.tsteptype == TSTEP_INSTANT3) compVar0.tsteptype = TSTEP_INSTANT3; - if (compVar0.tsteptype == TSTEP_INSTANT3 && compVar.tsteptype == TSTEP_INSTANT) compVar0.tsteptype = TSTEP_INSTANT; + if (compVar0.tsteptype == TSTEP_INSTANT && compVar->tsteptype == TSTEP_INSTANT3) compVar0.tsteptype = TSTEP_INSTANT3; + if (compVar0.tsteptype == TSTEP_INSTANT3 && compVar->tsteptype == TSTEP_INSTANT) compVar0.tsteptype = TSTEP_INSTANT; } - compVar0.scanKeys = record.scanKeys; - compVar0.tiles = record.tiles; + compVar0.scanKeys = record->scanKeys; + compVar0.tiles = record->tiles; // printf("var1: level1=%d level2=%d\n", compVar.level1, compVar.level2); // printf("var2: level1=%d level2=%d\n", compVar0.level1, compVar0.level2); - return memcmp(&compVar0, &compVar, sizeof(compvar2_t)); + return memcmp(&compVar0, compVar, sizeof(compvar2_t)); } static grib_handle * @@ -952,13 +952,13 @@ typedef enum } checkTimeResult; static checkTimeResult -checkTime(stream_t *streamptr, compvar2_t compVar, CdiDateTime verificationTime, CdiDateTime expectedVTime) +checkTime(stream_t *streamptr, const compvar2_t *compVar, CdiDateTime verificationTime, CdiDateTime expectedVTime) { // First determine whether the current record exists already. int recID = 0; for (; recID < streamptr->nrecs; recID++) { - if (gribapiVarCompare(compVar, streamptr->tsteps[0].records[recID], 1) == 0) break; + if (gribapiVarCompare(compVar, &streamptr->tsteps[0].records[recID], 1) == 0) break; } bool recordExists = (recID < streamptr->nrecs); @@ -1251,9 +1251,8 @@ gribapiScanTimestep1(stream_t *streamptr) int tsteptype = gribapiGetTsteptype(gh); size_t gridsize = gribapiGetGridsize(gh); - checkTimeResult result = checkTime( - streamptr, gribapiVarSet(param, level1, level2, leveltype1, tsteptype, gridsize, varname, scanKeys, tiles), vDateTime, - vDateTime0); + compvar2_t compVar = gribapiVarSet(param, level1, level2, leveltype1, tsteptype, gridsize, varname, scanKeys, tiles); + checkTimeResult result = checkTime(streamptr, &compVar, vDateTime, vDateTime0); if (result == CHECKTIME_STOP) { nrecsScanned--; @@ -1420,7 +1419,7 @@ gribapiScanTimestep2(stream_t *streamptr) compvar2_t compVar = gribapiVarSet(param, level1, level2, leveltype1, tsteptype, gridsize, varname, scanKeys, tiles); for (recID = 0; recID < nrecords; recID++) - if (gribapiVarCompare(compVar, records[recID], 0) == 0) break; + if (gribapiVarCompare(&compVar, &records[recID], 0) == 0) break; if (recID == nrecords) { @@ -1460,7 +1459,7 @@ gribapiScanTimestep2(stream_t *streamptr) paramstr, leveltype1, level1, level2, CdiDateTime_string(vDateTime)); } - if (gribapiVarCompare(compVar, records[recID], 0) != 0) + if (gribapiVarCompare(&compVar, &records[recID], 0) != 0) { Message("tsID = %d recID = %d param = %3d new %3d level = %3d new %3d", tsID, recID, records[recID].param, param, records[recID].ilevel, level1); @@ -1602,7 +1601,7 @@ gribapiScanTimestep(stream_t *streamptr) for (vrecID = 0; vrecID < nrecs; vrecID++) { recID = streamptr->tsteps[1].recIDs[vrecID]; - if (gribapiVarCompare(compVar, records[recID], 0) == 0) break; + if (gribapiVarCompare(&compVar, &records[recID], 0) == 0) break; } if (vrecID == nrecs) @@ -1639,7 +1638,7 @@ gribapiScanTimestep(stream_t *streamptr) if (CDI_Debug) Message("%4d %8lld %4d %8d %8s", rindex + 1, (long long) recpos, param, level1, CdiDateTime_string(vDateTime)); - if (gribapiVarCompare(compVar, records[recID], 0) != 0) + if (gribapiVarCompare(&compVar, &records[recID], 0) != 0) { Message("tsID = %d recID = %d param = %3d new %3d level = %3d new %3d", tsID, recID, records[recID].param, param, records[recID].ilevel, level1); @@ -1702,7 +1701,8 @@ gribapiScanTimestep(stream_t *streamptr) #endif int -gribapiDecode(void *gribbuffer, size_t gribsize, void *data, size_t gridsize, int unreduced, size_t *nmiss, double missval) +gribapiDecode(int memType, void *gribbuffer, size_t gribsize, void *data, size_t gridsize, int unreduced, size_t *nmiss, + double missval) { int status = 0; @@ -1729,7 +1729,16 @@ gribapiDecode(void *gribbuffer, size_t gribsize, void *data, size_t gridsize, in if (gridsize != datasize) Error("Internal problem: gridsize(%zu) != datasize(%zu)!", gridsize, datasize); size_t dummy = datasize; - GRIB_CHECK(grib_get_double_array(gh, "values", (double *) data, &dummy), 0); + if (memType == MEMTYPE_FLOAT) + { +#ifdef HAVE_GRIBAPI_FLOAT_INTERFACE + GRIB_CHECK(grib_get_float_array(gh, "values", (float *) data, &dummy), 0); +#else + Error("grib_get_float_array() not found!"); +#endif + } + else + GRIB_CHECK(grib_get_double_array(gh, "values", (double *) data, &dummy), 0); long lpar; GRIB_CHECK(grib_get_long(gh, "gridDefinitionTemplateNumber", &lpar), 0); @@ -3154,8 +3163,8 @@ gribapiSetExtMode(grib_handle *gh, int gridID, size_t datasize, const void *data // #define GRIBAPIENCODETEST 1 size_t -gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisID, CdiDateTime vDateTime, int tsteptype, int numavg, - size_t datasize, const void *data, size_t nmiss, void **gribbuffer, size_t *gribbuffersize, int comptype, +gribapiEncode(int memType, int varID, int levelID, int vlistID, int gridID, int zaxisID, CdiDateTime vDateTime, int tsteptype, + int numavg, size_t datasize, const void *data, size_t nmiss, void **gribbuffer, size_t *gribbuffersize, int comptype, void *gribContainer) { long editionNumber = 2; @@ -3332,7 +3341,16 @@ gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisID, CdiD gribapiSetExtMode(gh, gridID, datasize, data); - GRIB_CHECK(grib_set_double_array(gh, "values", (const double *) data, datasize), 0); + if (memType == MEMTYPE_FLOAT) + { +#ifdef HAVE_GRIBAPI_FLOAT_INTERFACE + GRIB_CHECK(grib_set_float_array(gh, "values", (const float *) data, datasize), 0); +#else + Error("grib_set_float_array() not found!"); +#endif + } + else + GRIB_CHECK(grib_set_double_array(gh, "values", (const double *) data, datasize), 0); if (nmiss) { diff --git a/src/stream_gribapi.h b/src/stream_gribapi.h index b5e6def463a96112fdb0cfe6be9f7b0594474f8e..7e1300fee2e482f3e57ac4c3de806fdb47a06e42 100644 --- a/src/stream_gribapi.h +++ b/src/stream_gribapi.h @@ -11,11 +11,12 @@ int gribapiScanTimestep1(stream_t *streamptr); int gribapiScanTimestep2(stream_t *streamptr); int gribapiScanTimestep(stream_t *streamptr); -int gribapiDecode(void *gribbuffer, size_t gribsize, void *data, size_t datasize, int unreduced, size_t *nmiss, double missval); +int gribapiDecode(int memType, void *gribbuffer, size_t gribsize, void *data, size_t datasize, int unreduced, size_t *nmiss, + double missval); -size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisID, CdiDateTime vDateTime, int tsteptype, int numavg, - size_t datasize, const void *data, size_t nmiss, void **gribbuffer, size_t *gribbuffersize, int ljpeg, - void *gribContainer); +size_t gribapiEncode(int memType, int varID, int levelID, int vlistID, int gridID, int zaxisID, CdiDateTime vDateTime, + int tsteptype, int numavg, size_t datasize, const void *data, size_t nmiss, void **gribbuffer, + size_t *gribbuffersize, int ljpeg, void *gribContainer); int gribapiGetScanningMode(grib_handle *gh); void gribapiSetScanningMode(grib_handle *gh, int scanningMode); diff --git a/src/stream_read.c b/src/stream_read.c index 54f95cbc98ed6a5840c990f85111efdc5e807fd1..e42dd0327dbcf45a4b9d05d097c1bacc723b7867 100644 --- a/src/stream_read.c +++ b/src/stream_read.c @@ -34,8 +34,7 @@ cdiStreamReadVar(int streamID, int varID, int memtype, void *data, size_t *nmiss switch (cdiBaseFiletype(filetype)) { #ifdef HAVE_LIBGRIB - case CDI_FILETYPE_GRB: - case CDI_FILETYPE_GRB2: grb_read_var(streamptr, varID, memtype, data, nmiss); break; + case CDI_FILETYPE_GRIB: grb_read_var(streamptr, varID, memtype, data, nmiss); break; #endif #ifdef HAVE_LIBSERVICE case CDI_FILETYPE_SRV: srvReadVarDP(streamptr, varID, (double *) data, nmiss); break; @@ -137,8 +136,7 @@ cdiStreamReadVarSlice(int streamID, int varID, int levelID, int memtype, void *d switch (cdiBaseFiletype(filetype)) { #ifdef HAVE_LIBGRIB - case CDI_FILETYPE_GRB: - case CDI_FILETYPE_GRB2: grb_read_var_slice(streamptr, varID, levelID, memtype, data, nmiss); break; + case CDI_FILETYPE_GRIB: grb_read_var_slice(streamptr, varID, levelID, memtype, data, nmiss); break; #endif #ifdef HAVE_LIBSERVICE case CDI_FILETYPE_SRV: srvReadVarSliceDP(streamptr, varID, levelID, (double *) data, nmiss); break; @@ -237,8 +235,7 @@ stream_read_record(int streamID, int memtype, void *data, size_t *nmiss) switch (cdiBaseFiletype(streamptr->filetype)) { #ifdef HAVE_LIBGRIB - case CDI_FILETYPE_GRB: - case CDI_FILETYPE_GRB2: grb_read_record(streamptr, memtype, data, nmiss); break; + case CDI_FILETYPE_GRIB: grb_read_record(streamptr, memtype, data, nmiss); break; #endif #ifdef HAVE_LIBSERVICE case CDI_FILETYPE_SRV: srv_read_record(streamptr, memtype, data, nmiss); break; diff --git a/src/stream_record.c b/src/stream_record.c index 0ef0dffa12204d72943a046b011fcdfda5af4ee0..41c033eda349ba0c3be207c4e0578f70e6e9201d 100644 --- a/src/stream_record.c +++ b/src/stream_record.c @@ -178,8 +178,7 @@ streamDefRecord(int streamID, int varID, int levelID) switch (cdiBaseFiletype(streamptr->filetype)) { #ifdef HAVE_LIBGRIB - case CDI_FILETYPE_GRB: - case CDI_FILETYPE_GRB2: grbDefRecord(streamptr); break; + case CDI_FILETYPE_GRIB: grbDefRecord(streamptr); break; #endif #ifdef HAVE_LIBSERVICE case CDI_FILETYPE_SRV: srvDefRecord(streamptr); break; @@ -214,8 +213,7 @@ streamCopyRecord(int streamID2, int streamID1) switch (cdiBaseFiletype(filetype)) { #ifdef HAVE_LIBGRIB - case CDI_FILETYPE_GRB: - case CDI_FILETYPE_GRB2: grbCopyRecord(streamptr2, streamptr1); break; + case CDI_FILETYPE_GRIB: grbCopyRecord(streamptr2, streamptr1); break; #endif #ifdef HAVE_LIBSERVICE case CDI_FILETYPE_SRV: srvCopyRecord(streamptr2, streamptr1); break; diff --git a/src/stream_write.c b/src/stream_write.c index 595f360e2096481e4c1a589cf7434f79a39b34f7..226db5f9c1ca15fe8c10e8752e5f273cfd19180c 100644 --- a/src/stream_write.c +++ b/src/stream_write.c @@ -37,8 +37,7 @@ cdiStreamWriteVar_(int streamID, int varID, int memtype, const void *data, SizeT switch (cdiBaseFiletype(filetype)) { #ifdef HAVE_LIBGRIB - case CDI_FILETYPE_GRB: - case CDI_FILETYPE_GRB2: grb_write_var(streamptr, varID, memtype, data, nmiss); break; + case CDI_FILETYPE_GRIB: grb_write_var(streamptr, varID, memtype, data, nmiss); break; #endif #ifdef HAVE_LIBSERVICE case CDI_FILETYPE_SRV: srvWriteVarDP(streamptr, varID, (double *) data); break; @@ -143,8 +142,7 @@ cdiStreamWriteVarSlice(int streamID, int varID, int levelID, int memtype, const switch (cdiBaseFiletype(filetype)) { #ifdef HAVE_LIBGRIB - case CDI_FILETYPE_GRB: - case CDI_FILETYPE_GRB2: grb_write_var_slice(streamptr, varID, levelID, memtype, data, nmiss); break; + case CDI_FILETYPE_GRIB: grb_write_var_slice(streamptr, varID, levelID, memtype, data, nmiss); break; #endif #ifdef HAVE_LIBSERVICE case CDI_FILETYPE_SRV: srvWriteVarSliceDP(streamptr, varID, levelID, (double *) data); break; @@ -252,8 +250,7 @@ cdiStreamWriteVarChunk_(int streamID, int varID, int memtype, const int rect[][2 switch (cdiBaseFiletype(filetype)) { #if defined(HAVE_LIBGRIB) - case CDI_FILETYPE_GRB: - case CDI_FILETYPE_GRB2: + case CDI_FILETYPE_GRIB: #endif #if defined(HAVE_LIBSERVICE) case CDI_FILETYPE_SRV: @@ -285,8 +282,7 @@ stream_write_record(int streamID, int memtype, const void *data, SizeType nmiss) switch (cdiBaseFiletype(streamptr->filetype)) { #ifdef HAVE_LIBGRIB - case CDI_FILETYPE_GRB: - case CDI_FILETYPE_GRB2: grb_write_record(streamptr, memtype, data, nmiss); break; + case CDI_FILETYPE_GRIB: grb_write_record(streamptr, memtype, data, nmiss); break; #endif #ifdef HAVE_LIBSERVICE case CDI_FILETYPE_SRV: srv_write_record(streamptr, memtype, data); break; diff --git a/src/taxis.c b/src/taxis.c index 5350c900b19918c9e613d5552cee12bd02d9faa2..bcb28982fe314ff60a1a27ee1138c74d4fd4ad77 100644 --- a/src/taxis.c +++ b/src/taxis.c @@ -1386,7 +1386,7 @@ taxisCompareP(void *taxisptr1, void *taxisptr2) return !(t1->type == t2->type && cdiDateTime_isEQ(t1->vDateTime, t2->vDateTime) && cdiDateTime_isEQ(t1->rDateTime, t2->rDateTime) && cdiDateTime_isEQ(t1->fDateTime, t2->fDateTime) && t1->calendar == t2->calendar && t1->unit == t2->unit - && t1->fc_unit == t2->fc_unit && t1->fc_period == t2->fc_period && t1->numavg == t2->numavg + && t1->fc_unit == t2->fc_unit && IS_EQUAL(t1->fc_period, t2->fc_period) && t1->numavg == t2->numavg && t1->climatology == t2->climatology && t1->hasBounds == t2->hasBounds && cdiDateTime_isEQ(t1->vDateTime_lb, t2->vDateTime_lb) && cdiDateTime_isEQ(t1->vDateTime_ub, t2->vDateTime_ub)); }