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

Preserve netcdf time units attribute.

parent b7419ce0
......@@ -2,6 +2,10 @@
* Version 1.8.1 released
2017-03-08 Uwe Schulzweida
* Preserve netcdf time units attribute
2017-03-07 Uwe Schulzweida
* Added function streamGrbChangeParameterIdentification() (patch from Michal Koutek, KMNI)
......
......@@ -3836,6 +3836,9 @@ int cdfInqContents(stream_t *streamptr)
if ( ncvars[nctimevarid].longname[0] )
ptaxisDefLongname(taxis, ncvars[nctimevarid].longname);
if ( ncvars[nctimevarid].units[0] )
ptaxisDefUnits(taxis, ncvars[nctimevarid].units);
int datatype = (ncvars[nctimevarid].xtype == NC_FLOAT) ? CDI_DATATYPE_FLT32 : CDI_DATATYPE_FLT64;
ptaxisDefDatatype(taxis, datatype);
}
......
......@@ -143,42 +143,46 @@ int cdfDefTimeBounds(int fileID, int nctimevarid, int nctimedimid, const char *t
}
static
void cdfDefTimeUnits(char *unitstr, taxis_t* taxis0, taxis_t* taxis)
void cdfDefTimeUnits(char *unitstr, taxis_t *taxis0, taxis_t *taxis)
{
unitstr[0] = 0;
if ( taxis0->type == TAXIS_ABSOLUTE )
if ( taxis->units && taxis->units[0] )
{
if ( taxis0->unit == TUNIT_YEAR )
sprintf(unitstr, "year as %s", "%Y.%f");
else if ( taxis0->unit == TUNIT_MONTH )
sprintf(unitstr, "month as %s", "%Y%m.%f");
else
sprintf(unitstr, "day as %s", "%Y%m%d.%f");
strcpy(unitstr, taxis->units);
}
else
{
int timeunit = taxis->unit != -1 ? taxis->unit : TUNIT_HOUR;
int rdate = taxis->rdate;
int rtime = taxis->rtime;
if ( rdate == -1 )
unitstr[0] = 0;
if ( taxis0->type == TAXIS_ABSOLUTE )
{
rdate = taxis->vdate;
rtime = taxis->vtime;
if ( taxis0->unit == TUNIT_YEAR ) sprintf(unitstr, "year as %s", "%Y.%f");
else if ( taxis0->unit == TUNIT_MONTH ) sprintf(unitstr, "month as %s", "%Y%m.%f");
else sprintf(unitstr, "day as %s", "%Y%m%d.%f");
}
else
{
int timeunit = taxis->unit != -1 ? taxis->unit : TUNIT_HOUR;
int rdate = taxis->rdate;
int rtime = taxis->rtime;
if ( rdate == -1 )
{
rdate = taxis->vdate;
rtime = taxis->vtime;
}
int year, month, day, hour, minute, second;
cdiDecodeDate(rdate, &year, &month, &day);
cdiDecodeTime(rtime, &hour, &minute, &second);
int year, month, day, hour, minute, second;
cdiDecodeDate(rdate, &year, &month, &day);
cdiDecodeTime(rtime, &hour, &minute, &second);
if ( timeunit == TUNIT_QUARTER ) timeunit = TUNIT_MINUTE;
if ( timeunit == TUNIT_30MINUTES ) timeunit = TUNIT_MINUTE;
if ( timeunit == TUNIT_3HOURS ||
timeunit == TUNIT_6HOURS ||
timeunit == TUNIT_12HOURS ) timeunit = TUNIT_HOUR;
if ( timeunit == TUNIT_QUARTER ) timeunit = TUNIT_MINUTE;
if ( timeunit == TUNIT_30MINUTES ) timeunit = TUNIT_MINUTE;
if ( timeunit == TUNIT_3HOURS ||
timeunit == TUNIT_6HOURS ||
timeunit == TUNIT_12HOURS ) timeunit = TUNIT_HOUR;
sprintf(unitstr, "%s since %d-%d-%d %02d:%02d:%02d",
tunitNamePtr(timeunit), year, month, day, hour, minute, second);
sprintf(unitstr, "%s since %d-%d-%d %02d:%02d:%02d",
tunitNamePtr(timeunit), year, month, day, hour, minute, second);
}
}
}
......
......@@ -3,7 +3,6 @@
#endif
#include <stddef.h>
#include <string.h>
#include "cdi.h"
#include "calendar.h"
......@@ -17,6 +16,7 @@
#include "resource_handle.h"
#include "resource_unpack.h"
static int DefaultTimeType = TAXIS_ABSOLUTE;
static int DefaultTimeUnit = TUNIT_HOUR;
......@@ -104,24 +104,15 @@ static int TAXIS_Debug = 0; /* If set to 1, debugging */
const char *tunitNamePtr(int unitID)
{
const char *name;
int size = sizeof(Timeunits)/sizeof(*Timeunits);
if ( unitID > 0 && unitID < size )
name = Timeunits[unitID];
else
name = Timeunits[0];
return name;
return (unitID > 0 && unitID < size) ? Timeunits[unitID] : Timeunits[0];
}
#if 0
static
void taxis_defaults(void)
{
char *timeunit;
timeunit = getenv("TIMEUNIT");
char *timeunit = getenv("TIMEUNIT");
if ( timeunit )
{
if ( strcmp(timeunit, "minutes") == 0 )
......@@ -172,6 +163,7 @@ void taxisDefaultValue(taxis_t* taxisptr)
taxisptr->fc_period = 0;
taxisptr->name = NULL;
taxisptr->longname = NULL;
taxisptr->units = NULL;
}
static taxis_t *
......@@ -192,7 +184,7 @@ taxisNewEntry(cdiResH resH)
}
static
void taxisInit (void)
void taxisInit(void)
{
static bool taxisInitialized = false;
......@@ -204,16 +196,6 @@ void taxisInit (void)
if ( env ) TAXIS_Debug = atoi(env);
}
#if 0
static
void taxis_copy(taxis_t *taxisptr2, taxis_t *taxisptr1)
{
int taxisID2 = taxisptr2->self;
memcpy(taxisptr2, taxisptr1, sizeof(taxis_t));
taxisptr2->self = taxisID2;
}
#endif
/*
@Function taxisCreate
@Title Create a Time axis
......@@ -266,6 +248,7 @@ void taxisDestroyKernel(taxis_t *taxisptr)
{
delete_refcount_string(taxisptr->name);
delete_refcount_string(taxisptr->longname);
delete_refcount_string(taxisptr->units);
}
/*
......@@ -311,11 +294,12 @@ int taxisDuplicate(int taxisID1)
void taxisDefType(int taxisID, int type)
{
taxis_t *taxisptr = ( taxis_t * ) reshGetVal ( taxisID, &taxisOps );
taxis_t *taxisptr = (taxis_t *) reshGetVal(taxisID, &taxisOps);
if (taxisptr->type != type)
if ( taxisptr->type != type )
{
taxisptr->type = type;
if ( taxisptr->units ) delete_refcount_string(taxisptr->units);
reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
}
}
......@@ -391,6 +375,7 @@ void taxisDefRdate(int taxisID, int rdate)
if (taxisptr->rdate != rdate)
{
taxisptr->rdate = rdate;
if ( taxisptr->units ) delete_refcount_string(taxisptr->units);
reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
}
}
......@@ -416,6 +401,7 @@ void taxisDefRtime(int taxisID, int rtime)
if (taxisptr->rtime != rtime)
{
taxisptr->rtime = rtime;
if ( taxisptr->units ) delete_refcount_string(taxisptr->units);
reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
}
}
......@@ -505,6 +491,7 @@ void taxisDefTunit(int taxisID, int unit)
if (taxisptr->unit != unit)
{
taxisptr->unit = unit;
if ( taxisptr->units ) delete_refcount_string(taxisptr->units);
reshSetStatus(taxisID, &taxisOps, RESH_DESYNC_IN_USE);
}
}
......@@ -909,6 +896,18 @@ void ptaxisDefLongname(taxis_t *taxisptr, const char *longname)
}
void ptaxisDefUnits(taxis_t *taxisptr, const char *units)
{
if ( units )
{
size_t len = strlen(units);
delete_refcount_string(taxisptr->units);
char *taxisunits = taxisptr->units = new_refcount_string(len);
strcpy(taxisunits, units);
}
}
static void
cdiDecodeTimevalue(int timeunit, double timevalue, int *days, int *secs)
{
......@@ -1377,8 +1376,10 @@ void ptaxisCopy(taxis_t *dest, taxis_t *source)
dest->climatology = source->climatology;
delete_refcount_string(dest->name);
delete_refcount_string(dest->longname);
delete_refcount_string(dest->units);
dest->name = dup_refcount_string(source->name);
dest->longname = dup_refcount_string(source->longname);
dest->units = dup_refcount_string(source->units);
if (dest->self != CDI_UNDEFID)
reshSetStatus(dest->self, &taxisOps, RESH_DESYNC_IN_USE);
reshUnlock ();
......@@ -1465,7 +1466,7 @@ taxisTxCode ( void )
return TAXIS;
}
enum { taxisNint = 21 };
enum { taxisNint = 22 };
static int
taxisGetPackSize(void *p, void *context)
......@@ -1477,8 +1478,9 @@ taxisGetPackSize(void *p, void *context)
+ (taxisptr->name ?
serializeGetSize((int)strlen(taxisptr->name), CDI_DATATYPE_TXT, context) : 0)
+ (taxisptr->longname ?
serializeGetSize((int)strlen(taxisptr->longname), CDI_DATATYPE_TXT,
context) : 0);
serializeGetSize((int)strlen(taxisptr->longname), CDI_DATATYPE_TXT, context) : 0);
+ (taxisptr->units ?
serializeGetSize((int)strlen(taxisptr->units), CDI_DATATYPE_TXT, context) : 0);
return packBufferSize;
}
......@@ -1543,6 +1545,15 @@ taxisUnpack(char * unpackBuffer, int unpackBufferSize, int * unpackBufferPos,
longname[len] = '\0';
taxisP->longname = longname;
}
if (intBuffer[idx])
{
int len = intBuffer[idx];
char *units = new_refcount_string((size_t)len);
serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
units, len, CDI_DATATYPE_TXT, context);
units[len] = '\0';
taxisP->units = units;
}
reshSetStatus(taxisP->self, &taxisOps,
reshGetStatus(taxisP->self, &taxisOps) & ~RESH_SYNC_BIT);
......@@ -1581,6 +1592,7 @@ taxisPack(void * voidP, void * packBuffer, int packBufferSize, int * packBufferP
intBuffer[idx++] = taxisP->vtime_ub;
intBuffer[idx++] = taxisP->name ? (int)strlen(taxisP->name) : 0;
intBuffer[idx++] = taxisP->longname ? (int)strlen(taxisP->longname) : 0;
intBuffer[idx++] = taxisP->units ? (int)strlen(taxisP->units) : 0;
serializePack(intBuffer, taxisNint, CDI_DATATYPE_INT,
packBuffer, packBufferSize, packBufferPos, context);
......@@ -1593,6 +1605,9 @@ taxisPack(void * voidP, void * packBuffer, int packBufferSize, int * packBufferP
if (taxisP->longname)
serializePack(taxisP->longname, intBuffer[16], CDI_DATATYPE_TXT,
packBuffer, packBufferSize, packBufferPos, context);
if (taxisP->units)
serializePack(taxisP->units, intBuffer[16], CDI_DATATYPE_TXT,
packBuffer, packBufferSize, packBufferPos, context);
}
......
......@@ -33,6 +33,7 @@ typedef struct {
double fc_period; // forecast time period
char *name;
char *longname;
char *units;
}
taxis_t;
......@@ -47,7 +48,8 @@ double vtime2timeval(int vdate, int vtime, taxis_t *taxis);
void ptaxisDefDatatype(taxis_t *taxisptr, int datatype);
void ptaxisDefName(taxis_t *taxisptr, const char *name);
void ptaxisDefLongname(taxis_t *taxisptr, const char *name);
void ptaxisDefLongname(taxis_t *taxisptr, const char *longname);
void ptaxisDefUnits(taxis_t *taxisptr, const char *units);
void taxisDestroyKernel(taxis_t *taxisptr);
#if !defined (SX)
extern const resOps taxisOps;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment