/*========================================================================================== * The user specified some origin to the time units. For example, if the units string * were "days since 2005-10-15", then the origin date is 2005-10-15. This routine * deduces the specified origin date from the passed units structure */ static void get_origin( ut_unit *dataunits, int *y0, int *mon0, int *d0, int *h0, int *min0, double *s0 ) { double s0lib, rez, tval, tval_conv, resolution; cv_converter *conv_user_date_to_ref_date; ut_unit *tmpu; int y0lib, mon0lib, d0lib, h0lib, min0lib; char ustr[1024]; static ut_unit *udu_ref_date=NULL; /* Saved between invocations */ if( udu_ref_date == NULL ) { /* Make a timestamp units that refers to the udunits2 library's intrinsic * time origin. The first thing we do is parse a timestampe unit * (any old timestamp unit) and immediately discard the result, to account * for a bug in the udunits-2 library that fails to set the library's * time origin unless this step is done first. Without this, a call to * ut_decode_time with tval==0 returns year=-4713 rather than 2001. */ if( (tmpu = ut_parse( ut_get_system(dataunits), "days since 2010-01-09", UT_ASCII )) == NULL ) { fprintf( stderr, "Internal error in routnie utCalendar2/get_origin: failed to parse temp timestamp string\n" ); exit(-1); } ut_free( tmpu ); tval = 0.0; ut_decode_time( tval, &y0lib, &mon0lib, &d0lib, &h0lib, &min0lib, &s0lib, &rez ); sprintf( ustr, "seconds since %04d-%02d-%02d %02d:%02d:%f", y0lib, mon0lib, d0lib, h0lib, min0lib, s0lib ); udu_ref_date = ut_parse( ut_get_system(dataunits), ustr, UT_ASCII ); if( udu_ref_date == NULL ) { fprintf( stderr, "internal error in routine utCalendar2/get_origin: could not parse origin string \"%s\"\n", ustr ); exit(-1); } } /* Get converter from passed units to the library's intrinsic time units */ conv_user_date_to_ref_date = ut_get_converter( dataunits, udu_ref_date ); /* convert tval=0 to ref date */ tval = 0.0; tval_conv = cv_convert_double( conv_user_date_to_ref_date, tval ); /* Now decode the converted value */ ut_decode_time( tval_conv, y0, mon0, d0, h0, min0, s0, &resolution ); cv_free( conv_user_date_to_ref_date ); }
void cmor_convert_value( char *units, char *ctmp, double *tmp ) { /* -------------------------------------------------------------------- */ /* Local variables */ /* -------------------------------------------------------------------- */ ut_unit *user_units = NULL, *cmor_units = NULL; cv_converter *ut_cmor_converter = NULL; double value; char msg[CMOR_MAX_STRING]; cmor_add_traceback( "cmor_convert_value" ); value = *tmp; if( units[0] != '\0' ) { cmor_prep_units( ctmp, units, &cmor_units, &user_units, &ut_cmor_converter ); *tmp = cv_convert_double( ut_cmor_converter, value ); if( ut_get_status( ) != UT_SUCCESS ) { snprintf( msg, CMOR_MAX_STRING, "Udunits: Error converting units from %s to %s", units, ctmp ); cmor_handle_error( msg, CMOR_CRITICAL ); } cv_free( ut_cmor_converter ); if( ut_get_status( ) != UT_SUCCESS ) { snprintf( msg, CMOR_MAX_STRING, "Udunits: Error freeing converter" ); cmor_handle_error( msg, CMOR_CRITICAL ); } ut_free( cmor_units ); if( ut_get_status( ) != UT_SUCCESS ) { snprintf( msg, CMOR_MAX_STRING, "Udunits: Error freeing units" ); cmor_handle_error( msg, CMOR_CRITICAL ); } ut_free( user_units ); if( ut_get_status( ) != UT_SUCCESS ) { snprintf( msg, CMOR_MAX_STRING, "Udunits: Error freeing units" ); cmor_handle_error( msg, CMOR_CRITICAL ); } } else *tmp = value; cmor_pop_traceback( ); return; }
/* * match_variable * INPUT: * string Input string to match * pvt variable type (from definition) * cmd variable string (from definition) - can contain range * RETURNS: * -1 Error (print msg on stderr) * 0 Not match and reason returned as malloced string. * 1 Match * Who prints errors? */ static int match_variable(cg_obj *co, char *str, char **reason) { int retval = -1; cg_var *cv; cg_varspec *cs; cs = &co->u.cou_var; if ((cv = cv_new(co->co_vtype)) == NULL) goto done; if ((retval = cv_parse1(str, cv, reason)) <= 0) goto done; retval = cv_validate(cv, cs, reason); done: if (cv) cv_free(cv); return retval; }
/*======================================================================================== * Turns the passed value into a Y/M/D date */ int utCalendar2_cal( double val, ut_unit *dataunits, int *year, int *month, int *day, int *hour, int *minute, double *second, const char *calendar_name ) { int jdnew, ndinc, ierr, iorig, iround; double fdays, extra_seconds, tot_extra_seconds; int ndays; calcalcs_cal *cal2use; /* Following vars are saved between invocations and reused if the * passed units are the same as last time. */ static ut_unit *prev_units=NULL; static cv_converter *conv_user_units_to_days=NULL; static int y0, mon0, d0, h0, min0, jday0; static double s0, extra_seconds0; static char *prev_calendar=NULL; if( dataunits == NULL ) { fprintf( stderr, "Error, utCalendar2 passed a NULL units\n" ); return( UT_ENOINIT ); } if( have_initted == 0 ) initialize( ut_get_system(dataunits) ); /* Get the calendar we will be using, based on the passed name */ cal2use = getcal( calendar_name ); if( cal2use == NULL ) { unknown_cal_emit_warning( calendar_name ); cal2use = getcal( "Standard" ); } /* See if we are being passed the same units and calendar as last time. If so, * we can optimize by not recomputing all this junk */ if( (prev_units != NULL) && (prev_calendar != NULL) && (strcmp(prev_calendar,cal2use->name)==0) && (ut_compare( prev_units, dataunits ) == 0)) { /* Units and calendar are same as used last call */ } else { /* Units/calendar combo are different from previously saved units, must redo calcs */ if( prev_units != NULL ) ut_free( prev_units ); if( prev_calendar != NULL ) free( prev_calendar ); /* Get origin day of the data units */ get_origin( dataunits, &y0, &mon0, &d0, &h0, &min0, &s0 ); /* Note: static vars */ /* Number of seconds into the specified origin day */ extra_seconds0 = h0*3600.0 + min0*60.0 + s0; /* Note: static vars */ /* Convert the origin day to Julian Day number in the specified calendar */ if( (ierr = ccs_date2jday( cal2use, y0, mon0, d0, &jday0 )) != 0 ) { fprintf( stderr, "Error in utCalendar2: %s\n", ccs_err_str(ierr) ); return( UT_EINVALID ); } /* Get converter from user-specified units to "days" */ if( conv_user_units_to_days != NULL ) cv_free( conv_user_units_to_days ); conv_user_units_to_days = get_user_to_day_converter( dataunits, y0, mon0, d0, h0, min0, s0 ); /* Save these units so we can reuse our time-consuming * calculations next time if they are the same units */ prev_units = ut_clone( dataunits ); if( ut_compare( prev_units, dataunits ) != 0 ) { fprintf( stderr, "error, internal error in udunits2 library found in routine utCalendar2: a clone of the user's units does not equal the original units!\n" ); exit(-1); } prev_calendar = (char *)malloc( sizeof(char) * (strlen(cal2use->name)+1 )); strcpy( prev_calendar, cal2use->name ); } /* Convert user value of offset to floating point days */ fdays = cv_convert_double( conv_user_units_to_days, val ); /* Get integer number of days and seconds past that */ ndays = fdays; extra_seconds = (fdays - ndays)*86400.0; /* Get new Julian day */ jdnew = jday0 + ndays; /* Handle the sub-day part */ tot_extra_seconds = extra_seconds0 + extra_seconds; ndinc = tot_extra_seconds / 86400.0; jdnew += ndinc; tot_extra_seconds -= ndinc*86400.0; if( tot_extra_seconds < 0.0 ) { tot_extra_seconds += 86400.0; jdnew--; } /* Convert to a date */ if( (ierr = ccs_jday2date( cal2use, jdnew, year, month, day )) != 0 ) { fprintf( stderr, "Error in utCalendar2: %s\n", ccs_err_str(ierr) ); return( UT_EINVALID ); } *hour = tot_extra_seconds / 3600.0; tot_extra_seconds -= *hour * 3600.0; *minute = tot_extra_seconds / 60.0; tot_extra_seconds -= *minute * 60.0; *second = tot_extra_seconds; /* Handle the rouding issues */ iorig = *second; /* Integer conversion */ iround = *second + sec_rounding_value; if( iround > iorig ) { /* printf( "rounding alg invoked, orig date: %04d-%02d-%02d %02d:%02d:%.20lf\n", *year, *month, *day, *hour, *minute, *second ); */ *second = (double)iround; if( *second >= 60.0 ) { *second -= 60.0; *minute += 1.0; if( *minute >= 60.0 ) { *minute -= 60.0; *hour += 1.0; if( *hour >= 24.0 ) { *hour -= 24.0; if( (ierr = ccs_jday2date( cal2use, jdnew+1, year, month, day )) != 0 ) { fprintf( stderr, "Error in utCalendar2: %s\n", ccs_err_str(ierr) ); return( UT_EINVALID ); } } } } /* printf( "after rounding alg here is new date: %04d-%02d-%02d %02d:%02d:%02.20lf\n", *year, *month, *day, *hour, *minute, *second ); */ } return(0); }
/*======================================================================================== * Turn the passed Y/M/D date into a value in the user's units */ int utInvCalendar2_cal( int year, int month, int day, int hour, int minute, double second, ut_unit *user_unit, double *value, const char *calendar_name ) { int jday, ierr, diff_in_days; double fdiff_in_days, val_days, val_partdays, fdiff_in_partdays, fpartday; calcalcs_cal *cal2use; /* Following vars are static and retained between invocations for efficiency */ static ut_unit *prev_units=NULL; static int y0, mon0, d0, h0, min0, jday0; static double s0, fpartday0; static cv_converter *conv_days_to_user_units=NULL; static char *prev_calendar=NULL; if( have_initted == 0 ) initialize( ut_get_system(user_unit) ); /* Get the calendar we will be using, based on the passed name */ cal2use = getcal( calendar_name ); if( cal2use == NULL ) { unknown_cal_emit_warning( calendar_name ); cal2use = getcal( "Standard" ); } if( (prev_units != NULL) && (prev_calendar != NULL) && (strcmp(prev_calendar,cal2use->name)==0) && (ut_compare( prev_units, user_unit ) == 0)) { /* Units are same as used last call */ } else { if( prev_units != NULL ) ut_free( prev_units ); if( prev_calendar != NULL ) free( prev_calendar ); if( conv_days_to_user_units != NULL ) cv_free( conv_days_to_user_units ); /* Get origin day of the data units */ get_origin( user_unit, &y0, &mon0, &d0, &h0, &min0, &s0 ); /* Note: static vars */ /* Convert the origin day to Julian Day number in the specified calendar */ if( (ierr = ccs_date2jday( cal2use, y0, mon0, d0, &jday0 )) != 0 ) { fprintf( stderr, "Error in utCalendar2: %s\n", ccs_err_str(ierr) ); return( UT_EINVALID ); } /* Get the origin's HMS in fractional (floating point) part of a Julian day */ fpartday0 = (double)h0/24.0 + (double)min0/1440.0 + s0/86400.0; /* Get converter for turning days into user's units */ conv_days_to_user_units = get_day_to_user_converter( user_unit, y0, mon0, d0, h0, min0, s0 ); /* Save these units so we can reuse our time-consuming * calculations next time if they are the same units */ prev_units = ut_clone( user_unit ); if( ut_compare( prev_units, user_unit ) != 0 ) { fprintf( stderr, "error, internal error in udunits2 library found in routine utInvCalendar2: a clone of the user's units does not equal the original units!\n" ); exit(-1); } prev_calendar = (char *)malloc( sizeof(char) * (strlen(cal2use->name)+1 )); strcpy( prev_calendar, cal2use->name ); } /* Turn passed date into a Julian day */ if( (ierr = ccs_date2jday( cal2use, year, month, day, &jday )) != 0 ) { fprintf( stderr, "Error in utInvCalendar2: %s\n", ccs_err_str(ierr) ); return( UT_EINVALID ); } /* jday and jday0 can be very large and nearly equal, so we difference * them first to keep the precision high */ diff_in_days = jday - jday0; fdiff_in_days = (double)diff_in_days; /* Get the fractional (floating point) part of a Julian day difference */ fpartday = (double)hour/24.0 + (double)minute/1440.0 + second/86400.0; fdiff_in_partdays = fpartday - fpartday0; /* Convert days and partial days to user's units */ val_days = cv_convert_double( conv_days_to_user_units, fdiff_in_days ); val_partdays = cv_convert_double( conv_days_to_user_units, fdiff_in_partdays ); /* Hopefully this will minimize the roundoff errors */ *value = val_days + val_partdays; return(0); }
NFio_p Open_NCgrid(const char *url, NFtime_p beginTime, NFtime_p endTime, ut_system *utSystem) { int status, ncid; size_t i; const char *urlAddress; NCurlType urlType; NFio_p io = (NFio_p) NULL; NFtime_p timePtr = (NFtime_p) NULL; NFtime_p bundleTime = (NFtime_p) NULL; NFtimeUnit bundleTimeUnit; NFtimeStep_p bundleTimeStep = (NFtimeStep_p) NULL; NCgrid_p ncGrid = (NCgrid_p) NULL; ut_unit *baseTimeUnit = (ut_unit *) NULL; cv_converter *cvConverter = (cv_converter *) NULL; if ((baseTimeUnit = ut_parse(utSystem, "seconds since 2001-01-01 00:00:00", UT_ASCII)) == (ut_unit *) NULL) { CMmsgPrint(CMmsgAppError, "Total metal gebasz in %s:%d!\n", __FILE__, __LINE__); switch (ut_get_status()) { case UT_BAD_ARG: CMmsgPrint(CMmsgAppError, "System or string is NULL!\n"); break; case UT_SYNTAX: CMmsgPrint(CMmsgAppError, "String contained a syntax error!n"); break; case UT_UNKNOWN: CMmsgPrint(CMmsgAppError, "String contained an unknown identifier!\n"); break; default: CMmsgPrint(CMmsgSysError, "System error in %s:%d!n", __FILE__, __LINE__); } goto Abort; } if ((bundleTime = NFtimeCreate()) == (NFtime_p) NULL) { CMmsgPrint(CMmsgAppError, "Time object creation error in %s:%d!\n", __FILE__, __LINE__); goto Abort; } if ((bundleTimeStep = NFtimeStepCreate()) == (NFtimeStep_p) NULL) { CMmsgPrint(CMmsgAppError, "Timestep object creation error in %s:%d!\n", __FILE__, __LINE__); goto Abort; } bundleTimeUnit = NCurlGetBundleTimeUnit(url); if (((urlType = NCurlGetType(url)) == NCurlInvalid) || ((urlAddress = NCurlGetAddress(url)) == (const char *) NULL)) { CMmsgPrint(CMmsgAppError, "Ivalid URL: %s!\n", url); goto Abort; } if ((io = NFioCreate()) == (NFio_p) NULL) { CMmsgPrint(CMmsgAppError, "Layout creation error in: %s:%d\n", __FILE__, __LINE__); goto Abort; } if ((ncGrid = _NCgridCreate()) == (NCgrid_p) NULL) { CMmsgPrint(CMmsgSysError, "Plugin data allocation error in: %s:%d\n", __FILE__, __LINE__); goto Abort; } ncGrid->FileNames[0] = CMstrDuplicate(urlAddress); if (bundleTimeUnit != NFtimeUnitUnset) { ncGrid->FileNames[0] = NCcompleteURLaddress(urlAddress, ncGrid->FileNames[0], bundleTimeUnit, beginTime); NFtimeStepSet(bundleTimeStep, bundleTimeUnit, 1); // TODO handle return value } if ((status = nc_open(ncGrid->FileNames[0], NC_NOWRITE, &(ncGrid->NCid))) != NC_NOERR) { CMmsgPrint(CMmsgAppError, "NetCDF (%s) Openining error \"%s\"!\n", ncGrid->FileNames[0], nc_strerror(status)); goto Abort; } ncGrid->Open = 0; if (!NCaxisInitialize(ncGrid->NCid, ncGrid->X[0], NCaxisX, utSystem)) goto Abort; if (!NCaxisInitialize(ncGrid->NCid, ncGrid->Y[0], NCaxisY, utSystem)) goto Abort; if (!NCaxisInitialize(ncGrid->NCid, ncGrid->Z[0], NCaxisZ, utSystem)) goto Abort; if (!NCaxisInitialize(ncGrid->NCid, ncGrid->Time[0], NCaxisTime, utSystem)) goto Abort; io->ItemNum = ncGrid->X[0]->N * ncGrid->Y[0]->N * ncGrid->Z[0]->N; io->ItemBoxMin.X = ncGrid->X[0]->IntervalMin; io->ItemBoxMin.Y = ncGrid->Y[0]->IntervalMin; io->ItemBoxMax.X = ncGrid->X[0]->IntervalMax; io->ItemBoxMax.Y = ncGrid->Y[0]->IntervalMax; io->Extent.LowerLeft.X = ncGrid->X[0]->Bounds[ncGrid->X[0]->N * 2 - 1] - ncGrid->X[0]->Bounds[0]; io->Extent.LowerLeft.Y = ncGrid->Y[0]->Bounds[ncGrid->Y[0]->N * 2 - 1] - ncGrid->Y[0]->Bounds[0]; if ((cvConverter = ut_get_converter(ncGrid->Time[0]->Unit, baseTimeUnit)) == (cv_converter *) NULL) { CMmsgPrint(CMmsgAppError, "Time converter error!n"); switch (ut_get_status()) { case UT_BAD_ARG: CMmsgPrint(CMmsgAppError, "unit1 or unit2 is NULL.\n"); break; case UT_NOT_SAME_SYSTEM: CMmsgPrint(CMmsgAppError, "unit1 and unit2 belong to different unit-systems."); break; default: CMmsgPrint(CMmsgAppError, "Conversion between the units is not possible."); break; } } io->TimeLine = NCtimeLineExpand(ncGrid->Time[0], beginTime, endTime, cvConverter, io->TimeLine); if (io->TimeLine == (NFtimeLine_p) NULL) { CMmsgPrint(CMmsgAppError, "Timeline expansion error in %s:%d!\n", __FILE__, __LINE__); goto Abort; } cv_free(cvConverter); if ((ncGrid->TimeBundleIDs = (size_t *) realloc(ncGrid->TimeBundleIDs, io->TimeLine->TimeStepNum * sizeof(size_t))) == (size_t *) NULL) { CMmsgPrint(CMmsgSysError, "Memory allocation error in %s:%d!\n", __FILE__, __LINE__); goto Abort; } for (i = 0; i < io->TimeLine->TimeStepNum; ++i) ncGrid->TimeBundleIDs[i] = 0; if (bundleTimeUnit != NFtimeUnitUnset) { NFtimeCopy(beginTime, bundleTime); // TODO handle return value if ((ncGrid = _NCgridRealloc(ncGrid)) == (NCgrid_p) NULL) goto Abort; for (NFtimeAdvance(bundleTime, bundleTimeStep); NFtimeCompare(bundleTime, endTime) < 0; NFtimeAdvance(bundleTime, bundleTimeStep)) { ncGrid->FileNames[ncGrid->FileNum - 1] = NCcompleteURLaddress(urlAddress, CMstrDuplicate(urlAddress), bundleTimeUnit, bundleTime); if ((status = nc_open(ncGrid->FileNames[ncGrid->FileNum - 1], NC_NOWRITE, &ncid)) != NC_NOERR) { CMmsgPrint(CMmsgAppError, "NetCDF (%s) Openining error \"%s\"!\n", ncGrid->FileNames[ncGrid->FileNum - 1], nc_strerror(status)); goto Abort; } if (!NCaxisInitialize(ncid, ncGrid->X[ncGrid->FileNum - 1], NCaxisX, utSystem)) goto Abort; if (!NCaxisInitialize(ncid, ncGrid->Y[ncGrid->FileNum - 1], NCaxisY, utSystem)) goto Abort; if (!NCaxisInitialize(ncid, ncGrid->Z[ncGrid->FileNum - 1], NCaxisZ, utSystem)) goto Abort; if (!NCaxisInitialize(ncid, ncGrid->Time[ncGrid->FileNum - 1], NCaxisTime, utSystem)) goto Abort; nc_close(ncid); if ((ncGrid->X[0]->N != ncGrid->X[ncGrid->FileNum - 1]->N) || (ncGrid->Y[0]->N != ncGrid->Y[ncGrid->FileNum - 1]->N) || (ncGrid->Z[0]->N != ncGrid->Z[ncGrid->FileNum - 1]->N) || (ncGrid->Time[0]->N != ncGrid->Time[ncGrid->FileNum - 1]->N)) { CMmsgPrint(CMmsgUsrError, "Inconsisten NetCDF [%s] bundle!\n", urlAddress); goto Abort; } if ((cvConverter = ut_get_converter(ncGrid->Time[ncGrid->FileNum - 1]->Unit, baseTimeUnit)) == (cv_converter *) NULL) { CMmsgPrint(CMmsgAppError, "Time converter error!n"); switch (ut_get_status()) { case UT_BAD_ARG: CMmsgPrint(CMmsgAppError, "unit1 or unit2 is NULL.\n"); break; case UT_NOT_SAME_SYSTEM: CMmsgPrint(CMmsgAppError, "unit1 and unit2 belong to different unit-systems."); break; default: CMmsgPrint(CMmsgAppError, "Conversion between the units is not possible."); break; } } io->TimeLine = NCtimeLineExpand(ncGrid->Time[ncGrid->FileNum - 1], beginTime, endTime, cvConverter, io->TimeLine); if (io->TimeLine == (NFtimeLine_p) NULL) { CMmsgPrint(CMmsgAppError, "Timeline expansion error in %s:%d!\n", __FILE__, __LINE__); goto Abort; } cv_free(cvConverter); if ((ncGrid->TimeBundleIDs = (size_t *) realloc(ncGrid->TimeBundleIDs, io->TimeLine->TimeStepNum * sizeof(size_t))) == (size_t *) NULL) { CMmsgPrint(CMmsgSysError, "Memory allocation error in %s:%d!\n", __FILE__, __LINE__); goto Abort; } for (; i < io->TimeLine->TimeStepNum; ++i) ncGrid->TimeBundleIDs[i] = ncGrid->FileNum - 1; } } io->PluginData = (void *) ncGrid; io->GetItem = _NCgridGetItem; io->GetItemList = _NCgridGetItemList; io->GetVertexes = _NCgridGetVertexes; io->ProjectXY2UV = NFioDefaultProjectXY2UV; // TODO Handle proj4 entries io->Close = _NCgridClose; io->VarHandleFunc = _NCgridVariableHandle; io->VarTypeFunc = _NCgridVariableType; io->VarLoadFunc = _NCgridVariableLoad; NFtimeFree(timePtr); NFtimeFree(bundleTime); NFtimeStepFree(bundleTimeStep); ut_free(baseTimeUnit); return (io); Abort: nc_close(ncGrid->NCid); if (ncGrid != (NCgrid_p) NULL) _NCgridFree(ncGrid); if (io != (NFio_p) NULL) NFioFree(io); if (timePtr != (NFtime_p) NULL) NFtimeFree(timePtr); if (bundleTime != (NFtime_p) NULL) NFtimeFree(bundleTime); if (bundleTimeStep != (NFtimeStep_p) NULL) NFtimeStepFree(bundleTimeStep); if (baseTimeUnit != (ut_unit *) NULL) ut_free(baseTimeUnit); return ((NFio_p) NULL); }
/*! * Destroys the converter; */ UdUnitConverter::~UdUnitConverter() { cv_free(m_converter); }
void udunits::convert(viennamini::numeric& value, std::string const& source_unit, std::string const& target_unit) { cv_converter* converter = this->get_converter(source_unit, target_unit); value = cv_convert_double(converter, value); cv_free(converter); }
int udu_calc_tgran( int fileid, NCVar *v, int dimid ) { ut_unit *unit, *seconds; int ii, retval; int verbose, has_bounds; double tval0_user, tval0_sec, tval1_user, tval1_sec, delta_sec, bound_min, bound_max; char cval0[1024], cval1[1024]; nc_type rettype; size_t cursor_place[MAX_NC_DIMS]; cv_converter *convert_units_to_sec; NCDim *d; d = *(v->dim+dimid); /* Not enough data to analyze */ if( d->size < 3 ) return(TGRAN_SEC); verbose = 0; if( ! valid_udunits_pkg ) return( 0 ); if( (unit = ut_parse( unitsys, d->units, UT_ASCII )) == NULL ) { fprintf( stderr, "internal error: udu_calc_tgran with invalid unit string: %s\n", d->units ); exit( -1 ); } if( (seconds = ut_parse( unitsys, "seconds", UT_ASCII )) == NULL ) { fprintf( stderr, "internal error: udu_calc_tgran can't parse seconds unit string!\n" ); exit( -1 ); } /* Get converter to convert from "units" to "seconds" */ if( ut_are_convertible( unit, seconds ) == 0 ) { /* Units are not convertible */ return( TGRAN_SEC ); } if( (convert_units_to_sec = ut_get_converter( unit, seconds )) == NULL ) { /* This shouldn't happen */ return( TGRAN_SEC ); } /* Get a delta time to analyze */ for( ii=0L; ii<v->n_dims; ii++ ) cursor_place[ii] = (int)((*(v->size+ii))/2.0); rettype = fi_dim_value( v, dimid, 1L, &tval0_user, cval0, &has_bounds, &bound_min, &bound_max, cursor_place ); rettype = fi_dim_value( v, dimid, 2L, &tval1_user, cval1, &has_bounds, &bound_min, &bound_max, cursor_place ); /* Convert time vals from user units to seconds */ tval0_sec = cv_convert_double( convert_units_to_sec, tval0_user ); tval1_sec = cv_convert_double( convert_units_to_sec, tval1_user ); /* Free our units converter storage */ cv_free( convert_units_to_sec ); delta_sec = fabs(tval1_sec - tval0_sec); if( verbose ) printf( "units: %s t1: %lf t2: %lf delta-sec: %lf\n", d->units, tval0_user, tval1_user, delta_sec ); if( delta_sec < 57. ) { if(verbose) printf("data is TGRAN_SEC\n"); retval = TGRAN_SEC; } else if( delta_sec < 3590. ) { if(verbose) printf("data is TGRAN_MIN\n"); retval = TGRAN_MIN; } else if( delta_sec < 86300. ) { if(verbose) printf("data is TGRAN_HOUR\n"); retval = TGRAN_HOUR; } else if( delta_sec < 86395.*28. ) { if(verbose) printf("data is TGRAN_DAY\n"); retval = TGRAN_DAY; } else if( delta_sec < 86395.*365. ) { if(verbose) printf("data is TGRAN_MONTH\n"); retval = TGRAN_MONTH; } else { if(verbose) printf("data is TGRAN_YEAR\n"); retval = TGRAN_YEAR; } return( retval ); }
static int handleRequest(void) { int success = 0; if (getInputValue()) { if (getOutputRequest()) { if (_wantDefinition) { char buf[256]; ut_unit* unit = ut_scale(_haveUnitAmount, _haveUnit); int nbytes = ut_format(unit, buf, sizeof(buf), _formattingOptions); if (nbytes >= sizeof(buf)) { errMsg("Resulting unit specification is too long"); } else if (nbytes >= 0) { buf[nbytes] = 0; (void)printf(" %s\n", buf); } ut_free(unit); } else if (!ut_are_convertible(_wantUnit, _haveUnit)) { errMsg("Units are not convertible"); } else { cv_converter* conv = ut_get_converter(_haveUnit, _wantUnit); if (conv == NULL) { errMsg("Couldn't get unit converter"); } else { char haveExp[_POSIX_MAX_INPUT+1]; char exp[_POSIX_MAX_INPUT+1]; char whiteSpace[] = " \t\n\r\f\v\xa0"; int needsParens = strpbrk(_wantSpec, whiteSpace) != NULL; int n; (void)printf( needsParens ? " %g %s = %g (%s)\n" : " %g %s = %g %s\n", _haveUnitAmount, _haveUnitSpec, cv_convert_double(conv, _haveUnitAmount), _wantSpec); (void)sprintf(haveExp, strpbrk(_haveUnitSpec, whiteSpace) || strpbrk(_haveUnitSpec, "/") ? "(x/(%s))" : "(x/%s)", _haveUnitSpec); n = cv_get_expression(conv, exp, sizeof(exp), haveExp); if (n >= 0) (void)printf( strpbrk(_wantSpec, whiteSpace) || strpbrk(_wantSpec, "/") ? " x/(%s) = %*s\n" : " x/%s = %*s\n", _wantSpec, n, exp); cv_free(conv); } } success = 1; } } return success; }
// DESTRUCTOR DPC_UnitConvDataStream::~DPC_UnitConvDataStream() { cv_free(cf); delete source_ds; }
/* * Returns a converter corresponding to the sequential application of two * other converters. The returned converter should be passed to cv_free() when * it is no longer needed. * * Arguments: * first The converter to be applied first. May be passed to cv_free() * upon return. * second The converter to be applied second. May be passed to cv_free() * upon return. * Returns: * NULL Either "first" or "second" is NULL or necessary memory couldn't * be allocated. * else A converter corresponding to the sequential application of the * given converters. If one of the input converters is the trivial * converter, then the returned converter will be the other input * converter. */ cv_converter* cv_combine( cv_converter* const first, cv_converter* const second) { cv_converter* conv; if (first == NULL || second == NULL) { conv = NULL; } else if (IS_TRIVIAL(first)) { conv = CV_CLONE(second); } else if (IS_TRIVIAL(second)) { conv = CV_CLONE(first); } else { conv = NULL; if (IS_RECIPROCAL(first)) { if (IS_RECIPROCAL(second)) { conv = cv_get_trivial(); } } else if (IS_SCALE(first)) { if (IS_SCALE(second)) { conv = cv_get_scale(first->scale.value * second->scale.value); } else if (IS_OFFSET(second)) { conv = cv_get_galilean(first->scale.value, second->offset.value); } else if (IS_GALILEAN(second)) { conv = cv_get_galilean( first->scale.value * second->galilean.slope, second->galilean.intercept); } } else if (IS_OFFSET(first)) { if (IS_SCALE(second)) { conv = cv_get_galilean(second->scale.value, first->offset.value * second->scale.value); } else if (IS_OFFSET(second)) { conv = cv_get_offset(first->offset.value + second->offset.value); } else if (IS_GALILEAN(second)) { conv = cv_get_galilean(second->galilean.slope, first->offset.value * second->galilean.slope + second->galilean.intercept); } } else if (IS_GALILEAN(first)) { if (IS_SCALE(second)) { conv = cv_get_galilean( second->scale.value * first->galilean.slope, second->scale.value * first->galilean.intercept); } else if (IS_OFFSET(second)) { conv = cv_get_galilean(first->galilean.slope, first->galilean.intercept + second->offset.value); } else if (IS_GALILEAN(second)) { conv = cv_get_galilean( second->galilean.slope * first->galilean.slope, second->galilean.slope * first->galilean.intercept + second->galilean.intercept); } } if (conv == NULL) { /* * General case: create a composite converter. */ cv_converter* c1 = CV_CLONE(first); int error = 1; if (c1 != NULL) { cv_converter* c2 = CV_CLONE(second); if (c2 != NULL) { conv = malloc(sizeof(CompositeConverter)); if (conv != NULL) { conv->composite.ops = &compositeOps; conv->composite.first = c1; conv->composite.second = c2; error = 0; } /* "conv" allocated */ if (error) cv_free(c2); } /* "c2" allocated */ if (error) cv_free(c1); } /* "c1" allocated */ } /* "conv != NULL" */ } /* "first" & "second" not trivial */ return conv; }
int /* [rcd] Return code */ nco_cln_clc_dff /* [fnc] UDUnits2 Compute difference between two coordinate 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 [] Difference between two units strings */ { const char fnc_nm[]="nco_cln_clc_dff()"; /* [sng] Function name */ cv_converter *ut_cnv; /* UDUnits converter */ int ut_rcd; /* [enm] UDUnits2 status */ ut_system *ut_sys; ut_unit *ut_sct_in; /* [sct] UDUnits structure, input units */ ut_unit *ut_sct_out; /* [sct] UDUnits structure, output units */ /* Quick return if units identical */ if(!strcasecmp(fl_unt_sng,fl_bs_sng)){ *og_val=crr_val; return NCO_NOERR; } /* end if */ /* When empty, ut_read_xml() uses environment variable UDUNITS2_XML_PATH, if any Otherwise it uses default initial location hardcoded when library was built */ if(nco_dbg_lvl_get() >= nco_dbg_vrb) ut_set_error_message_handler(ut_write_to_stderr); else ut_set_error_message_handler(ut_ignore); ut_sys=ut_read_xml(NULL); if(ut_sys == NULL){ (void)fprintf(stdout,"%s: %s() failed to initialize UDUnits2 library\n",nco_prg_nm_get(),fnc_nm); return NCO_ERR; /* Failure */ } /* end if err */ /* Units string to convert from */ ut_sct_in=ut_parse(ut_sys,fl_unt_sng,UT_ASCII); if(!ut_sct_in){ /* Problem with 'units' attribute */ ut_rcd=ut_get_status(); /* [enm] UDUnits2 status */ if(ut_rcd == UT_BAD_ARG) (void)fprintf(stderr,"ERROR: empty units attribute string\n"); if(ut_rcd == UT_SYNTAX) (void)fprintf(stderr,"ERROR: units attribute \"%s\" has a syntax error\n",fl_unt_sng); if(ut_rcd == UT_UNKNOWN) (void)fprintf(stderr,"ERROR: units attribute \"%s\" is not listed in UDUnits2 SI system database\n",fl_unt_sng); return NCO_ERR; /* Failure */ } /* endif coordinate on disk has no units attribute */ /* Units string to convert to */ ut_sct_out=ut_parse(ut_sys,fl_bs_sng,UT_ASCII); if(!ut_sct_out){ /* Problem with 'units' attribute */ ut_rcd=ut_get_status(); /* [enm] UDUnits2 status */ if(ut_rcd == UT_BAD_ARG) (void)fprintf(stderr,"ERROR: Empty units attribute string\n"); if(ut_rcd == UT_SYNTAX) (void)fprintf(stderr,"ERROR: units attribute \"%s\" has a syntax error\n",fl_bs_sng); if(ut_rcd == UT_UNKNOWN) (void)fprintf(stderr,"ERROR: units attribute \"%s\" is not listed in UDUnits2 SI system database\n",fl_bs_sng); return NCO_ERR; /* Failure */ } /* endif */ /* Create converter */ ut_cnv=ut_get_converter(ut_sct_in,ut_sct_out); /* UDUnits converter */ if(!ut_cnv){ ut_rcd=ut_get_status(); /* [enm] UDUnits2 status */ if(ut_rcd == UT_BAD_ARG) (void)fprintf(stderr,"WARNING: One of units, %s or %s, is NULL\n",fl_bs_sng,fl_unt_sng); if(ut_rcd == UT_NOT_SAME_SYSTEM) (void)fprintf(stderr,"WARNING: Units %s and %s belong to different unit systems\n",fl_bs_sng,fl_unt_sng); if(ut_rcd == UT_MEANINGLESS) (void)fprintf(stderr,"WARNING: Conversion between user-specified unit \"%s\" and file units \"%s\" is meaningless\n",fl_bs_sng,fl_unt_sng); return NCO_ERR; /* Failure */ } /* endif */ /* Convert */ *og_val=cv_convert_double(ut_cnv,crr_val); if(nco_dbg_lvl_get() >= nco_dbg_var) fprintf(stderr, "%s: INFO %s() reports conversion between systems \"%s\" and \"%s\" is %f\n",nco_prg_nm_get(),fnc_nm,fl_unt_sng,fl_bs_sng,*og_val); ut_free(ut_sct_in); ut_free(ut_sct_out); cv_free(ut_cnv); ut_free_system(ut_sys); /* Free memory taken by UDUnits library */ return NCO_NOERR; } /* end UDUnits2 nco_cln_clc_dff() */