/* * Compute the conversion factor between two unit-structures. */ int utConvert( const utUnit *from, const utUnit *to, double *slope, double *intercept) { int status; cv_converter* converter = ut_get_converter(from->unit2, to->unit2); if (converter == NULL) { status = ut_get_status(); if (status == UT_BAD_ARG) { status = UT_EINVALID; } else if (status == UT_NOT_SAME_SYSTEM) { status = UT_ENOINIT; } else if (status == UT_MEANINGLESS) { status = UT_ECONVERT; } else { status = UT_EALLOC; } } else { *intercept = cv_convert_double(converter, 0.0); *slope = cv_convert_double(converter, 1.0) - *intercept; status = 0; } return status; }
/*============================================================================================== * Get a converter that turns days into the user's units */ static cv_converter *get_day_to_user_converter( ut_unit *uu, int y0, int mon0, int d0, int h0, int min0, double s0 ) { char daystr[1024]; ut_unit *udu_days; cv_converter *conv_days_to_user_units; sprintf( daystr, "days since %04d-%02d-%02d %02d:%02d:%f", y0, mon0, d0, h0, min0, s0 ); udu_days = ut_parse( ut_get_system(uu), daystr, UT_ASCII ); if( udu_days == NULL ) { fprintf( stderr, "internal error in utCalendar2/conv_to_user_units: failed to parse following string: \"%s\"\n", daystr ); exit(-1); } conv_days_to_user_units = ut_get_converter( udu_days, uu ); if( conv_days_to_user_units == NULL ) { fprintf( stderr, "internal error in utCalendar2/conv_to_user_units: cannot convert from user units to \"%s\"\n", daystr ); exit(-1); } free( udu_days ); return( conv_days_to_user_units ); }
/* * Convert a temporal value into a UTC Gregorian date and time. */ int utCalendar( double value, const utUnit *unit, int *year, int *month, int *day, int *hour, int *minute, float *second) { int status = 0; /* success */ cv_converter* converter = ut_get_converter(unit->unit2, encodedTimeUnit); if (converter == NULL) { status = encodedTimeUnit == NULL ? UT_ENOINIT : UT_EINVALID; } else { double encodedTime = cv_convert_double(converter, value); double sec, res; ut_decode_time(encodedTime, year, month, day, hour, minute, &sec, &res); *second = (float)sec; cv_free(converter); } return status; }
/* * Convert a date into a temporal value. The date is assumed to * use the Gregorian calendar if on or after noon, October 15, 1582; * otherwise, the date is assumed to use the Julian calendar. */ int utInvCalendar( int year, int month, int day, int hour, int minute, double second, const utUnit *unit, double *value) { int status = 0; /* success */ cv_converter* converter = ut_get_converter(encodedTimeUnit, unit->unit2); if (converter == NULL) { status = encodedTimeUnit == NULL ? UT_ENOINIT : UT_EINVALID; } else { double encodedTime = ut_encode_time(year, month, day, hour, minute, second); *value = cv_convert_double(converter, encodedTime); cv_free(converter); } return status; }
/*! * Constructs a converter from \a from unit to \a to unit. */ UdUnitConverter::UdUnitConverter(const UdUnit &from, const UdUnit &to): m_from(from), m_to(to), m_converter(nullptr) { ut_set_status(UT_SUCCESS); m_converter = ut_get_converter(m_from.m_unit, m_to.m_unit); //m_status = ut_get_status(); }
void R_ut_convert(const double *x, int *count, char * const *units_from, char * const *units_to, double *rv) { ut_unit *from, *to; cv_converter *conv; int one = 1; if (sys == NULL) { R_ut_init(&one); } ut_trim(*units_from, enc); ut_trim(*units_to, enc); from = ut_parse(sys, *units_from, enc); if (from == NULL) { handle_error("R_ut_convert"); return; } to = ut_parse(sys, *units_to, enc); if (from == NULL) { handle_error("R_ut_convert"); return; } conv = ut_get_converter(from, to); if (conv == NULL) { handle_error("R_ut_convert"); return; } cv_convert_doubles(conv, x, (size_t) *count, rv); // Cleanup cv_free(conv); ut_free(to); ut_free(from); return; }
value ml_ut_get_converter( value from, value to ) { CAMLparam2( from, to ); cv_converter *c; c = ut_get_converter( UD_ut_unit_val( from ), UD_ut_unit_val( to ) ); CHECK_STATUS( c ) CAMLreturn( Val_cv_converter( c ) ); }
cv_converter* udunits::get_converter(std::string const& source_unit, std::string const& target_unit) { ut_unit* udunit_source = ut_parse(unit_system_, source_unit.c_str(), UT_UTF8); if(!udunit_source) investigate_parse_error(source_unit); ut_unit* udunit_target = ut_parse(unit_system_, target_unit.c_str(), UT_UTF8); if(!udunit_target) investigate_parse_error(target_unit); cv_converter* converter = ut_get_converter(udunit_source, udunit_target); if(!converter) investigate_conversion_error(source_unit, target_unit); return converter; }
int harp_unit_converter_new(const char *from_unit, const char *to_unit, harp_unit_converter **new_unit_converter) { harp_unit_converter *unit_converter; ut_unit *from_udunit; ut_unit *to_udunit; if (parse_unit(from_unit, &from_udunit) != 0) { return -1; } if (parse_unit(to_unit, &to_udunit) != 0) { ut_free(from_udunit); return -1; } if (!ut_are_convertible(from_udunit, to_udunit)) { harp_set_error(HARP_ERROR_UNIT_CONVERSION, "unit '%s' cannot be converted to unit '%s'", from_unit, to_unit); ut_free(to_udunit); ut_free(from_udunit); return -1; } unit_converter = (harp_unit_converter *)malloc(sizeof(harp_unit_converter)); if (unit_converter == NULL) { harp_set_error(HARP_ERROR_OUT_OF_MEMORY, "out of memory (could not allocate %lu bytes) (%s:%u)", sizeof(harp_unit_converter), __FILE__, __LINE__); ut_free(to_udunit); ut_free(from_udunit); return -1; } unit_converter->converter = ut_get_converter(from_udunit, to_udunit); if (unit_converter->converter == NULL) { handle_udunits_error(); harp_unit_converter_delete(unit_converter); ut_free(to_udunit); ut_free(from_udunit); return -1; } ut_free(to_udunit); ut_free(from_udunit); *new_unit_converter = unit_converter; return 0; }
/*========================================================================================== * 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 ); }
int Trick::VariableServerThread::var_units(std::string var_name, std::string units_name) { unsigned int ii ; for ( ii = 0 ; ii < vars.size() ; ii++ ) { if ( ! std::string(vars[ii]->ref->reference).compare(var_name) ) { if (!units_name.compare("xx")) { vars[ii]->ref->units = strdup(vars[ii]->ref->attr->units); } else if (!units_name.compare("--")) { vars[ii]->ref->units = strdup("1"); } else { std::string new_units = map_trick_units_to_udunits(units_name) ; if ( units_name.compare(new_units) ) { std::cout << "\033[33mUnits converted from [" << units_name << "] to [" << new_units << "] in Variable Server for " << var_name << "\033[0m" << std::endl ; } ut_unit * from = ut_parse(Trick::UdUnits::get_u_system(), vars[ii]->ref->attr->units, UT_ASCII) ; if ( !from ) { message_publish(MSG_ERROR, "Variable Server Error: var_units Units conversion error for \"%s\".\n", var_name.c_str()); return -1 ; } ut_unit * to = ut_parse(Trick::UdUnits::get_u_system(), new_units.c_str(), UT_ASCII) ; if ( !to ) { message_publish(MSG_ERROR, "Variable Server Error: var_units Units conversion error for \"%s\".\n", var_name.c_str()); return -1 ; } cv_converter * conversion_factor = ut_get_converter(from,to) ; if ( conversion_factor != NULL ) { // only assign conversion_factor if it is not NULL, otherwise leave previous value. vars[ii]->conversion_factor = conversion_factor ; } vars[ii]->ref->units = strdup(units_name.c_str()); ut_free(from) ; ut_free(to) ; } } } 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); }
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; }
// CONSTRUCTOR DPC_UnitConvDataStream::DPC_UnitConvDataStream(DataStream* ds, const char *ToUnits, const char *FromUnitsHint ) { ut_unit * to = NULL ; ut_unit * from = NULL ; const char * recorded_units = ds->getUnit().c_str(); source_ds = ds; if (ToUnits != NULL) { to = ut_parse(u_system, ToUnits, UT_ASCII) ; to_units = ToUnits ; } // If the user has specified a units conversion and those units are valid ... if ( to != NULL ) { // If the recorded data file doesn't contain the units in which the data is recorded ... if ((recorded_units == NULL) || (strcmp(recorded_units,"") == 0)) { // If the user didn't give us a hint as to what the units are (using var@from_units) ... if ((FromUnitsHint == NULL) || (strcmp(FromUnitsHint,"") == 0)) { // set the from units to the same as the to units. cf = cv_get_trivial() ; std::cerr << "ERROR: Unable to to perform units conversion" << " because the recorded data doesn't indicate it's" << " units and no @from_units hint is provided." << std::endl; std::cerr.flush(); } else { // the user did give us a hint. from = ut_parse(u_system, FromUnitsHint, UT_ASCII) ; if ( ! from ) { std::cerr << "ERROR: Unable to to perform units conversion" << " because the recorded data doesn't indicate it's" << " units and although a @from_units hint is provided (" << "(\"" << FromUnitsHint << "\"), they are invalid." << std::endl; std::cerr.flush(); } } } else { // the recorded data file does "know" the units in which the data was recorded, // so those will be the units that we convert from. from = ut_parse(u_system, recorded_units, UT_ASCII) ; if ( !from ) { std::cerr << "ERROR: Unable to to perform units conversion because the" << " units in the data recording file appear to be corrupt." << std::endl; std::cerr.flush(); } } // If we know what units the data was recorded in ... if ( from != NULL ) { cf = ut_get_converter(from,to) ; if ( cf == NULL ) { std::cerr << "ERROR: Unable to convert from \"" << FromUnitsHint << "\" to \"" << to_units << "\" because they are incompatible." << std::endl; std::cerr.flush(); cf = cv_get_trivial() ; } } else { std::cerr << "ERROR: Unable to perform units conversion becuase the units" << " that the data is recorded in is unknown." << std::endl; cf = cv_get_trivial() ; } } else { // The user has not specified a units conversion or the units were not valid. // If the recorded data file doesn't contain the units in which the data is recorded ... if ((recorded_units == NULL) || (strcmp(recorded_units,"") == 0)) { // If the user didn't give us a hint as to what the units are (using var@from_units) ... if ((FromUnitsHint == NULL) || (strcmp(FromUnitsHint,"") == 0)) { cf = cv_get_trivial() ; } else { // the user did give us a hint. to_units = FromUnitsHint ; cf = cv_get_trivial() ; } } else { // the recorded data file does "know" the units in which the data was recorded, to_units = recorded_units ; cf = cv_get_trivial() ; } } if (to) ut_free(to) ; if (from) ut_free(from) ; this->begin(); }
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() */