libdas2
das2 core C utilities
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Typedefs | Functions
Units

General unit normalization and manipulation with a focus on SI units. More...

Detailed Description

General unit normalization and manipulation with a focus on SI units.

Typedefs

typedef const char * das_units
 Enumeration of unit types, that correspond to physical unit types. More...
 

Functions

das_units Units_fromStr (const char *string)
 Basic constructor for das_unit's. More...
 
const char * Units_toStr (das_units unit)
 Get the canonical string representation of a das_unit Even though das_unit is a const char*, this function should be used in case the das_unit implementation is changed in the future. More...
 
char * Units_toLabel (das_units unit, char *sBuf, int nLen)
 Get label string representation das_units. More...
 
das_units Units_invert (das_units unit)
 Invert the units, most commonly used for Fourier transform results. More...
 
das_units Units_multiply (das_units ut1, das_units ut2)
 Combine units via multiplication. More...
 
das_units Units_divide (das_units a, das_units b)
 Combine units via division. More...
 
das_units Units_power (das_units unit, int power)
 Raise units to a power. More...
 
das_units Units_root (das_units unit, int root)
 Reduce units to a root. More...
 
das_units Units_interval (das_units unit)
 Get the unit type for intervals between data points of a given unit type. More...
 
das_units Units_reduce (das_units orig, double *pFactor)
 Reduce arbitrary units to the most basic know representation. More...
 
bool Units_canConvert (das_units fromUnits, das_units toUnits)
 Determine if given units are interchangeable Though not as good a solution as using UDUNITS2 works for common space physics quantities as well as SI units. More...
 
double Units_convertTo (das_units toUnits, double rVal, das_units fromUnits)
 Generic unit conversion utility. More...
 
bool Units_haveCalRep (das_units unit)
 Determine if the units in question can be converted to date-times. More...
 
void Units_convertToDt (das_time *pDt, double value, das_units epoch_units)
 Convert a value in time offset units to a calendar representation. More...
 
double Units_convertFromDt (das_units epoch_units, const das_time *pDt)
 Convert a calendar representation of a time to value in time offset units. More...
 
double Units_secondsSinceMidnight (double rVal, das_units epoch_units)
 Get seconds since midnight for some value of an epoch time unit. More...
 
bool Units_canMerge (das_units left, int op, das_units right)
 Determine if the units of values in a binary expression are compatable. More...
 

Typedef Documentation

typedef const char* das_units

Enumeration of unit types, that correspond to physical unit types.

Note that although these are strings, Units_fromStr() should be be used to get a reference to the enumerated string since pointer equality comparison is done in the code. Thus UnitType objects created using the functions in this module satisfy the rule:

* das_unit a;
* das_unit b;
*
* if(a == b){
* // Units are equal
* }
*

The Epoch Time unit types understood by this library are:

  • UNIT_US2000 - Non-Leap microseconds since midnight, January 1st 2000
  • UNIT_MJ1958 - Days since midnight January 1st 1958
  • UNIT_T2000 - Non-Leap seconds since midnight, January 1st 2000
  • UNIT_T1970 - Non-Leap seconds since midnight, January 1st 1970
  • UNIT_UTC - Time strings on the gregorian calendar
  • UNIT_NS2020 - Non-Leap nanoseconds since midnight Jan 1st, 2020, typically transmitted as signed 8-byte integers

As it stands the library currently does not understand SI prefixes, so each scaled unit has it's own entry. This should change.

  • UNIT_SECONDS - Seconds, a time span.
  • UNIT_HOURS - hours, a time span = 3600 seconds.
  • UNIT_MIRCOSECONDS - A smaller time span.
  • UNIT_HERTZ - Hertz, a measure of frequency.
  • UNIT_KILO_HERTZ - KiloHertz, another measure of frequency.
  • UNIT_E_SPECDENS - Electric Spectral Density, V**2 m**-2 Hz**-1;
  • UNIT_B_SPECDENS - Magnetic Spectral Density, nT**2 Hz**-1;
  • UNIT_NT - Magnetic Field intensity, nT
  • UNIT_NUMBER_DENS - Number density, the number of items in a cubic centimeter
  • UNIT_DB - Decibels, a ratio measure, typically versus 1.0.
  • UNIT_KM - Kilometers, a unit of distance
  • UNIT_DEGREES - Degrees, a ratio measure on circles: (arch length / circumference) * 360

And if you don't know what else to use, try this:

  • UNIT_DIMENSIONLESS - I.E. No units
Todo:
Redo units as small structures

Function Documentation

das_units Units_fromStr ( const char *  string)

Basic constructor for das_unit's.

das_unit values are just char pointers, however they are singletons so that equality operations are possible. For proper operation of the functions in the module it is assumed that one of the pre-defined units are used, or that new unit types are created via this function.

Returns
a pointer to the singleton string representing these units.
const char* Units_toStr ( das_units  unit)

Get the canonical string representation of a das_unit Even though das_unit is a const char*, this function should be used in case the das_unit implementation is changed in the future.

See Also
Units_toLabel()
char* Units_toLabel ( das_units  unit,
char *  sBuf,
int  nLen 
)

Get label string representation das_units.

This function inserts formatting characters into the unit string returned by Units_toStr(). The resulting output is suitable for use in Das2 labels For example if Units_toStr() returns:

V**2 m**-2 Hz**-1

this function would generate the string

V!a2!n m!a-2!n Hz!a-1!n

Units that are an offset from some UTC time merely return "UTC"

Parameters
unitthe unit object to convert to a label
sBufa buffer to hold the UTF-8 label string
nLenthe length of the buffer pointed to by sBuf
Returns
a pointer to sBuf, or NULL if nLen was too short to hold the label, or if the name contains a trailing '_' or there was more than one '_' characters in a unit name.
das_units Units_invert ( das_units  unit)

Invert the units, most commonly used for Fourier transform results.

Create the corresponding inverted unit from a given unit. For example seconds become Hz, milliseconds become kHz and so on. This function does not product the same output as calling:

*
* Units_exponentiate(unit, -1, 1);
*
*

because a special lookup table is used for converting s**-1 (and related) values to Hertz.

For all other unit types, calling this function is equivalent to calling Units_exponentiate(unit, -1, 1)

Warning This function is not multi-thread safe. It alters global library state data

Parameters
unitthe input unit to invert
Returns
the inverted unit
das_units Units_multiply ( das_units  ut1,
das_units  ut2 
)

Combine units via multiplication.

Examples:

Precondition
A, B -> A B

A, A -> A**2

kg m**2 s**-1, kg**-1 -> m**2 s**-1

Parameters
ut1the first unit object
ut2the second uint object
Returns
A new unit type which is the product of a and b.
das_units Units_divide ( das_units  a,
das_units  b 
)

Combine units via division.

This is just a convenience routine that has the effect of calling:

* Units_multiply( a, Units_power(b, -1) );
*
Parameters
athe numerator units
bthe denominator units
Returns
A new unit type which is the quotient of a divided by b
das_units Units_power ( das_units  unit,
int  power 
)

Raise units to a power.

To invert a unit use the power -1.

For units following the canonical pattern:

A**n B**m

A new inverted unit:

A**-n B**-m

is produced.

das_units Units_root ( das_units  unit,
int  root 
)

Reduce units to a root.

Use this to reduce units to a integer root, for example:

Units_root( "m**2", 2 ) –> "m" Units_root( "nT / cm**2" ) –> "nT**1/2 cm**-1"

Parameters
unitThe input unit
rootA positive integer greater than 0
Returns
the new unit.
das_units Units_interval ( das_units  unit)

Get the unit type for intervals between data points of a given unit type.

This is confusing, but basically some data points, such as calendar times and various other Das epoch based values cannot represent differences, only absolute positions. Use this to get the unit type of the subtraction of two point specified as the given time.

For example the units of 2017-10-14 UTC - 2017-10-13 UTC is seconds.

Parameters
unitThe unit type for which the difference type is desired
Returns
the interval unit type. Basic units such as meters have no standard epoch and thus they are just their own interval type.
das_units Units_reduce ( das_units  orig,
double *  pFactor 
)

Reduce arbitrary units to the most basic know representation.

Units such as days can be represented as 86400 seconds, likewise units such as km**2 can be represented as 10e6 m**2. Use this function to reduce units to the most basic type known by this library and return the scaling factor that would be needed to convert data in the given units to the reduced units.

This handles all SI units (except candela) and allows for metric prefix names on arbitrary items, but not metric prefix symbols on arbitrary unit tyes. For example 'microcows' are reduced to '1e-6 cows', but 'μcows' are not converted to 'cows'.

Parameters
[in]origthe original unit type
[out]pFactora pointer to a double which will hold the scaling factor, for units that are already in the most basic form this factor is 1.0.
Returns
the new UnitType, which may just be the old unit type if the given units are already in their most basic form
bool Units_canConvert ( das_units  fromUnits,
das_units  toUnits 
)

Determine if given units are interchangeable Though not as good a solution as using UDUNITS2 works for common space physics quantities as well as SI units.

Units are convertible if:

  1. They are both known time offset units.
  2. They have a built in conversion factor (ex: 1 day = 24 hours)
  3. Both unit sets use SI units, including Hz
  4. When reduced to base units the exponents of each unit are the same.
double Units_convertTo ( das_units  toUnits,
double  rVal,
das_units  fromUnits 
)

Generic unit conversion utility.

Parameters
toUnitsThe new units that the value should be represented in
rValThe value to convert, to get a conversion factor from one unit type to another set this to 1.0.
fromUnitsThe original units of the value
Note
: Thanks Wikipedia. This code incorporates the algorithm on page http://en.wikipedia.org/wiki/Julian_day
bool Units_haveCalRep ( das_units  unit)

Determine if the units in question can be converted to date-times.

If this function returns true, then the following functions may be used on this unit type:

Units_convertToDt() Units_convertFromDt() Units_secondsSinceMidnight() Units_getJulianDay()

Furthermore a call to Units_interval() returns a different unittype then the given units.

Parameters
unitThe units to check possible mapping to calendar dates.
void Units_convertToDt ( das_time pDt,
double  value,
das_units  epoch_units 
)

Convert a value in time offset units to a calendar representation.

Parameters
[out]pDta pointer to a das_time structure to receive the broken down time.
[in]valuethe double value representing time from the epoch in some scale
[in]epoch_unitsUnit string
double Units_convertFromDt ( das_units  epoch_units,
const das_time pDt 
)

Convert a calendar representation of a time to value in time offset units.

Parameters
epoch_unitsThe units associated with the return value
pDtthe calendar time object from which to derive the value
Returns
the value as a floating point offset from the epoch associated with epoch_units, or DAS_FILL_VALUE on an error
double Units_secondsSinceMidnight ( double  rVal,
das_units  epoch_units 
)

Get seconds since midnight for some value of an epoch time unit.

Parameters
rValthe value of the epoch time
epoch_unitsso type of epoch time unit.
Returns
the number of floating point second since midnight
bool Units_canMerge ( das_units  left,
int  op,
das_units  right 
)

Determine if the units of values in a binary expression are compatable.

Parameters
right
op
left
Returns