From e311236c51ab6470d5896a50ad3437bdf3b58461 Mon Sep 17 00:00:00 2001 From: Uwe Schulzweida <uwe.schulzweida@mpimet.mpg.de> Date: Wed, 12 Feb 2025 10:16:27 +0100 Subject: [PATCH 1/5] GRIB_API: Handle LLAM as LCC --- ChangeLog | 4 ++++ src/gribapi.h | 1 + src/gribapi_utilities.c | 1 + 3 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index 3c80e270f..936af6411 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,10 @@ * Version 2.5.1 released +2025-02-12 Uwe Schulzweida + + * GRIB_API: Handle LLAM as LCC + 2025-02-06 Uwe Schulzweida * Added obsolete functions vlistNgrids() and vlistNzaxis() for ParaView vtkCDIReader diff --git a/src/gribapi.h b/src/gribapi.h index 87e9a23e3..784eb940a 100644 --- a/src/gribapi.h +++ b/src/gribapi.h @@ -49,6 +49,7 @@ #define GRIB2_GTYPE_LATLON_ROTSTR 3 // Stretched and Rotated Latitude/longitude #define GRIB2_GTYPE_STERE 20 // Polar stereographic projection #define GRIB2_GTYPE_LCC 30 // Lambert conformal +#define GRIB2_GTYPE_LLAM 33 // Lambert LAM #define GRIB2_GTYPE_GAUSSIAN 40 // Gaussian latitude/longitude #define GRIB2_GTYPE_GAUSSIAN_ROT 41 // Rotated Gaussian latitude/longitude #define GRIB2_GTYPE_GAUSSIAN_STR 42 // Stretched Gaussian latitude/longitude diff --git a/src/gribapi_utilities.c b/src/gribapi_utilities.c index 068b7f4bb..ee5b15863 100644 --- a/src/gribapi_utilities.c +++ b/src/gribapi_utilities.c @@ -591,6 +591,7 @@ gribapiGetGridType(grib_handle *gh) case GRIB2_GTYPE_GAUSSIAN: return has_ni(gh) ? GRID_GAUSSIAN : GRID_GAUSSIAN_REDUCED; case GRIB2_GTYPE_LATLON_ROT: return GRID_PROJECTION; case GRIB2_GTYPE_LCC: return CDI_PROJ_LCC; + case GRIB2_GTYPE_LLAM: return CDI_PROJ_LCC; // Handle LLAM as LCC case GRIB2_GTYPE_STERE: return CDI_PROJ_STERE; case GRIB2_GTYPE_SPECTRAL: return GRID_SPECTRAL; case GRIB2_GTYPE_GME: return GRID_GME; -- GitLab From 46ebf9d78c8576f7b4ee9a0524414a5cb502b526 Mon Sep 17 00:00:00 2001 From: Uwe Schulzweida <uwe.schulzweida@mpimet.mpg.de> Date: Wed, 12 Feb 2025 11:49:44 +0100 Subject: [PATCH 2/5] Replaced gridDefDatatype()/gridInqDatatype() by cdiDefKeyInt()/cdiInqKeyInt() with CDI_KEY_DATATYPE --- app/printinfo.c | 9 +++++---- examples/pio/compareResourcesArray.c | 2 +- tests/test_resource_copy.c | 4 ++-- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/app/printinfo.c b/app/printinfo.c index ccbeea004..8fd902e0b 100644 --- a/app/printinfo.c +++ b/app/printinfo.c @@ -300,8 +300,8 @@ printGridInfoKernel(int gridID, int index, bool lproj) size_t xsize = (size_t) gridInqXsize(gridID); size_t ysize = (size_t) gridInqYsize(gridID); - // int prec = gridInqDatatype(gridID); - // int dig = (prec == CDI_DATATYPE_FLT64) ? 15 : 7; + // int datatype; + // cdiInqKeyInt(gridID, CDI_GLOBAL, CDI_KEY_DATATYPE, &datatype); int dig = 7; if (!lproj) @@ -537,8 +537,9 @@ printZaxisInfo(int vlistID) int ltype = 0; cdiInqKeyInt(zaxisID, CDI_GLOBAL, CDI_KEY_TYPEOFFIRSTFIXEDSURFACE, <ype); int levelsize = zaxisInqSize(zaxisID); - // int prec = zaxisInqDatatype(zaxisID); - // int dig = (prec == CDI_DATATYPE_FLT64) ? 15 : 7; + // int datatype; + // cdiInqKeyInt(gridID, CDI_GLOBAL, CDI_KEY_DATATYPE, &datatype); + // int dig = (datatype == CDI_DATATYPE_FLT64) ? 15 : 7; zaxisName(zaxistype, zaxisname); int length = CDI_MAX_NAME; diff --git a/examples/pio/compareResourcesArray.c b/examples/pio/compareResourcesArray.c index 0082d60ca..4eb771089 100644 --- a/examples/pio/compareResourcesArray.c +++ b/examples/pio/compareResourcesArray.c @@ -60,7 +60,7 @@ defineGrid() cdiDefKeyString(gridID, CDI_XAXIS, CDI_KEY_UNITS, "myXunits"); cdiDefKeyString(gridID, CDI_YAXIS, CDI_KEY_UNITS, "myYunits"); - gridDefDatatype(gridID, DOUBLE_PRECISION); + cdiDefKeyInt(gridID, CDI_GLOBAL, CDI_KEY_DATATYPE, DOUBLE_PRECISION); gridDefTrunc(gridID, 1); cdiDefKeyInt(gridID, CDI_GLOBAL, CDI_KEY_NUMBEROFGRIDUSED, 6); diff --git a/tests/test_resource_copy.c b/tests/test_resource_copy.c index ce789c30d..ffd2c7793 100644 --- a/tests/test_resource_copy.c +++ b/tests/test_resource_copy.c @@ -63,7 +63,7 @@ defineGrid(void) cdiDefKeyString(gridID, CDI_XAXIS, CDI_KEY_UNITS, "myXunits"); cdiDefKeyString(gridID, CDI_YAXIS, CDI_KEY_UNITS, "myYunits"); - gridDefDatatype(gridID, DOUBLE_PRECISION); + cdiDefKeyInt(gridID, CDI_GLOBAL, CDI_KEY_DATATYPE, DOUBLE_PRECISION); gridDefTrunc(gridID, 1); gridDefParamGME(gridID, 2, 3, 4, 5); @@ -164,7 +164,7 @@ defineVlist(int gridID, int zaxisID, int taxisID) cdiDefAttTxt(vlistID, varID2, "txt demo", 6, "banana"); vlistDefTaxis(vlistID, taxisID); int vlistID2 = vlistDuplicate(vlistID); - return (struct idPair){ vlistID, vlistID2 }; + return (struct idPair) { vlistID, vlistID2 }; } static int -- GitLab From 9ef4ff35972e938e91cfd7db6ebd4111386e8637 Mon Sep 17 00:00:00 2001 From: Uwe Schulzweida <uwe.schulzweida@mpimet.mpg.de> Date: Thu, 27 Feb 2025 21:16:52 +0100 Subject: [PATCH 3/5] taxis_t: added cdi_keys_t --- src/taxis.c | 17 +++++++++++++++-- src/taxis.h | 3 +++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/taxis.c b/src/taxis.c index 5acf45b57..e0363e598 100644 --- a/src/taxis.c +++ b/src/taxis.c @@ -102,7 +102,6 @@ void ptaxisInit(taxis_t *taxisptr) { taxisptr->self = CDI_UNDEFID; - taxisptr->datatype = CDI_DATATYPE_FLT64; taxisptr->type = DefaultTimeType; taxisptr->calendar = CDI_Default_Calendar; taxisptr->unit = DefaultTimeUnit; @@ -120,6 +119,10 @@ ptaxisInit(taxis_t *taxisptr) taxisptr->name = NULL; taxisptr->longname = NULL; taxisptr->units = NULL; + + cdiInitKeys(&taxisptr->keys); + cdiDefVarKeyInt(&taxisptr->keys, CDI_KEY_DATATYPE, CDI_DATATYPE_FLT64); + taxisptr->datatype = CDI_DATATYPE_FLT64; } static taxis_t * @@ -235,6 +238,7 @@ taxisDefType(int taxisID, int taxistype) if (taxisptr->type != taxistype) { taxisptr->type = taxistype; + cdiDefVarKeyInt(&taxisptr->keys, CDI_KEY_DATATYPE, CDI_DATATYPE_FLT64); taxisptr->datatype = CDI_DATATYPE_FLT64; delete_refcount_string(taxisptr->units); taxisptr->units = NULL; @@ -849,6 +853,7 @@ taxisPtr(int taxisID) void ptaxisDefDatatype(taxis_t *taxisptr, int datatype) { + cdiDefVarKeyInt(&taxisptr->keys, CDI_KEY_DATATYPE, datatype); taxisptr->datatype = datatype; } @@ -1349,7 +1354,6 @@ ptaxisCopy(taxis_t *dest, taxis_t *source) reshLock(); // memcpy(dest, source, sizeof(taxis_t)); - dest->datatype = source->datatype; dest->type = source->type; dest->calendar = source->calendar; dest->unit = source->unit; @@ -1374,6 +1378,10 @@ ptaxisCopy(taxis_t *dest, taxis_t *source) dest->units = dup_refcount_string(source->units); if (dest->self != CDI_UNDEFID) reshSetStatus(dest->self, &taxisOps, RESH_DESYNC_IN_USE); + dest->datatype = source->datatype; + cdiInitKeys(&dest->keys); + cdiCopyVarKeys(&source->keys, &dest->keys); + reshUnlock(); } @@ -1480,6 +1488,7 @@ taxisGetPackSize(void *p, void *context) + (taxisptr->longname ? serializeGetSize((int) strlen(taxisptr->longname), CDI_DATATYPE_TXT, context) : 0) + (taxisptr->units ? serializeGetSize((int) strlen(taxisptr->units), CDI_DATATYPE_TXT, context) : 0) + serializeGetSize(1, CDI_DATATYPE_UINT32, context); + packBufferSize += serializeKeysGetPackSize(&taxisptr->keys, context); return packBufferSize; } @@ -1546,6 +1555,8 @@ taxisUnpack(char *unpackBuffer, int unpackBufferSize, int *unpackBufferPos, int taxisP->units = units; } + serializeKeysUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos, &taxisP->keys, context); + reshSetStatus(taxisP->self, &taxisOps, reshGetStatus(taxisP->self, &taxisOps) & ~RESH_SYNC_BIT); #undef adaptKey @@ -1596,6 +1607,8 @@ taxisPack(void *voidP, void *packBuffer, int packBufferSize, int *packBufferPos, if (taxisP->longname) serializePack(taxisP->longname, lnameLen, CDI_DATATYPE_TXT, packBuffer, packBufferSize, packBufferPos, context); if (taxisP->units) serializePack(taxisP->units, unitsLen, CDI_DATATYPE_TXT, packBuffer, packBufferSize, packBufferPos, context); + + serializeKeysPack(&taxisP->keys, packBuffer, packBufferSize, packBufferPos, context); } /* diff --git a/src/taxis.h b/src/taxis.h index b7eac2893..7f98b99ad 100644 --- a/src/taxis.h +++ b/src/taxis.h @@ -4,6 +4,8 @@ #include <stdbool.h> #include "cdi.h" +#include "cdi_key.h" + #ifndef RESOURCE_HANDLE_H #include "resource_handle.h" #endif @@ -29,6 +31,7 @@ typedef struct char *units; bool climatology; bool hasBounds; + cdi_keys_t keys; } taxis_t; // taxisInqSdatetime: Get the start date/time -- GitLab From f14d5e7ea135299754987f7e009af21af01c728a Mon Sep 17 00:00:00 2001 From: Uwe Schulzweida <uwe.schulzweida@mpimet.mpg.de> Date: Fri, 28 Feb 2025 08:50:39 +0100 Subject: [PATCH 4/5] taxis: added support for CDI_KEY_DATATYPE --- ChangeLog | 4 ++++ src/cdi_key.c | 8 ++++++++ src/stream.c | 12 ++++++------ src/stream_cdf_time.c | 7 ++++--- src/taxis.c | 6 +----- src/taxis.h | 5 ++--- 6 files changed, 25 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index 936af6411..093a8abe4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,10 @@ * Version 2.5.1 released +2025-02-28 Uwe Schulzweida + + * taxis: added support for CDI_KEY_DATATYPE + 2025-02-12 Uwe Schulzweida * GRIB_API: Handle LLAM as LCC diff --git a/src/cdi_key.c b/src/cdi_key.c index b80d936df..3f0351a1e 100644 --- a/src/cdi_key.c +++ b/src/cdi_key.c @@ -12,6 +12,7 @@ #include "cdi.h" #include "cdi_int.h" +#include "taxis.h" #include "zaxis.h" #include "grid.h" #include "vlist.h" @@ -43,6 +44,12 @@ zaxis_get_keysp(zaxis_t *zaxisptr, int varID) return (varID == CDI_GLOBAL) ? &zaxisptr->keys : NULL; } +static cdi_keys_t * +taxis_get_keysp(taxis_t *taxisptr, int varID) +{ + return (varID == CDI_GLOBAL) ? &taxisptr->keys : NULL; +} + static cdi_key_t * new_key(cdi_keys_t *keysp, int key) { @@ -100,6 +107,7 @@ cdi_get_keysp(int objID, int varID) if (reshID == GRID) return grid_get_keysp(grid_to_pointer(objID), varID); if (reshID == DIST_GRID) return grid_get_keysp(grid_to_pointer(objID), varID); if (reshID == ZAXIS) return zaxis_get_keysp(zaxis_to_pointer(objID), varID); + if (reshID == TAXIS) return taxis_get_keysp(taxis_to_pointer(objID), varID); if (reshID == VLIST) return vlist_get_keysp(vlist_to_pointer(objID), varID); return NULL; diff --git a/src/stream.c b/src/stream.c index 34aabfbab..f3a11f7c8 100644 --- a/src/stream.c +++ b/src/stream.c @@ -430,7 +430,7 @@ cdiInqContents(stream_t *streamptr) if (taxisID != CDI_UNDEFID) { taxis_t *taxisptr1 = &streamptr->tsteps[0].taxis; - taxis_t *taxisptr2 = taxisPtr(taxisID); + taxis_t *taxisptr2 = taxis_to_pointer(taxisID); ptaxisCopy(taxisptr2, taxisptr1); } } @@ -1462,7 +1462,7 @@ cdiStreamDefTimestep_(stream_t *streamptr, int tsID) } int taxisID = vlistInqTaxis(vlistID); - if (taxisID != CDI_UNDEFID) ptaxisCopy(&streamptr->tsteps[tsID].taxis, taxisPtr(taxisID)); + if (taxisID != CDI_UNDEFID) ptaxisCopy(&streamptr->tsteps[tsID].taxis, taxis_to_pointer(taxisID)); streamptr->curTsID = tsID; streamptr->ntsteps = tsID + 1; @@ -1564,7 +1564,7 @@ streamInqTimestep(int streamID, int tsID) streamptr->tsteps[tsID].curRecID = CDI_UNDEFID; int taxisID = vlistInqTaxis(vlistID); if (taxisID == -1) Error("Timestep undefined for fileID = %d", streamID); - ptaxisCopy(taxisPtr(taxisID), &streamptr->tsteps[tsID].taxis); + ptaxisCopy(taxis_to_pointer(taxisID), &streamptr->tsteps[tsID].taxis); return nrecs; } @@ -1633,7 +1633,7 @@ streamInqTimestep(int streamID, int tsID) int taxisID = vlistInqTaxis(vlistID); if (taxisID == -1) Error("Timestep undefined for fileID = %d", streamID); - ptaxisCopy(taxisPtr(taxisID), &streamptr->tsteps[tsID].taxis); + ptaxisCopy(taxis_to_pointer(taxisID), &streamptr->tsteps[tsID].taxis); return nrecs; } @@ -1832,7 +1832,7 @@ cdiStreamSetupVlist_(stream_t *streamptr, int vlistID) if (taxisInqType(taxisID) == TAXIS_RELATIVE) if (cdiBaseFiletype(streamptr->filetype) == CDI_FILETYPE_NETCDF) { - const taxis_t *taxisptr = taxisPtr(taxisID); + const taxis_t *taxisptr = taxis_to_pointer(taxisID); if (cdiDateTime_isNull(taxisptr->rDateTime)) { int vdate = taxisInqVdate(taxisID); @@ -1841,7 +1841,7 @@ cdiStreamSetupVlist_(stream_t *streamptr, int vlistID) } } #endif - ptaxisCopy(&streamptr->tsteps[0].taxis, taxisPtr(taxisID)); + ptaxisCopy(&streamptr->tsteps[0].taxis, taxis_to_pointer(taxisID)); } switch (cdiBaseFiletype(streamptr->filetype)) diff --git a/src/stream_cdf_time.c b/src/stream_cdf_time.c index dc594c44d..8b5e662a9 100644 --- a/src/stream_cdf_time.c +++ b/src/stream_cdf_time.c @@ -153,7 +153,7 @@ cdfDefTime(stream_t *streamptr) if (streamptr->ncmode == 0) streamptr->ncmode = 1; if (streamptr->ncmode == 2) cdf_redef(fileID); - taxis_t *taxis = taxisPtr(vlistInqTaxis(streamptr->vlistID)); + taxis_t *taxis = taxis_to_pointer(vlistInqTaxis(streamptr->vlistID)); const char *taxisName = (taxis->name && taxis->name[0]) ? taxis->name : defaultTimeAxisName; @@ -170,7 +170,8 @@ cdfDefTime(stream_t *streamptr) cdf_def_dim(fileID, taxisName, timeDimLen, &timeDimId); streamptr->basetime.ncdimid = timeDimId; - int datatype = taxis->datatype; + int datatype = CDI_UNDEFID; + cdiInqKeyInt(taxis->self, CDI_GLOBAL, CDI_KEY_DATATYPE, &datatype); nc_type xtype = (datatype == CDI_DATATYPE_INT32) ? NC_INT : ((datatype == CDI_DATATYPE_FLT32) ? NC_FLOAT : NC_DOUBLE); int timeVarId; @@ -245,7 +246,7 @@ cdfDefTimestep(stream_t *streamptr, int tsID, size_t valCount) int time_varid = streamptr->basetime.ncvarid; if (time_varid != CDI_UNDEFID && tsID == 0) { - taxis_t *taxis = taxisPtr(vlistInqTaxis(streamptr->vlistID)); + taxis_t *taxis = taxis_to_pointer(vlistInqTaxis(streamptr->vlistID)); int fileID = streamptr->fileID; const char *unitstr = cdfGetTimeUnits(taxis); size_t len = strlen(unitstr); diff --git a/src/taxis.c b/src/taxis.c index e0363e598..a252db8b1 100644 --- a/src/taxis.c +++ b/src/taxis.c @@ -122,7 +122,6 @@ ptaxisInit(taxis_t *taxisptr) cdiInitKeys(&taxisptr->keys); cdiDefVarKeyInt(&taxisptr->keys, CDI_KEY_DATATYPE, CDI_DATATYPE_FLT64); - taxisptr->datatype = CDI_DATATYPE_FLT64; } static taxis_t * @@ -239,7 +238,6 @@ taxisDefType(int taxisID, int taxistype) { taxisptr->type = taxistype; cdiDefVarKeyInt(&taxisptr->keys, CDI_KEY_DATATYPE, CDI_DATATYPE_FLT64); - taxisptr->datatype = CDI_DATATYPE_FLT64; delete_refcount_string(taxisptr->units); taxisptr->units = NULL; reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE); @@ -844,7 +842,7 @@ taxisInqNumavg(int taxisID) } taxis_t * -taxisPtr(int taxisID) +taxis_to_pointer(int taxisID) { taxis_t *taxisptr = (taxis_t *) reshGetVal(taxisID, &taxisOps); return taxisptr; @@ -854,7 +852,6 @@ void ptaxisDefDatatype(taxis_t *taxisptr, int datatype) { cdiDefVarKeyInt(&taxisptr->keys, CDI_KEY_DATATYPE, datatype); - taxisptr->datatype = datatype; } void @@ -1378,7 +1375,6 @@ ptaxisCopy(taxis_t *dest, taxis_t *source) dest->units = dup_refcount_string(source->units); if (dest->self != CDI_UNDEFID) reshSetStatus(dest->self, &taxisOps, RESH_DESYNC_IN_USE); - dest->datatype = source->datatype; cdiInitKeys(&dest->keys); cdiCopyVarKeys(&source->keys, &dest->keys); diff --git a/src/taxis.h b/src/taxis.h index 7f98b99ad..5888b513d 100644 --- a/src/taxis.h +++ b/src/taxis.h @@ -13,8 +13,7 @@ typedef struct { int self; - int datatype; // datatype - int type; // time type + int type; // time type int calendar; int unit; // time units int numavg; @@ -39,7 +38,7 @@ CdiDateTime taxisInqSdatetime(int taxisID); void ptaxisInit(taxis_t *taxis); void ptaxisCopy(taxis_t *dest, taxis_t *source); -taxis_t *taxisPtr(int taxisID); +taxis_t *taxis_to_pointer(int taxisID); void cdi_set_forecast_period(double timevalue, taxis_t *taxis); CdiDateTime cdi_decode_timeval(double timevalue, const taxis_t *taxis); double cdi_encode_timeval(CdiDateTime datetime, taxis_t *taxis); -- GitLab From ff8e438e306dea8a5b333449aa07583148c58fbe Mon Sep 17 00:00:00 2001 From: Uwe Schulzweida <uwe.schulzweida@mpimet.mpg.de> Date: Fri, 28 Feb 2025 08:55:22 +0100 Subject: [PATCH 5/5] taxis: added support for CDI_KEY_DATATYPE --- src/pio_server.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pio_server.c b/src/pio_server.c index bdda03d49..a9f4c7c3d 100644 --- a/src/pio_server.c +++ b/src/pio_server.c @@ -246,8 +246,8 @@ readFuncCall(struct winHeaderEntry *header, size_t streamIdx) int position = header->offset; int changedTaxisID = taxisUnpack((char *) rxWin[streamIdx].clientBuf[0].mem, (int) rxWin[streamIdx].clientBuf[0].size, &position, originNamespace, &pioInterComm, 0); - taxis_t *oldTaxisPtr = taxisPtr(oldTaxisID); - taxis_t *changedTaxisPtr = taxisPtr(changedTaxisID); + taxis_t *oldTaxisPtr = taxis_to_pointer(oldTaxisID); + taxis_t *changedTaxisPtr = taxis_to_pointer(changedTaxisID); ptaxisCopy(oldTaxisPtr, changedTaxisPtr); taxisDestroy(changedTaxisID); streamDefTimestep(streamID, funcArgs->streamNewTimestep.tsID); -- GitLab