Defining new units
Note
Logarithmic units should not be used in the @refunit
or @unit
macros described below. See the section on logarithmic scales for customization help.
The package automatically generates a useful set of units and dimensions in the Unitful
module in src/pkgdefaults.jl
.
If a different set of default units or dimensions is desired, macros for generating units and dimensions are provided. To create new units interactively, most users will be happy with the @unit
macro and the Unitful.register
function, which makes units defined in a module available to the @u_str
string macro.
An example of defining units in a module:
julia> module MyUnits; using Unitful; @unit myMeter "m" MyMeter 1u"m" false; end MyUnits julia> using Unitful julia> u"myMeter" ERROR: LoadError: Symbol myMeter could not be found in registered unit modules. [...]
julia> Unitful.register(MyUnits) 2-element Array{Module,1}: Unitful MyUnits julia> u"myMeter" m
You could have also called Unitful.register
inside the MyUnits
module; the choice is somewhat analogous to whether or not to export symbols from a module, although the symbols are never really exported, just made available to the @u_str
macro. If you want to make a precompiled units package, rather than define a module at the REPL, see Making your own units package.
You can also define units directly in the Main
module at the REPL:
julia> using Unitful julia> Unitful.register(@__MODULE__); julia> @unit M "M" Molar 1u"mol/L" true; julia> 1u"mM" 1 mM
A note for the experts: Some care should be taken if explicitly creating Unitful.Units
objects. The ordering of Unitful.Unit
objects inside a tuple matters for type comparisons. Using the unary multiplication operator on the Units
object will return a "canonically sorted" Units
object. Indeed, this is how we avoid ordering issues when multiplying quantities together.
Defining units in precompiled packages
See Precompilation.
Useful functions and macros
#
Unitful.@dimension
— Macro.
@dimension(symb, abbr, name)
Creates new dimensions. name
will be used like an identifier in the type parameter for a Unitful.Dimension
object. symb
will be a symbol defined in the namespace from which this macro is called that is bound to a Unitful.Dimensions
object. For most intents and purposes it is this object that the user would manipulate in doing dimensional analysis. The symbol is not exported.
This macro extends Unitful.abbr
to display the new dimension in an abbreviated format using the string abbr
.
Type aliases are created that allow the user to dispatch on Unitful.Quantity
, Unitful.Level
and Unitful.Units
objects of the newly defined dimension. The type alias for quantities or levels is simply given by name
, and the type alias for units is given by name*"Units"
, e.g. LengthUnits
. Note that there is also LengthFreeUnits
, for example, which is an alias for dispatching on FreeUnits
with length dimensions. The aliases are not exported.
Finally, if you define new dimensions with @dimension
you will need to specify a preferred unit for that dimension with Unitful.preferunits
, otherwise promotion will not work with that dimension. This is done automatically in the @refunit
macro.
Returns the Dimensions
object to which symb
is bound.
Usage example from src/pkgdefaults.jl
: @dimension 𝐋 "𝐋" Length
#
Unitful.@derived_dimension
— Macro.
@derived_dimension(name, dims)
Creates type aliases to allow dispatch on Unitful.Quantity
, Unitful.Level
, and Unitful.Units
objects of a derived dimension, like area, which is just length squared. The type aliases are not exported.
dims
is a Unitful.Dimensions
object.
Returns nothing
.
Usage examples:
@derived_dimension Area 𝐋^2
givesArea
andAreaUnit
type aliases@derived_dimension Speed 𝐋/𝐓
givesSpeed
andSpeedUnit
type aliases
#
Unitful.@refunit
— Macro.
@refunit(symb, name, abbr, dimension, tf)
Define a reference unit, typically SI. Rather than define conversion factors between each and every unit of a given dimension, conversion factors are given between each unit and a reference unit, defined by this macro.
This macro extends Unitful.abbr
so that the reference unit can be displayed in an abbreviated format. If tf == true
, this macro generates symbols for every power of ten of the unit, using the standard SI prefixes. A dimension
must be given (Unitful.Dimensions
object) that specifies the dimension of the reference unit.
In principle, users can use this macro, but it probably does not make much sense to do so. If you define a new (probably unphysical) dimension using @dimension
, then this macro will be necessary. With existing dimensions, you will almost certainly cause confusion if you use this macro. One potential use case would be to define a unit system without reference to SI. However, there's no explicit barrier to prevent attempting conversions between SI and this hypothetical unit system, which could yield unexpected results.
Note that this macro will also choose the new unit (no power-of-ten prefix) as the default unit for promotion given this dimension.
Returns the Unitful.FreeUnits
object to which symb
is bound.
Usage example: @refunit m "m" Meter 𝐋 true
This example, found in src/pkgdefaults.jl
, generates km
, m
, cm
, ...
#
Unitful.@unit
— Macro.
@unit(symb,abbr,name,equals,tf)
Define a unit. Rather than specifying a dimension like in @refunit
, equals
should be a Unitful.Quantity
equal to one of the unit being defined. If tf == true
, symbols will be made for each power-of-ten prefix.
Returns the Unitful.FreeUnits
object to which symb
is bound.
Usage example: @unit mi "mi" Mile (201168//125)*m false
This example will not generate kmi
(kilomiles).
#
Unitful.@affineunit
— Macro.
@affineunit(symb, abbr, offset)
Macro for easily defining affine units. offset
gives the zero of the relative scale in terms of an absolute scale; the scaling is the same as the absolute scale. Example: @affineunit °C "°C" (27315//100)K
is used internally to define degrees Celsius.
Internals
#
Unitful.@prefixed_unit_symbols
— Macro.
@prefixed_unit_symbols(symb,name,dimension,basefactor)
Not called directly by the user. Given a unit symbol and a unit's name, will define units for each possible SI power-of-ten prefix on that unit.
Example: @prefixed_unit_symbols m Meter 𝐋 (1.0,1)
results in nm, cm, m, km, ... all getting defined in the calling namespace.
#
Unitful.@unit_symbols
— Macro.
@unit_symbols(symb,name)
Not called directly by the user. Given a unit symbol and a unit's name, will define units without SI power-of-ten prefixes.
Example: @unit_symbols ft Foot 𝐋
results in ft
getting defined but not kft
.
#
Unitful.basefactor
— Function.
basefactor(x::Unit)
Specifies conversion factors to reference units. It returns a tuple. The first value is any irrational part of the conversion, and the second value is a rational component. This segregation permits exact conversions within unit systems that have no rational conversion to the reference units.