Skip to content

Units of Measurement

HankHerr-NOAA edited this page Jun 25, 2024 · 14 revisions

Units of Measurement (WRES Release 5.14 and Later Versions)

A change in WRES Release 5.14 to the way WRES handles units of measurement means that WRES can recognize and convert more units of measurements than in previous versions. The change also paves the way for more sophisticated unit conversions in the future. As of WRES Release 5.14, if the dimensions are the same (e.g. [M]/[T]) but the units differ (e.g. kg/ms to [lb_av]/d), WRES Release 5.14 can perform the conversion provided it can recognize the units. In the case where the syntax of the unit in the dataset is not successfully parsed by WRES, the declaration can tell WRES “the unit kilograms per millisecond in the datasets should be treated as kg/ms”. In other words, WRES cannot successfully parse kilograms per millisecond but it can parse and recognize kg/ms because WRES now uses a formal units of measurement library supporting the Unified Code for Units of Measure^1 (UCUM) and the unit kg/ms is a valid UCUM^2 unit string. Likewise, [lb_av]/d is also a valid UCUM^3 unit string. The WRES uses an internal default map of commonly seen hydrological vernacular unit strings to their formal UCUM unit strings but the caller can declare a different map to be applied for an evaluation to support arbitrary unit strings.

This page is largely about telling WRES how to recognize a unit of measurement from your datasets. Your datasets may not use the same name that UCUM^4 uses or WRES may make the wrong guess on your behalf in which case you can point WRES in the right direction for your evaluations.

What to do with Existing Declarations

Nothing. If the declarations worked in WRES Release 5.12/5.13, they should still work in WRES Release 5.14. If your declarations do not work, this is an error on the part of the WRES team. Please let us know and continue reading this page for workarounds. For example, WRES will automatically map the vernacular CFS string to the formal UCUM string [ft_i]3/s and log the same (see below, “What is this message…”).

What to do when Units are not Recognized by WRES

When a unit is not recognized an UnrecognizedUnitException should be thrown. The message should explain that a unitAlias declaration is required for WRES to recognize the unit.

Suppose the original dataset on the left and right have the unit name kilograms per millisecond and the declared desired unit for pairs is [lb_av]/d (avoirdupois pounds per day^5), WRES can perform this conversion once it knows what kilograms per millisecond means in terms of UCUM^6. Here is the declaration to help WRES along:

<code class="xml">
        <unitAlias>
            <alias>kilograms per millisecond</alias>
            <unit>kg/ms</unit>
        </unitAlias>
</code>

The optional unitAlias declaration(s) (zero, one, or many) immediately follow the unit declaration. For example, the above example in context:

<code class="xml">
<!-- Same as the above example showing the context of declaration for WRES Release 5.14 -->
<?xml version="1.0" encoding="UTF-8"?>
<project>
<!-- ... -->
    <pair>
        <unit><!-- whatever desired unit of the pairs ... --></unit>
        <unitAlias>
            <alias>kilograms per millisecond</alias>
            <unit>kg/ms</unit>
        </unitAlias>
<!-- ... -->
    </pair>
<!-- ... -->
</project>
</code>

What the declaration says is “whenever you find the unit of measurement string kilograms per millisecond, consider it to be an alias for the UCUM^7 unit of measurement string kg/ms.”

A demo for validation and conversion of UCUM units is available at https://ucum.nlm.nih.gov/ucum-lhc/demo.html (though it does not highlight deprecated UCUM^8 units). This site makes it easier to find the unit name you are looking for from plain words.

What is this message INFO Units Treating measurement unit name...?

You may see messages like the following in logs:
2021-10-20T13:51:26.958+0000 INFO Units Treating measurement unit name 'CMS' as UCUM unit 'm3/s' along dimension '[L]³/[T]'
or
2021-10-20T14:30:28.829+0000 INFO Units Treating measurement unit name 'kg m-2' as UCUM unit 'kg/m2' along dimension '[M]/[L]²'

To clarify what unit is used by WRES during an evaluation, this message indicates the underlying formal unit as well as the dimension used. In the first example message, the string CMS is being used by WRES as the unit that UCUM^9 names m3/s and the dimension is volume (length cubed) over time. In the second example message, the string kg m-2 is being used by WRES as the unit that the UCUM^10 names kg/m2 and the dimension is mass over area (length squared). Sometimes the unit name and the UCUM^11 unit will be identical in this message. This can be important information because of the default unit aliases inside WRES and also because of the caller-supplied unit aliases and the interactions between them. When setting unit aliases (see above and below) this message can help discover if the intended unit is used by WRES. Even when not setting unit aliases it can also be helpful to see that the intended unit is used by WRES. The UCUM^12 unit printed in this message is informational but also can be used directly as the value in the unit tag of a unitAlias declaration. The dimension printed is informational to help the user judge whether this is the correct unit.

A WRES default map from common strings to formal UCUM^13 units has educated guesses based on experience with datasets at OWP. For many datasets at OWP the map will make the correct guess but your dataset may be different. This message makes it possible to verify that WRES appears to be using the correct interpretation.

What is Meant by Recognize Units versus Convert Units

To recognize a unit means the WRES software can create a formal unit of measurement representation using a formal unit of measurement library from a given unit string. In other words, to recognize a unit means that WRES software “knows” that it is a length measurement or a time measurement or a volume measurement and its relative magnitude to other units along that same dimension.

To convert a unit means the WRES software converts from one unit to another. This requires WRES to recognize both units and also that it can perform a sensible conversion between those two already-recognized units.

Most of this page has to do with getting WRES to recognize units. Unit conversions are the purpose of unit recognition, so in that sense unit conversions are related and mentioned here. But for the most part the trouble is in making sure that the unit name used in a dataset is understood by WRES accurately. Once the units are recognized, conversions become possible, and conversions along the same dimension are going to work easily at that point.

When are No Unit Conversions Required by WRES?

When all datasets in a declaration (left, right, and optional baseline) have a unit of measurement, e.g. “ASDF”, and the declaration declares the same unit of measurement, e.g. “ASDF”, then WRES software treats it as identity and no unit conversion will be attempted. Because no unit conversion is attempted, no attempt is made by WRES to understand or recognize the unit, e.g. “ASDF”, because there is no need. In this special case, arbitrary unit names are OK, so long as they match exactly (case-sensitive) between all the datasets and the declared desired unit of measurement. In this special case, you will see a WARN message such as Unknown unit '-' may cause unit conversion issues but then no subsequent exceptions related to units or unit conversions.

Table of Example Units Supported by WRES (Not Exhaustive)

The WRES uses UCUM^14 unit strings that are case-sensitive (c/s). This table of examples is intended as an introduction to UCUM^15 for Office of Water Prediction people. In most cases this example table builds from simpler to more complex, with a footnote having a link to the newly-introduced complication. For example, the first unit shown links to the definition of a unit and the second unit builds on this by using a prefix for that unit and links to the UCUM^16 section regarding prefixes. UCUM^17 is normative, not this list. If there is an error here, correct it.

UCUM^18 Unit Description
m Meters^19
mm Millimeters^20
[ft_i] Feet^21 (international, US customary, USGS current^22)
[ft_us] US Survey Feet^23
[in_i] Inches
s Seconds^24
min Minutes^25
h Hours^26
d Days^27
m/s Meters per Second^28
[ft_i]/s Feet per Second
m3 Cubic Meters^29
[ft_i]3 Cubic Feet (international, US Customary, USGS current^30)
[ft_us]3 Cubic US Survey Feet
m3/s Cubic Meters per Second
[ft_i]3/s Cubic Feet per Second
1000.[ft_i]3/s Thousands of Cubic Feet per Second^31
1000.[ft_us]3/s Thousands of Cubic US Survey Feet per Second
K Kelvin
Cel Degrees Celsius
[degF] Degrees Fahrenheit

Easily find more units at https://ucum.nlm.nih.gov/ucum-lhc/demo.html (but then double-check in the UCUM^32 documentation that they are not deprecated)

Why Does C Still Work? How can I make C mean Coulomb instead?

For backward compatibility, WRES Release 5.14 has a default map^33 of unit aliases to corresponding UCUM^34 strings. The units that were available in WRES Release 5.13 and earlier should be present in 5.14 by the same name. For example, C maps to Cel and F maps to [degF]. What if you want C to mean C (Coulomb) or F to mean F (Farad) instead of the default WRES map to degrees Celsius and degrees Fahrenheit? The declared alias takes precedence over the default map, therefore if you want C to mean Coulomb instead of degrees Celsius, do this (yes, it is counter-intuitive):

<code class="xml">
    <unitAlias>
        <alias>C</alias>
        <unit>C</unit>
    </unitAlias>
</code>

Limitations or Discrepancies Between UCUM, WRES, and the NIH Demo

The library that WRES uses as of 2021-10-26 does not appear to interpret UCUM powers of numeric literals. For example, 10^6 or 10*6 would typically mean one million or 1000000 in UCUM terms^35. The workaround is to use the full number such as 1000000 until the library (and WRES in turn) supports it. The metric prefix M would also work with the library and the NIH demo at https://ucum.nlm.nih.gov/ucum-lhc/demo.html but is prohibited for non-metric units when strictly interpreting UCUM^36. For example, k[ft_i]3/s (like KCFS) might work, but strictly speaking should be 1000.[ft_i]3/s because [ft_i] is not metric^37.

Can I Chain Aliases or Alias Aliases?

No. Aliases are flat across the whole evaluation. Conceptually there is only a one-level deep map from arbitrary unit names to formal UCUM^38 units per evaluation. This map is prepared with a set of default entries (educated guesses), but specifying a unit alias with the same unit name as present in the default map in the declaration overrides the key-value pair in the map. The same map from arbitrary unit names to formal UCUM^39 units applies in the same way to the units found in datasets on the left, right, baseline as well as to desired units and threshold units.

Can I Declare Multiple Unit Aliases?

Yes. You can declare zero, one, or many unit aliases, but you may not declare the same alias name twice. You may declare multiple aliases to mean the same target UCUM^40 unit, however.

Example valid declaration, supposing that some data in the evaluation uses the string “metres” to denote meters while other data in the evaluation uses the string “meters” to denote meters, and other data in the evaluation uses the string “feet” to denote feet:

<code class="xml">
<!-- Example valid unit alias declaration set -->
    <unitAlias>
        <alias>metres</alias>
        <unit>m</unit>
    </unitAlias>
    <unitAlias>
        <alias>meters</alias>
        <unit>m</unit>
    </unitAlias>
    <unitAlias>
        <alias>feet</alias>
        <unit>[ft_i]</unit>
    </unitAlias>
</code>

Example invalid declaration supposing some data in the evaluation uses the string “cubic meters” to denote cubic meters:

<code class="xml">
<!-- Example INVALID unit alias declaration set -->
    <unitAlias>
        <alias>cubic meters</alias>
        <unit>m3</unit>
    </unitAlias>
    <unitAlias>
        <alias>cubic meters</alias>
        <unit>35315.ft3/1000</unit>
    </unitAlias>
</code>

The reason the above is invalid is it defines the same alias twice. The unit alias applies across all the datasets and it can only have one interpretation, not more than one. The only sense in which is is acceptable to have two aliases is when overriding an internal-to-WRES default convenience alias name using a declared unit alias. Still, this results in only one unitAlias declaration per alias.

Clone this wiki locally