/* * 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; }
static double compositeConvertDouble( const cv_converter* const conv, const double value) { return cv_convert_double(conv->composite.second, cv_convert_double(((CompositeConverter*)conv)->first, value)); }
NFtimeLine_p NCtimeLineExpand (NCaxis_p timeAxis, NFtime_p beginTime, NFtime_p endTime, cv_converter *cvConverter, NFtimeLine_p timeLine) { size_t timeStep = 0; NFtime_p timePtr = (NFtime_p) NULL; double variable; if ((timePtr = (NFtimeCreate ())) == (NFtime_p) NULL) { CMmsgPrint (CMmsgAppError,"Time object creation error in %s:%d!\n",__FILE__,__LINE__); return ((NFtimeLine_p) NULL); } if (timeLine == (NFtimeLine_p) NULL) timeLine = NFtimeLineCreate (); for (timeStep = 0;timeStep < timeAxis->N; ++timeStep) { variable = cv_convert_double (cvConverter, timeAxis->Bounds [timeStep * 2]); if (NFtimeSetFromVariable (timePtr, variable) == false) { CMmsgPrint (CMmsgAppError, "Time reading error in %s:%d!\n",__FILE__,__LINE__); NFtimeLineFree (timeLine); return ((NFtimeLine_p) NULL); } if (NFtimeCompare (beginTime, timePtr) <= 0) break; } if (timeStep < timeAxis->N) { for ( ;timeStep < timeAxis->N; ++timeStep) { variable = cv_convert_double (cvConverter, timeAxis->Bounds [timeStep * 2]); if (NFtimeSetFromVariable (timePtr, variable) == false) { CMmsgPrint (CMmsgAppError, "Time reading error in %s:%d!\n",__FILE__,__LINE__); NFtimeLineFree (timeLine); return ((NFtimeLine_p) NULL); } if (NFtimeLineAddStep (timeLine,timePtr) == false) { CMmsgPrint (CMmsgAppError, "Time step insertion error in %s:%d!\n",__FILE__,__LINE__); return ((NFtimeLine_p) NULL); } variable = cv_convert_double (cvConverter, timeAxis->Bounds [timeStep * 2 + 1]); if (NFtimeSetFromVariable (timePtr, variable) == false) { CMmsgPrint (CMmsgAppError, "Time reading error in %s:%d!\n",__FILE__,__LINE__); NFtimeLineFree (timeLine); return ((NFtimeLine_p) NULL); } if (NFtimeCompare (endTime, timePtr) < 0) break; } if (NFtimeSetFromVariable (timePtr, variable) == false) { CMmsgPrint (CMmsgAppError, "Time reading error in %s:%d!\n",__FILE__,__LINE__); NFtimeLineFree (timeLine); return ((NFtimeLine_p) NULL); } NFtimeCopy (timePtr,timeLine->TimeLine [timeLine->TimeStepNum]); } else { CMmsgPrint (CMmsgAppError, "Time axis outside of time period in %s:%d!\n",__FILE__,__LINE__); NFtimeLineFree (timeLine); return ((NFtimeLine_p) NULL); } if (timePtr != (NFtime_p) NULL) NFtimeFree (timePtr); return (timeLine); }
/* * 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; }
/* * 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; }
void udunits::convert(viennamini::dense_values& values, std::string const& source_unit, std::string const& target_unit) { cv_converter* converter = this->get_converter(source_unit, target_unit); for(viennamini::dense_values::iterator iter = values.begin(); iter != values.end(); iter++) *iter = cv_convert_double(converter, *iter); cv_free(converter); }
value ml_cv_convert_double( value converter, value x ) { CAMLparam2( converter, x ); double result; result = cv_convert_double( UD_cv_converter_val( converter ), Double_val( x ) ); CAMLreturn( caml_copy_double( result ) ); }
void harp_unit_converter_convert_array(const harp_unit_converter *unit_converter, long num_values, double *value) { double *value_end; for (value_end = value + num_values; value != value_end; value++) { *value = cv_convert_double(unit_converter->converter, *value); } }
// MEMBER FUNCTION int DPC_UnitConvDataStream::get(double* timestamp, double* paramValue) { double time, value; int ret ; ret = source_ds->get(&time, &value) ; *timestamp = time; *paramValue = cv_convert_double(cf, value) ;; return ret ; }
// MEMBER FUNCTION int DPC_UnitConvDataStream::peek(double* timestamp, double* paramValue) { double time, value; if (! source_ds->peek(&time, &value) ) { *timestamp = time; *paramValue = cv_convert_double(cf, value) ;; return (0); } else { return (-1); } }
/*========================================================================================== * 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; }
double harp_unit_converter_convert(const harp_unit_converter *unit_converter, double value) { return cv_convert_double(unit_converter->converter, value); }
/*! * Returns \a value (which is expressed in the converter's from unit) converted * to this converter's to unit. If the converter is invalid, the behaviour is undefined. */ qreal UdUnitConverter::convert(qreal value) { return cv_convert_double(m_converter, value); }
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; }
/*======================================================================================== * 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); }
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); }
/*======================================================================================== * 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); }
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() */