uk.me.nxg.unity (The Unity library)
Date: 2014-05-13

Package | Class | Tree | Deprecated | Index | Help
PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES

## Package uk.me.nxg.unity

The Unity package provides a parser for unit strings.

See:
Description

Class Summary
Dimensions | A dimensions specification is a record of the measurement dimensions of a quantity.
FunctionDefinition | Describes a ‘known’' function.
FunctionDefinitionMap | Provides a mapping from function abbreviations to function definitions.
FunctionOfUnit | Represents a function of a unit, such as `log(m)`.
OneUnit | A single unit.
SimpleBinaryUnit | A unit which has a prefix which is a round power of 1024.
SimpleDecimalUnit | A unit which has a prefix which is a round power of 1000.
SimpleUnit | A single simple unit, such as 'kg'.
UnitDefinition | Describes a unit.
UnitDefinitionMap | Provides a mapping from unit abbreviations to unit definitions.
UnitExpr | A parsed unit expression.
UnitParser | A parser for unit strings.
UnitParser.Lexeme | A single lexeme.
UnitRepresentation | A description of the way that a unit is represented in a particular syntax.
Version | Manage version information

Enum Summary
Syntax | An enumeration of the allowed syntaxes within the Unity libary.

Exception Summary
UnitParserException | Thrown when an expression cannot be parsed.

## Package uk.me.nxg.unity Description

The Unity package provides a parser for unit strings.

NOTE: The library should currently be regarded as beta quality: the implementation and interface may change in response to experience and comments.

This is the unity parser (version 1.0), which is a Java class library to help parse unit specification strings such as `W.mm**-2`. There is also an associated C library, which uses the same grammars. For more details, see the library's home page; the source is on bitbucket.

As well as parsing various unit strings, the library can also serialise a parsed expression in various formats, including the four formats that it can parse, a LaTeX version with name `latex` (which uses the `{siunitx}` package) and a `debug` format which lists the parsed unit in an unambiguous, but not otherwise useful, form.

## Parsing Units

You can parse units using a couple of different syntaxes since, unfortunately, there is no general consensus on which syntax the world should agree on. The ones supported are as follows (cf `Syntax` for the list of parsers) :

fits
  FITS v3.0, section 4.3, W.D. Pence et al., A&A 524, A42, 2010 doi:10.1051/0004-6361/201015362
ogip
  OGIP memo OGIP/93-001, 1993
cds
  Standards for Astronomical Catalogues, Version 2.0, section 3.2, 2000
vounits
  IVOA VOUnits Proposed Recommendation

See also:

- The IAU style manual, section 5.1 (1989) is by now rather old, but appears to be one of the few existing standards for units, specific to astronomy.
- ISO/IEC 80000 (parts 1–13) describes a variety of units, including the specification of the 'binary' prefixes kibi, mebi, and so on (see ISO/IEC 80000-13 Sect.4, and IEEE standard 1541-2002).
- The VOUnits Recommendation discusses various tradeoffs and conflicting specifications, at some length.

Each of these has an associated writer, which allows you to write a parsed UnitExpression to a string, in a format which should be conformant with the particular syntax's standard. See `UnitExpr.toString()`.

In addition, there is a latex writer, which produces a formatted form for the the expression, in a form suitable for inclusion in a LaTeX document, using the `siunitx` package. To use the resulting output in a LaTeX document, include the following in the preamble of the file:

    \usepackage{siunitx}
    \DeclareSIQualifier\solar{$\odot$}

You may add any `siunitx` options that seem convenient, and you may omit the declaration of `\solar` if the units in the document do not include the various solar ones.

The parsing is permissive, to the extent that it permits non-recognised and deprecated units. The result of the parse may be checked for conformance with one or other standard using the methods `UnitExpr.allUnitsRecognised(uk.me.nxg.unity.Syntax)`, `UnitExpr.allUnitsRecommended(uk.me.nxg.unity.Syntax)` and `UnitExpr.allUsageConstraintsSatisfied(uk.me.nxg.unity.Syntax)`. Note that SI prefixes are still noticed for unrecognised units: thus `furlongs/fortnight` will be parsed as femto-urlongs per femto-ortnight. The same is not true of recognised units: a `pixel/s` is a pixel per second, and does not involve a pico-ixel.

### Demo

If you want to experiment with the library, you can do so using the jar file:

        % java -jar unity.jar -icds -oogip 'mm2/s'
        mm**2 /s
        % java -jar unity.jar -icds -ofits -v mm/s
        mm s-1
        check: all units recognised?           yes
        check: all units recommended?          yes
        check: all units satisfy constraints?  yes
        % java -jar unity.jar -ifits -ocds -v 'merg/s'
        merg/s
        check: all units recognised?           yes
        check: all units recommended?          no
        check: all units satisfy constraints?  no
        % java -jar unity.jar -icds -ofits -v 'merg/s'
        merg s-1
        check: all units recognised?           no
        check: all units recommended?          no
        check: all units satisfy constraints?  yes

In the latter cases, the `-v` option validates the input string against various constraints. The expression `mm/s` is completely valid in all the syntaxes. In the FITS syntax, the `erg` is a recognised unit, but it is deprecated; although it is recognised, it is not permitted to have SI prefixes. In the CDS syntax, the `erg` is neither recognised nor (a fortiori) recommended; since there are no constraints on it in this syntax, it satisfies all of them (this latter behaviour is admittedly slightly counterintuitive).

## Grammars supported

The four supported grammars have a fair amount in common, but the differences are nonetheless significant enough that they require separate grammars. Important differences are in the number of solidi they allow in the units specifications, and the symbols they use for products and powers.

Current limitations:

- Currently ignores some of the odder unit restrictions (such as the OGIP requirement that 'Crab' can have a 'milli' prefix, but no other SI prefixes)

In the grammars below, the common terminals are as follows:

- WHITESPACE: one or more whitespace characters
- STAR, DOT: a star or a dot, generally used to indicate multiplication
- DIVISION: a slash
- STARSTAR, CARET: the former is '**'; both are used to indicate exponentiation
- OPEN_P, CLOSE_P: open and close parentheses
- INTEGER, FLOAT: numbers; the syntax of FLOAT is `[+-]?[1-9][0-9]*\.[0-9]+` so that there are no exponents allowed; the signed integers have a non-optional leading sign, the unsigned don't
- STRING: a sequence of upper- and lower-case letters

There are some other terminals used in some grammars. See the VOUnits specification for further details.

### The FITS grammar

    input: complete_expression
            | scalefactor complete_expression
            | scalefactor WHITESPACE complete_expression
            | division unit_expression
            ;

    complete_expression: product_of_units
            | product_of_units division unit_expression
            ;

    product_of_units: unit_expression
            | product_of_units product unit_expression
            ;

    unit_expression: term
            // m(2) is m^2, not function application
            | STRING parenthesized_number
            | function_application
            | OPEN_P complete_expression CLOSE_P
            ;

    function_application: STRING OPEN_P complete_expression CLOSE_P
            ;

    scalefactor: LIT10 power numeric_power
            | LIT10 SIGNED_INTEGER
            ;

    division: DIVISION;

    term: unit
            | unit numeric_power
            | unit power numeric_power
            ;

    unit: STRING
            ;

    power: CARET
            | STARSTAR
            ;

    numeric_power: integer
            | parenthesized_number
            ;

    parenthesized_number: OPEN_P integer CLOSE_P
            | OPEN_P FLOAT CLOSE_P
            | OPEN_P integer division UNSIGNED_INTEGER CLOSE_P
            ;

    integer: SIGNED_INTEGER | UNSIGNED_INTEGER;

    product: WHITESPACE | STAR | DOT;

### The OGIP grammar

    input: complete_expression
            | scalefactor complete_expression
            | scalefactor WHITESPACE complete_expression
            ;

    complete_expression: product_of_units
            ;

    product_of_units: unit_expression
            | division unit_expression
            | product_of_units product unit_expression
            | product_of_units division unit_expression
            ;

    unit_expression: term
            | function_application
            | OPEN_P complete_expression CLOSE_P
            ;

    function_application: STRING OPEN_P complete_expression CLOSE_P
            ;

    scalefactor: LIT10 power numeric_power
            | LIT10
            | FLOAT
            ;

    division: DIVISION | WHITESPACE DIVISION
            | WHITESPACE DIVISION WHITESPACE | DIVISION WHITESPACE;

    term: unit
            | unit power numeric_power
            ;

    unit: STRING
            ;

    power: STARSTAR;

    numeric_power: UNSIGNED_INTEGER
            | FLOAT
            | parenthesized_number
            ;

    parenthesized_number: OPEN_P integer CLOSE_P
            | OPEN_P FLOAT CLOSE_P
            | OPEN_P integer division UNSIGNED_INTEGER CLOSE_P
            ;

    integer: SIGNED_INTEGER | UNSIGNED_INTEGER;

    product: WHITESPACE | STAR | WHITESPACE STAR
           | WHITESPACE STAR WHITESPACE | STAR WHITESPACE;

### The CDS grammar

This is quite similar to the OGIP grammar, but with more restrictions.

The `CDSFLOAT` terminal is a string matching the regular expression `[0-9]+\.[0-9]+x10[-+][0-9]+` (that is, something resembling `1.5x10+11`). The termainals `OPEN_SQ` and `CLOSE_SQ` are opening and closing square brackets `[...]`.

    input: complete_expression
            | scalefactor complete_expression
            ;

    complete_expression: product_of_units
            ;

    product_of_units: unit_expression
            | division unit_expression
            | product_of_units product unit_expression
            | product_of_units division unit_expression
            ;

    unit_expression: term
            | function_application
            | OPEN_P complete_expression CLOSE_P
            ;

    function_application: OPEN_SQ complete_expression CLOSE_SQ
            ;

    scalefactor: LIT10 power numeric_power
            | LIT10 SIGNED_INTEGER
            | UNSIGNED_INTEGER
            | LIT10
            | CDSFLOAT
            | FLOAT
            ;

    division: DIVISION;

    term: unit
            | unit numeric_power
            ;

    unit: STRING
            | PERCENT
            ;

    power: STARSTAR;

    numeric_power: integer
            ;

    integer: SIGNED_INTEGER | UNSIGNED_INTEGER;

    product: DOT;

### The VOUnits grammar

The `VOUFLOAT` and `QUOTED_STRING` features are extensions beyond the other grammars. These aside, this syntax is a strict subset of the FITS and CDS grammars, in the sense that any VOUnit unit string, without these extensions, is a valid FITS and CDS string, too), and it is almost a subset of the OGIP grammar, except that it uses the dot for multiplication rather than star.

The `VOUFLOAT` terminal is a string matching either of the regular expressions `0\.[0-9]+([eE][+-]?[0-9]+)?` or `[1-9][0-9]*(\.[0-9]+)?([eE][+-]?[0-9]+)?` (that is, something resembling, for example, `0.123` or `1.5e+11`). Also `QUOTED_STRING` is a `STRING` enclosed in single quotes `'...'`.

    input: complete_expression
            | scalefactor complete_expression
            ;

    complete_expression: product_of_units
            | product_of_units division unit_expression
            ;

    product_of_units: unit_expression
            | product_of_units product unit_expression
            ;

    unit_expression: term
            | function_application
            | OPEN_P complete_expression CLOSE_P
            ;

    function_application: STRING OPEN_P complete_expression CLOSE_P
            ;

    scalefactor: LIT10 power numeric_power
            | LIT10
            | VOUFLOAT
            ;

    division: DIVISION;

    term: unit
            | unit power numeric_power
            ;

    unit: STRING
            | QUOTED_STRING
            | STRING QUOTED_STRING
            ;

    power: STARSTAR;

    numeric_power: integer
            | parenthesized_number
            ;

    parenthesized_number: OPEN_P integer CLOSE_P
            | OPEN_P FLOAT CLOSE_P
            | OPEN_P integer division UNSIGNED_INTEGER CLOSE_P
            ;

    integer: SIGNED_INTEGER | UNSIGNED_INTEGER;

    product: DOT;

Package | Class | Tree | Deprecated | Index | Help
PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES