void CUnit::Compile () { utUnit Base; m_Slope = 1.0; m_Offset = 0.0; if (CTools::StringToUpper(m_Text) == "DATE") { m_Text = "days"; m_Text.append(GetDateRefAsString()); } m_Text = CTools::RemoveCharSurroundingNumber(m_Text); CheckUdunits(utScan(m_Text.c_str(), &m_Compiled), m_Text); Base = m_Compiled; // = SetConversionTo(BaseUnit(self)) FindBaseUnit(Base); CheckUdunits(utConvert(&m_Compiled, &Base, &m_Slope, &m_Offset), m_Text, "Base unit"); }
int /* [rcd] Successful conversion returns NCO_NOERR */ nco_cln_prs_tm /* UDUnits1 Extract time stamp from a parsed udunits string */ (const char *unt_sng, /* I [ptr] units attribute string */ tm_cln_sct *tm_in) /* O [sct] Time structure to be populated */ { const char fnc_nm[]="nco_cln_prs_tm()"; /* [sng] Function name */ int rcd; utUnit udu_sct_in; /* UDUnits structure, input units */ #ifdef UDUNITS_PATH /* UDUNITS_PATH macro expands to where autoconf found database file */ rcd=utInit(UDUNITS_PATH); #else /* !UDUNITS_PATH */ /* When empty, utInit() uses environment variable UDUNITS_PATH, if any Otherwise it uses default initial location hardcoded when library was built */ rcd=utInit(""); #endif /* !UDUNITS_PATH */ if(rcd != UDUNITS_NOERR){ (void)fprintf(stdout,"%s: %s failed to initialize UDUnits library\n",nco_prg_nm_get(),fnc_nm); return NCO_ERR; } /* end if err */ /* Units string to convert from */ rcd=utScan(unt_sng,&udu_sct_in); if(rcd != UDUNITS_NOERR){ if(rcd == UT_EINVALID) (void)fprintf(stderr,"ERROR: units attribute \"%s\" is invalid \n",unt_sng); if(rcd == UT_ESYNTAX) (void)fprintf(stderr,"ERROR units attribute \"%s\" contains a syntax error",unt_sng); if(rcd == UT_EUNKNOWN) (void)fprintf(stderr,"ERROR units attribute \"%s\" is not in udunits database",unt_sng); (void)utTerm(); /* Free memory taken by UDUnits library */ return NCO_ERR; } /* endif unkown type */ /* Extract time origin */ if(utIsTime(&udu_sct_in)){ utCalendar(0.0,&udu_sct_in,&tm_in->year,&tm_in->month,&tm_in->day,&tm_in->hour,&tm_in->min,&tm_in->sec); rcd=NCO_NOERR; }else{ rcd=NCO_ERR; } /* endelse */ (void)utTerm(); /* Free memory taken by UDUnits library */ return rcd; } /* end UDUnits1 nco_cln_prs_tm() */
NCdsHandle_t *NCdsHandleCreate (const char *pattern, const char *name, int dncid, NCtimeStep tsMode, utUnit *tUnitIn, double sTime, double eTime) { size_t i, j, strLen, strOffset, ncNum = 0, index; char *str [] = { "{year}", "{month}", "{day}", "{hour}", "{minute}", "{second}" }; char *searchStr, *subStr, **fileNames = (char **) NULL, tsUnitStr [NCsizeString]; int *ncids = (int *) NULL, tvarid, status; int endYear, endMonth, year, month, day, hour, minute; float second; double time = 0.0, scale, offset; utUnit tUnitOut; NCdsHandle_t *dsh; if ((searchStr = malloc (strlen (pattern) + 1)) == (char *) NULL) { CMmsgPrint (CMmsgSysError, "Memory allocation error in: NCdsHandleCreate ()!"); return ((NCdsHandle_t *) NULL); } if ((utCalendar (eTime,tUnitIn,&endYear,&endMonth,&day,&hour,&minute,&second) != 0) || (utCalendar (sTime,tUnitIn,&year, &month, &day,&hour,&minute,&second) != 0)) { CMmsgPrint (CMmsgAppError, "Calender scanning error in:%s %d",__FILE__,__LINE__); goto ABORT; } switch (tsMode) { case NCtimeYear: sprintf (tsUnitStr,"years since %04d-01-01 00:00 0.0",year); break; case NCtimeMonth: sprintf (tsUnitStr,"months since %04d-%02d-01 00:00 0.0",year, month); break; case NCtimeDay: sprintf (tsUnitStr,"days since %04d-%02d-%02d 00:00 0.0",year, month, day); break; case NCtimeHour: sprintf (tsUnitStr,"hours since %04d-%02d-%02d %02d:00 0.0",year, month, day, hour); break; case NCtimeMinute: sprintf (tsUnitStr,"minutes since %04d-%02d-%02d %02d:%02d 0.0", year, month, day, hour, minute); break; case NCtimeSecond: sprintf (tsUnitStr,"seconds since %04d-%02d-%02d %02d:%02d %.1f", year, month, day, hour, minute, second); break; } if (tsMode > NCtimeMonth) { if ((utScan (tsUnitStr, &tUnitOut) != 0) || (utConvert (tUnitIn, &tUnitOut, &scale, &offset) != 0)) { CMmsgPrint (CMmsgAppError, "Time unit scanning error in: %s %d",__FILE__,__LINE__); goto ABORT; } sTime = sTime * scale + offset; eTime = eTime * scale + offset; } else { sTime = 0.0; eTime = tsMode > NCtimeYear ? (endYear - year) * 12 + (endMonth - month + 1) : (double) (year - endYear); } do { if (tsMode > NCtimeMonth) { if (utCalendar (sTime + time,&tUnitOut,&year,&month,&day,&hour,&minute,&second) != 0) { CMmsgPrint (CMmsgAppError, "Time unit scaning error in: %s %d",__FILE__,__LINE__); goto ABORT; } } strcpy (searchStr, pattern); for (i = 0;i < tsMode; ++i) if ((subStr = strstr (searchStr,str [i])) == (char *) NULL) break; else { strOffset = strlen (str [i]); strLen = strlen (subStr) - strOffset; switch (i) { case NCtimeYear: sprintf (subStr,"%04d", year); subStr += 4; strOffset -= 4; break; case NCtimeMonth: sprintf (subStr,"%02d", month); subStr += 2; strOffset -= 2; break; case NCtimeDay: sprintf (subStr,"%02d", day); subStr += 2; strOffset -= 2; break; case NCtimeHour: sprintf (subStr,"%02d", hour); subStr += 2; strOffset -= 2; break; case NCtimeMinute: sprintf (subStr,"%02d", minute); subStr += 2; strOffset -= 2; break; case NCtimeSecond: sprintf (subStr,"%04.1f",second); subStr += 4; strOffset -= 4; break; } for (j = 0;j <= strLen; j++) subStr [j] = subStr [j + strOffset]; } if ((ncNum == 0) || (strcmp (fileNames [ncNum - 1], searchStr) != 0)) { if (((fileNames = (char **) realloc (fileNames, (ncNum + 1) * sizeof (char *))) == (char **) NULL) || ((ncids = (int *) realloc (ncids, (ncNum + 1) * sizeof (int))) == (int *) NULL)) { CMmsgPrint (CMmsgSysError, "Memory allocation error in: %s %d",__FILE__,__LINE__); goto ABORT; } else ncNum++; if ((fileNames [ncNum - 1] = (char *) malloc (strlen (searchStr) + 1)) == (char *) NULL) { CMmsgPrint (CMmsgSysError, "Memory allocation error in: %s %d",__FILE__,__LINE__); goto ABORT; } strcpy (fileNames [ncNum - 1], searchStr); if (((ncids [ncNum - 1] = NCfileCreate (fileNames [ncNum - 1], dncid)) == NCfailed) || (NCfileVarAdd (ncids [ncNum - 1], name, NC_FLOAT, NC_DOUBLE, NC_FLOAT) == NCfailed) || (NCfileSetTimeUnit (ncids [ncNum - 1], tsUnitStr) == NCfailed) || (NCfileSetMissingVal (ncids [ncNum - 1], -9999.0) == NCfailed) || ((tvarid = NCdataGetTVarId (ncids [ncNum - 1])) == NCfailed)) goto ABORT; index = 0; } if ((status = nc_put_var1_double (ncids [ncNum - 1],tvarid,&index, &time)) != NC_NOERR) { NCprintNCError (status,"NCdsHandleCreate"); goto ABORT; } index++; if (tsMode == NCtimeMonth) { month++; if (month > 12) { month = 1; year++;} } if (tsMode == NCtimeYear) { year++; } time = time + 1.0; } while ((sTime + time) < eTime); for (i = 0;i < ncNum; i++) nc_sync (ncids [i]); if ((dsh = NCdsHandleOpenByIds (ncids, ncNum)) == (NCdsHandle_t *) NULL) goto ABORT; for (i = 0;i < ncNum; i++) free (fileNames [i]); utClear (&tUnitOut); free (fileNames); free (ncids); free (searchStr); return (dsh); ABORT: for (i = 0;i < ncNum;i++) { nc_abort (ncids [i]); unlink (fileNames [i]); if (fileNames [i] != (char *) NULL) free (fileNames [i]); } utClear (&tUnitOut); if (fileNames != (char **) NULL) free (fileNames); free (searchStr); return ((NCdsHandle_t *) NULL); }
NCstate NCdsHandleGContDefine(NCdsHandleGCont_t *gCont, int *ncids, size_t n) { int status, varid, i; int missingInt, fillInt; double missingFloat, fillFloat, scale, offset; size_t unitlen, row, col; char unitstr[NC_MAX_NAME], gunitstr[NC_MAX_NAME]; gCont->Data = (double *) NULL; gCont->AuxData = (double *) NULL; gCont->ObsNum = (size_t *) NULL; gCont->MeanIds = gCont->MinIds = gCont->MaxIds = gCont->StdIds = (int *) NULL; if (n < 1) return (NCfailed); if (NCdsHandleGridDefine((NCdsHandleGrid_t *) gCont, ncids, n) == NCfailed) return (NCfailed); if (gCont->DataType != NCtypeGCont) { CMmsgPrint(CMmsgAppError, "Invalid grid data in: %s %d", __FILE__, __LINE__); NCdsHandleGridClear((NCdsHandleGrid_t *) gCont); return (NCfailed); } if (((gCont->MeanIds = (int *) calloc(n, sizeof(int))) == (int *) NULL) || ((gCont->MinIds = (int *) calloc(n, sizeof(int))) == (int *) NULL) || ((gCont->MaxIds = (int *) calloc(n, sizeof(int))) == (int *) NULL) || ((gCont->StdIds = (int *) calloc(n, sizeof(int))) == (int *) NULL) || ((gCont->Data = (double *) calloc(gCont->ColNum * gCont->RowNum, sizeof(double))) == (double *) NULL) || ((gCont->AuxData = (double *) calloc(gCont->ColNum * gCont->RowNum, sizeof(double))) == (double *) NULL) || ((gCont->ObsNum = (size_t *) calloc(gCont->ColNum * gCont->RowNum, sizeof(size_t))) == (size_t *) NULL)) { CMmsgPrint(CMmsgSysError, "Memory allocation error in: %s %d", __FILE__, __LINE__); if (gCont->MeanIds != (int *) NULL) free(gCont->MeanIds); if (gCont->MinIds != (int *) NULL) free(gCont->MinIds); if (gCont->MaxIds != (int *) NULL) free(gCont->MaxIds); if (gCont->StdIds != (int *) NULL) free(gCont->StdIds); NCdsHandleGridClear((NCdsHandleGrid_t *) gCont); return (NCfailed); } for (i = 0; i < n; ++i) gCont->MeanIds[i] = gCont->MinIds[i] = gCont->MaxIds[i] = gCont->StdIds[i] = NCundefined; for (i = 0; i < n; ++i) { switch (gCont->GType) { default: gCont->FillValue.Float = gCont->MissingVal.Float = FLOAT_NOVALUE; break; case NC_BYTE: case NC_SHORT: case NC_INT: if ((status = nc_get_att_int(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAFillValue, &fillInt)) != NC_NOERR) { if ((status = nc_get_att_int(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAMissingVal, &missingInt)) != NC_NOERR) missingInt = fillInt = INT_NOVALUE; else fillInt = missingInt; } else if ((status = nc_get_att_int(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAMissingVal, &missingInt)) != NC_NOERR) missingInt = fillInt; break; case NC_FLOAT: case NC_DOUBLE: if ((status = nc_get_att_double(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAFillValue, &fillFloat)) != NC_NOERR) { if ((status = nc_get_att_double(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAMissingVal, &missingFloat)) != NC_NOERR) missingFloat = fillFloat = FLOAT_NOVALUE; else fillFloat = missingFloat; } else if ((status = nc_get_att_double(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAMissingVal, &missingFloat)) != NC_NOERR) missingFloat = fillFloat; break; } if ((status = nc_get_att_double(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAScaleFactor, &scale)) != NC_NOERR) scale = 1.0; if ((status = nc_get_att_double(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAAddOffset, &offset)) != NC_NOERR) offset = 0.0; if (((status = nc_inq_attlen(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAUnits, &unitlen)) == NC_NOERR) && ((status = nc_get_att_text(gCont->NCIds[i], gCont->GVarIds[i], NCnameVAUnits, unitstr)) == NC_NOERR)) unitstr[unitlen] = '\0'; if (i == 0) { if ((status == NC_NOERR) && (utScan(unitstr, &(gCont->GUnit)) == 0)) { gCont->DoGUnit = true; strcpy (gunitstr, unitstr); } else gCont->DoGUnit = false; switch (gCont->GType) { case NC_BYTE: case NC_SHORT: case NC_INT: gCont->FillValue.Int = fillInt; gCont->MissingVal.Int = missingInt; break; default: case NC_FLOAT: case NC_DOUBLE: gCont->FillValue.Float = fillFloat; gCont->MissingVal.Float = missingFloat; break; } gCont->Scale = scale; gCont->Offset = offset; } else { if (gCont->DoGUnit && ((status != NC_NOERR) || strcmp(unitstr, gunitstr) != 0)) { CMmsgPrint(CMmsgAppError, "Inconsistent data bundle (units) in: %s %d", __FILE__, __LINE__); return (NCfailed); } switch (gCont->GType) { case NC_BYTE: case NC_SHORT: case NC_INT: if ((gCont->FillValue.Int != fillInt) || (gCont->MissingVal.Int != missingInt)) { CMmsgPrint(CMmsgAppError, "Inconsistent data bundle (int fill value) in: %s %d", __FILE__, __LINE__); return (NCfailed); } break; default: case NC_FLOAT: case NC_DOUBLE: if ((NCmathEqualValues(gCont->FillValue.Float, fillFloat) == false) || (NCmathEqualValues(gCont->MissingVal.Float, missingFloat) == false)) { CMmsgPrint(CMmsgAppError, "Inconsistent bundle (float fill value) in: %s %d", __FILE__, __LINE__); return (NCfailed); } break; } if ((NCmathEqualValues(gCont->Scale, scale) == false) || (NCmathEqualValues(gCont->Offset, offset) == false)) { CMmsgPrint(CMmsgAppError, "Inconsistent bundle (scale and offset) in: %s %d", __FILE__, __LINE__); return (NCfailed); } } gCont->MeanIds[i] = nc_inq_varid(ncids[i], NCnameVAAverage, &varid) == NC_NOERR ? varid : NCundefined; gCont->MaxIds[i] = nc_inq_varid(ncids[i], NCnameVAMaximum, &varid) == NC_NOERR ? varid : NCundefined; gCont->MinIds[i] = nc_inq_varid(ncids[i], NCnameVAMinimum, &varid) == NC_NOERR ? varid : NCundefined; gCont->StdIds[i] = nc_inq_varid(ncids[i], NCnameVAStdDev, &varid) == NC_NOERR ? varid : NCundefined; } for (row = 0; row < gCont->RowNum; row++) for (col = 0; col < gCont->ColNum; col++) NCdsHandleGContSetFill(gCont, row, col); return (NCsucceeded); }
int /* [rcd] Successful conversion returns NCO_NOERR */ nco_cln_clc_dff /* [fnc] UDUnits1 Difference between two co-ordinate units */ (const char *fl_unt_sng, /* I [ptr] units attribute string from disk */ const char *fl_bs_sng, /* I [ptr] units attribute string from disk */ double crr_val, double *og_val) /* O [ptr] */ { const char fnc_nm[]="nco_cln_clc_dff()"; /* [sng] Function name */ double slp; double incpt; int rcd; utUnit udu_sct_in; /* UDUnits structure, input units */ utUnit udu_sct_out; /* UDUnits structure, output units */ /* Quick return if units identical */ if(!strcmp(fl_unt_sng,fl_bs_sng) ){ *og_val=crr_val; return NCO_NOERR; } /* endif */ #ifdef UDUNITS_PATH /* UDUNITS_PATH macro expands to where autoconf found database file */ rcd=utInit(UDUNITS_PATH); #else /* !UDUNITS_PATH */ /* When empty, utInit() uses environment variable UDUNITS_PATH, if any Otherwise it uses default initial location hardcoded when library was built */ rcd=utInit(""); #endif /* !UDUNITS_PATH */ if(rcd != UDUNITS_NOERR){ (void)fprintf(stdout,"%s: %s failed to initialize UDUnits2 library\n",nco_prg_nm_get(),fnc_nm); return NCO_ERR; } /* end if err */ /* units string to convert from */ rcd=utScan(fl_unt_sng,&udu_sct_in); if(rcd != UDUNITS_NOERR){ if(rcd == UT_EINVALID) (void)fprintf(stderr,"ERROR: units attribute \"%s\" is invalid \n",fl_unt_sng); if(rcd == UT_ESYNTAX) (void)fprintf(stderr,"ERROR units attribute \"%s\" contains a syntax error",fl_unt_sng); if(rcd == UT_EUNKNOWN) (void)fprintf(stderr,"ERROR units attribute \"%s\" is not in udunits database",fl_unt_sng); (void)utTerm(); /* Free memory taken by UDUnits library */ return NCO_ERR; } /* endif unkown type */ /* units string to convert to */ rcd=utScan(fl_bs_sng,&udu_sct_out); if(rcd != UDUNITS_NOERR){ if(rcd == UT_EINVALID) (void)fprintf(stderr,"ERROR: units attribute \"%s\" is invalid \n",fl_bs_sng); if(rcd == UT_ESYNTAX) (void)fprintf(stderr,"ERROR units attribute \"%s\" contains a syntax error",fl_bs_sng); if(rcd == UT_EUNKNOWN) (void)fprintf(stderr,"ERROR units attribute \"%s\" is not in udunits database",fl_bs_sng); (void)utTerm(); /* Free memory taken by UDUnits library */ return NCO_ERR; } /* endif unkown type */ rcd=utConvert(&udu_sct_in,&udu_sct_out,&slp,&incpt); if(rcd == UT_ECONVERT){ (void)fprintf(stderr,"ERROR: user specified unit \"%s\" cannot be converted to units \"%s\"\n",fl_unt_sng,fl_bs_sng); (void)utTerm(); return NCO_ERR; } /* endif */ *og_val=crr_val*slp+incpt; /* debug stuff */ if(nco_dbg_lvl_get() > nco_dbg_std) (void)fprintf(stderr,"%s: %s reports difference between systems \"%s\" and \"%s\" is %f\n",nco_prg_nm_get(),fnc_nm,fl_unt_sng,fl_bs_sng,*og_val); (void)utTerm(); return NCO_NOERR; } /* end UDUnits1 nco_cln_clc_dff() */