diff --git a/ChangeLog b/ChangeLog index 3c80e270fd6a9f5ce038c6c5bf7dc5045d2a47b9..093a8abe46e093501102c655d40c696409a862ef 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,14 @@ * 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 + 2025-02-06 Uwe Schulzweida * Added obsolete functions vlistNgrids() and vlistNzaxis() for ParaView vtkCDIReader diff --git a/app/printinfo.c b/app/printinfo.c index ccbeea0049bdb477e3734ebe858d7251880cf61f..8fd902e0b769628db06bbcf9e152f9938f603bf2 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 0082d60caee0271025039752166cee9fd0e94bd0..4eb771089b26c079bb3cbce5fa842bab1cc4cae1 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/src/cdi_key.c b/src/cdi_key.c index b80d936df41b9cf64976cf9639131ab2e8cd4bc4..3f0351a1e366d8eac9054cf0e10e30d82c3c6abe 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/gribapi.h b/src/gribapi.h index 87e9a23e30fa062572fc3314a9e18d5a71d8fdf7..784eb940a8e64e75d1f69e54d2b8fa50645ed675 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 068b7f4bbc062d838540238b83245fad48108df0..ee5b158633b7760dac7ff66825c1b92c778cda80 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; diff --git a/src/pio_server.c b/src/pio_server.c index bdda03d49c0726350b4daae0ffbfecbd6ceb01b5..a9f4c7c3dd66ef03bcd985ccaae950e450448bbc 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); diff --git a/src/stream.c b/src/stream.c index 34aabfbab941d64afdf4da3f208169b46c69d62f..f3a11f7c81df0494610670f4a9aa27cea5621718 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 dc594c44d4d14dd8080fc484636b7cdff7f8ecfb..8b5e662a99bdec5b897c928e9daa94477331bb9b 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 5acf45b5715e6dba9f64f41f1473927f3a56ddfd..a252db8b187e6d64c52b75b43383d3f70fe18b07 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,9 @@ 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); } static taxis_t * @@ -235,7 +237,7 @@ taxisDefType(int taxisID, int taxistype) if (taxisptr->type != taxistype) { taxisptr->type = taxistype; - taxisptr->datatype = CDI_DATATYPE_FLT64; + cdiDefVarKeyInt(&taxisptr->keys, CDI_KEY_DATATYPE, CDI_DATATYPE_FLT64); delete_refcount_string(taxisptr->units); taxisptr->units = NULL; reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE); @@ -840,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; @@ -849,7 +851,7 @@ taxisPtr(int taxisID) void ptaxisDefDatatype(taxis_t *taxisptr, int datatype) { - taxisptr->datatype = datatype; + cdiDefVarKeyInt(&taxisptr->keys, CDI_KEY_DATATYPE, datatype); } void @@ -1349,7 +1351,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 +1375,9 @@ 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); + cdiInitKeys(&dest->keys); + cdiCopyVarKeys(&source->keys, &dest->keys); + reshUnlock(); } @@ -1480,6 +1484,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 +1551,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 +1603,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 b7eac28932fc67368597f4fc030714c3782325e6..5888b513d4ba6715044d2d936faae5638f780dd4 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 @@ -11,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; @@ -29,6 +30,7 @@ typedef struct char *units; bool climatology; bool hasBounds; + cdi_keys_t keys; } taxis_t; // taxisInqSdatetime: Get the start date/time @@ -36,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); diff --git a/tests/test_resource_copy.c b/tests/test_resource_copy.c index ce789c30dabe9dfd5fbf8f62c897b1481afd9b83..ffd2c7793e01a36f2764ec7b56c31b66bdd1d596 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