Classes and Functions

Quantities

class quantiphy.Quantity

Create a Physical Quantity

A quantity is a number paired with a unit of measure.

Parameters:
  • value (real, string or quantity) – The value of the quantity. If a string, it may be the name of a pre-defined constant or it may be a number that may be specified with SI scale factors and/or units. For example, the following are all valid: ‘2.5ns’, ‘1.7 MHz’, ‘1e6Ω’, ‘2.8_V’, ‘1e4 m/s’, ‘$10_000’, ‘42’, ‘ħ’, etc. The string may also have name and description if they are provided in a way recognizable by assign_rec. For example, ‘trise: 10ns – rise time’ or ‘trise = 10ns # rise time’ would work with the default recognizer.
  • model (quantity or string) – Used to pick up any missing attibutes (units, name, desc). May be a quantity or a string. If model is a quantity, only its units would be taken. If model is a string, it is split. Then, if there is one item, it is taken to be units. If there are two, they are taken to be name and units. And if there are three or more, the first two are taken to the be name and units, and the remainder is taken to be description.
  • units (str) – Overrides the units taken from value or model.
  • scale (float, tuple, func, or string):) –
    • If a float, it multiplies by the given value to compute the value of the quantity.
    • If a tuple, the first value, a float, is treated as a scale factor and the second value, a string, is take to be the units of the quantity.
    • If a function, it takes two arguments, the given value and the units and it returns two values, the value and units of the quantity.
    • If a string, it is taken to the be desired units. This value along with the units of the given value are used to select a known unit conversion, which is applied to create the quantity.
  • name (str) – Overrides the name taken from value or model.
  • desc (str) – Overrides the desc taken from value or model.
  • ignore_sf (bool) – Assume the value given within a string does not employ a scale factors. In this way, ‘1m’ is interpreted as 1 meter rather than 1 milli.
Raises:
  • KeyError – A unit conversion was requested and there is no corresponding unit converter or assignment recognizer (assign_rec) does not match at least the value (val).
  • ValueError – A string was passed that cannot be converted to a quantity.

You can use Quantity to create quantities from floats, strings, or other quantities. If a float is given, model or units would be used to specify the units.

Examples:

>>> from quantiphy import Quantity
>>> from math import pi, tau
>>> newline = '''
... '''

>>> fhy = Quantity('1420.405751786 MHz')
>>> sagan = Quantity(pi*fhy, 'Hz')
>>> sagan2 = Quantity(tau*fhy, fhy)
>>> print(fhy, sagan, sagan2, sep=newline)
1.4204 GHz
4.4623 GHz
8.9247 GHz

You can use scale to scale the number or convert to different units when creating the quantity.

Examples:

>>> Tfreeze = Quantity('273.15 K', ignore_sf=True, scale='°C')
>>> print(Tfreeze)
0 °C

>>> Tboil = Quantity('212 °F', scale='°C')
>>> print(Tboil)
100 °C
classmethod all_from_conv_fmt(text, **kwargs)

Convert all numbers and quantities from conventional notation.

Parameters:
  • text (str) – A search and replace is performed on this text. The search looks for numbers and quantities in floating point or e-notation. They are replaced with the same number rendered as a quantity. To be recognized any units must be simple (only letters or underscores, no digits or symbols) and the units must be immediately adjacent to the number.
  • **kwargs – By default the numbers are rendered using the currently active preferences, but any valid argument to Quantity.render() can be passed in to control the rendering.
Returns:

A copy of text where all numbers that were formatted conventionally have been reformatted.

Return type:

str

Example:

>>> text = 'Applying stimulus @ 2.05000e-05s: V(in) = 5.00000e-01V.'
>>> with Quantity.prefs(spacer=''):
...     xlated = Quantity.all_from_conv_fmt(text)
...     print(xlated)
Applying stimulus @ 20.5us: V(in) = 500mV.
classmethod all_from_si_fmt(text, **kwargs)

Convert all numbers and quantities from SI notation.

Parameters:
  • text (str) – A search and replace is performed on this text. The search looks for numbers and quantities formatted in SI notation (must have either a scale factor or units or both). They are replaced with the same number rendered as a quantity. To be recognized any units must be simple (only letters or underscores, no digits or symbols) and the units must be immediately adjacent to the number.
  • **kwargs – By default the numbers are rendered using the currently active preferences, but any valid argument to Quantity.render() can be passed in to control the rendering.
Returns:

A copy of text where all numbers that were formatted with SI scale factors have been reformatted.

Return type:

str

Example:

>>> print(Quantity.all_from_si_fmt(xlated))
Applying stimulus @ 20.5 us: V(in) = 500 mV.

>>> print(Quantity.all_from_si_fmt(xlated, show_si=False))
Applying stimulus @ 20.5e-6 s: V(in) = 500e-3 V.
as_tuple()

Returns a tuple that contains the value as a float along with its units.

Example:

>>> period = Quantity('10ns')
>>> period.as_tuple()
(1e-08, 's')
classmethod extract(text)

Extract quantities

Takes a string that contains quantity definitions, one per line, and returns those quantities in a dictionary.

Parameters:quantities (str) –

The string that contains the quantities, one definition per line. Each is parsed by assign_rec. By default, the lines are assumed to be of the form:

[<name> = <value>]
[<name> = <value>] [-- <description>]
[<name> = <value>] [# <description>]
[<name> = <value>] [// <description>]
[<name>: <value>]
[<name>: <value>] [-- <description>]
[<name>: <value>] [# <description>]
[<name>: <value>] [// <description>]

The brackets indicate that the name/value pair and the description is optional. However, <name> must be given if <value> is given.

<name>: the name is used as a key for the value.

<value>: A number with optional units (ex: 3 or 1pF or 1 kOhm), the units need not be a simple identifier (ex: 9.07 GHz/V).

<description>: Optional textual description (ex: Gain of PD (Imax)).

Blank lines and any line that does not contain a value are ignored. So with the default assign_rec, lines with the following form are ignored:

-- comment

# comment
// comment
Returns:a dictionary of quantities for the values specified in the argument.
Return type:dict
Raises:ValueError – Value is not a valid number or was not given a name.

Example:

>>> sagan_frequencies = r'''
...     -- Carl Sagan's SETI frequencies of high interest
...
...     f_hy = 1420.405751786 MHz -- Hydrogen line frequency
...     f_sagan1 = 4462.336274928 MHz -- Sagan's first frequency: pi*f_hy
...     f_sagan2 = 8924.672549855 MHz -- Sagan's second frequency: 2*pi*f_hy
... '''
>>> freqs = Quantity.extract(sagan_frequencies)
>>> for f in freqs.values():
...     print(f.render(show_label='f'))
f_hy = 1.4204 GHz -- Hydrogen line frequency
f_sagan1 = 4.4623 GHz -- Sagan's first frequency: pi*f_hy
f_sagan2 = 8.9247 GHz -- Sagan's second frequency: 2*pi*f_hy

>>> globals().update(freqs)
>>> print(f_hy, f_sagan1, f_sagan2, sep=newline)
1.4204 GHz
4.4623 GHz
8.9247 GHz
classmethod get_pref(name)

Get class preference

Returns the value of given preference.

Parameters:name (str) – Name of the desired preference. See Quantity.set_prefs() for list of preferences.
Raises:KeyError – unknown preference.

Example:

>>> Quantity.set_prefs(known_units='au')
>>> known_units = Quantity.get_pref('known_units')
>>> known_units.append('pc')
>>> Quantity.set_prefs(known_units=known_units)
>>> print(Quantity.get_pref('known_units'))
['au', 'pc']
is_close(other, reltol=None, abstol=None, check_units=True)

Are values equivalent?

Indicates whether the value of a quantity or real number is equivalent to that of a quantity. The two values need not be identical, they just need to be close to be deemed equivalent.

Parameters:
  • other (quantity or real) – The value to compare against.
  • reltol (float) – The relative tolerance. If not specified. the reltol preference is used, which defaults to 1u.
  • abstol (float) – The absolute tolerance. If not specified. the abstol preference is used, which defaults to 1p.
  • check_units (bool) – If True (the default), and if other is a quantity, compare the units of the two values, if they differ return False. Otherwise only compare the numeric values, ignoring the units.
Returns:

Returns true if abs(a - b) <= max(reltol * max(abs(a), abs(b)), abstol) where a and b represent other and the numeric value of the underlying quantity.

Return type:

bool

Example:

>>> print(
...     c.is_close(c),                     # should pass, is identical
...     c.is_close(c+1),                   # should pass, is close
...     c.is_close(c+1e4),                 # should fail, not close
...     c.is_close(Quantity(c+1, 'm/s')),  # should pass, is close
...     c.is_close(Quantity(c+1, 'Hz')),   # should fail, wrong units
... )
True True False True False
is_infinite()

Test value to determine if quantity is infinite.

Example:

>>> inf = Quantity('inf Hz')
>>> inf.is_infinite()
True
is_nan()

Test value to determine if quantity is not a number.

Example:

>>> nan = Quantity('NaN Hz')
>>> nan.is_nan()
True
static map_sf_to_greek(sf)

Render scale factors in Greek alphabet if appropriate.

Pass this dictionary to map_sf preference if you prefer μ rather than u.

Example:

>>> with Quantity.prefs(map_sf=Quantity.map_sf_to_greek):
...     print(Quantity('mu0').render(show_label='f'))
μ₀ = 1.2566 μH/m -- permeability of free space
static map_sf_to_sci_notation(sf)

Render scale factors in scientific notation

Pass this function to map_sf preference if you prefer your large and small numbers in classic scientific notation. It also causes ‘u’ to be converted to ‘μ’. Set show_si False to format all numbers in scientific notation.

Example:

>>> with Quantity.prefs(map_sf=Quantity.map_sf_to_sci_notation):
...     print(
...         Quantity('k').render(show_label='f'),
...         Quantity('mu0').render(show_label='f'),
...         sep=newline,
...     )
k = 13.806×10⁻²⁴ J/K -- Boltzmann's constant
μ₀ = 1.2566 μH/m -- permeability of free space
classmethod prefs(**kwargs)

Set class preferences.

This is just like Quantity.set_prefs(), except it is designed to work as a context manager, meaning that it is meant to be used with Python’s with statement. It allows preferences to be set to new values temporarily. They are reset upon exiting the with statement. For example:

>>> with Quantity.prefs(ignore_sf=True):
...     t = Quantity('600_000 K')
>>> t_bad = Quantity('600_000 K')
>>> print(t, t_bad, sep=newline)
600 kK
600M

See Quantity.set_prefs() for list of available arguments.

Raises:KeyError – unknown preference.
render(show_units=None, show_si=None, prec=None, show_label=None, scale=None)

Convert quantity to a string.

Parameters:
  • show_units (bool) – Whether the units should be included in the string.
  • show_si (bool) – Whether SI scale factors should be used. If true, SI scale factors are used if the appropriate scale factor is available, otherwise engineering format is used. If false, engineering format is used for all numbers. Engineering format is normal E-notation except that the exponents are constrained to be a multiple of 3.
  • prec (integer or 'full') – The desired precision (one plus this value is the desired number of digits). If specified as ‘full’, the full original precision is used.
  • show_label ('f', 'a', or boolean) –

    Add the name and possibly the description when rendering a quantity to a string. Either label_fmt or label_fmt_full is used to label the quantity.

    • neither is used if show_label is False,
    • otherwise label_fmt is used if quantity does not have a description or if show_label is ‘a’ (short for abbreviated),
    • otherwise label_fmt_full is used if show_desc is True or show_label is ‘f’ (short for full).
  • scale (real, pair, function, or string:) –
    • If a float, it scales the displayed value (the quantity is multiplied by scale before being converted to the string).
    • If a tuple, the first value, a float, is treated as a scale factor and the second value, a string, is take to be the units of the displayed value.
    • If a function, it takes two arguments, the value and the units of the quantity and it returns two values, the value and units of the displayed value.
    • If a string, it is taken to the be desired units. This value along with the units of the quantity are used to select a known unit conversion, which is applied to create the displayed value.
Raises:

KeyError – A unit conversion was requested and there is no corresponding unit converter.

Example:

>>> c = Quantity('c')
>>> print(
...     c.render(),
...     c.render(show_units=False),
...     c.render(show_si=False),
...     c.render(prec=6),
...     c.render(prec='full'),
...     c.render(show_label=True),
...     c.render(show_label='f'),
...     sep=newline
... )
299.79 Mm/s
299.79M
299.79e6 m/s
299.7925 Mm/s
299.792458 Mm/s
c = 299.79 Mm/s
c = 299.79 Mm/s -- speed of light

>>> print(
...     Tfreeze.render(scale='°F'),
...     Tboil.render(scale='°F'),
...     sep=newline
... )
32 °F
212 °F
classmethod set_prefs(**kwargs)

Set class preferences.

Any values not passed in are left alone. Pass in None to reset a preference to its default value.

Parameters:
  • abstol (float) – Absolute tolerance, used by Quantity.is_close() when determining equivalence. Default is 10⁻¹².
  • assign_rec (str) –

    Regular expression used to recognize an assignment. Used in constructor and extract(). By default an ‘=’ or ‘:’ separates the name from the value and a ‘–’, ‘#’ or ‘//’ separates the value from the description, if a description is given. So the default recognizes the following forms:

    'vel = 60 m/s'
    'vel = 60 m/s -- velocity'
    'vel = 60 m/s # velocity'
    'vel = 60 m/s // velocity'
    'vel: 60 m/s'
    'vel: 60 m/s -- velocity'
    'vel: 60 m/s # velocity'
    'vel: 60 m/s // velocity'
    

    The name, value, and description are identified in the regular expression using named groups the names name, val and desc. For example:

    assign_req = r'(?P<name>.*+) = (?P<val>.*?) -- (?P<desc>.*?)',
    
  • full_prec (int) – Default full precision in digits where 0 corresponds to 1 digit. Must be nonnegative. This precision is used when the full precision is requested and the precision is not otherwise known. Default is 12.
  • ignore_sf (bool) – Whether all scale factors should be ignored by default when recognizing numbers.
  • input_sf (str) – Which scale factors to recognize when reading numbers. The default is ‘YZEPTGMKk_cmuμnpfazy’. You can use this to ignore the scale factors you never expect to reduce the chance of a scale factor/unit ambiguity. For example, if you expect to encounter temperatures in Kelvin and can do without ‘K’ as a scale factor, you might use ‘TGMK_munpfa’. This also gets rid of the unusual scale factors.
  • keep_components (bool) – Indicate whether components should be kept if quantity value was given as string. Doing so takes a bit of space, but allows the original precision of the number to be recreated when full precision is requested.
  • known_units (list or string) – List of units that are expected to be used in preference to a scale factor when the leading character could be mistaken as a scale factor. If a string is given, it is split at white space to form the list. When set, any previous known units are overridden.
  • label_fmt (str) –

    Format string used when label is requested if the quantity does not have a description or if the description was not requested (if show_desc is False). Is passed through string .format() method. Format string takes two possible arguments named n and v for the name and value. A typical values include:

    '{n} = {v}'    (default)
    '{n}: {v}'
    
  • label_fmt_full (str) –

    Format string used when label is requested if the quantity has a description and the description was requested (if show_desc is True). Is passed through string .format() method. Format string takes four possible arguments named n, v, d and V for the name, value, description, and value as formatted by label_fmt. Typical value include:

    '{n} = {v} --  {d}'    (default)
    '{n} = {v} # {d}'
    '{n} = {v} // {d}'
    '{n}: {v} -- {d}'
    '{V} -- {d}'
    '{V:<20}  # {d}'
    

    The last example shows the V argument with alignment and width modifiers. In this case the modifiers apply to the name and value after being they are combined with the label_fmt. This is typically done when printing several quantities, one per line, because it allows you to line up the descriptions.

  • map_sf (dictionary or function) – Use this to change the way individual scale factors are rendered, ex: map_sf={‘u’: ‘μ’} to render micro using mu. If a function is given, it takes a single string argument, the nominal scale factor, and returns a string, the desired scale factor. QuantiPhy provides two predefined functions intended for use with maps_sf: Quantity.map_sf_to_greek() and Quantity.map_sf_to_sci_notation().
  • number_fmt (dictionary or function) –

    Format string used to convert the components of the number into the number itself. Normally this is not necessary. However, it can be used to perform special formatting that is helpful when aligning numbers in tables. It allows you to specify the widths and alignments of the individual components. There are three named components: whole, frac, and units. whole contains the portion of the mantissa to the left of the radix (decimal point). It is the whole mantissa if there is no radix. It also includes the sign and the leading units (currency symbols), if any. frac contains the radix and the fractional part. It also contains the exponent if the number has one. units contains the scale factor and units. The following value can be used to align both the radix and the units, and give the number a fixed width:

    number_fmt = '{whole:>3s}{frac:<4s} {units:<3s}'
    

    The various widths and alignments could be adjusted to fit a variety of needs.

    It is also possible to specify a function as number_fmt, in which case it is passed the three values in order (whole, frac and units) and it expected to return the number as a string.

  • output_sf (str) – Which scale factors to output, generally one would only use familiar scale factors. The default is ‘TGMkmunpfa’, which gets rid or the very large (‘YZEP’) and very small (‘zy’) scale factors that many people do not recognize.
  • prec (int) – Default precision in digits where 0 corresponds to 1 digit. Must be nonnegative. This precision is used when the full precision is not required. Default is 4.
  • reltol (float) – Relative tolerance, used by Quantity.is_close() when determining equivalence. Default is 10⁻⁶.
  • show_desc (bool) –

    Whether the description should be shown if it is available when showing the label. By default show_desc is False.

    Deprecated since version 2.1: Use show_label='f' instead.

  • show_label ('f', 'a', or bool) –

    Add the name and possibly the description when rendering a quantity to a string. Either label_fmt or label_fmt_full is used to label the quantity.

    • Neither is used if show_label is False,
    • otherwise label_fmt is used if quantity does not have a description or if show_label is ‘a’ (short for abbreviated),
    • otherwise label_fmt_full is used if show_desc is True or show_label is ‘f’ (short for full).
  • show_si (bool) – Use SI scale factors by default. If this is not set, engineering format is used. Engineering format is normal E-notation except that the exponents are constrained to be a multiple of 3.
  • spacer (str) – The spacer text to be inserted in a string between the numeric value and the scale factor when units are present. Is generally specified to be ‘’ or ‘ ‘; use the latter if you prefer a space between the number and the units. Generally using ‘ ‘ makes numbers easier to read, particularly with complex units, and using ‘’ is easier to parse. You could also use a Unicode non-breaking space ‘ ’. For your convenience, you can access a non-breaking space using Quantity.non_breaking_space.
  • strip_radix (bool) – When rendering, strip the radix (decimal point) from numbers even if they can then be mistaken for integers. By default this is True.
  • unity_sf (str) – The output scale factor for unity, generally ‘’ or ‘_’. The default is ‘’, but use ‘_’ if you want there to be no ambiguity between units and scale factors. For example, 0.3 would be rendered as ‘300m’, and 300 m would be rendered as ‘300_m’.
Raises:

KeyError – unknown preference.

Example:

>>> mu0 = Quantity('mu0')
>>> print(mu0)
1.2566 uH/m

>>> Quantity.set_prefs(prec=6, map_sf={'u': 'μ'})
>>> print(mu0)
1.256637 μH/m

>>> Quantity.set_prefs(prec=None, map_sf=None)
>>> print(mu0)
1.2566 uH/m

Unit Conversion

class quantiphy.UnitConversion(to_units, from_units, slope=1, intercept=0)

Creates a unit converter. Just the creation of the converter is sufficient to make it available to Quantity (the UnitConversion object itself is normally discarded). Once created, it is automatically employed by Quantity when a conversion is requested with the given units. A forward conversion is performed if the from and to units match, and a reversion conversion is performed if they are swapped.

Parameters:
  • to_units (string or list of strings) – A collection of units. If given as a single string it is split.
  • from_units (string or list of strings) – A collection of units. If given as a single string it is split.
  • slope (float) – Scale factor for conversion.
  • intercept (float) – Conversion offset.

Forward Conversion: The following conversion is applied if the given units are among the from_units and the desired units are among the to_units:

new_value = given_value * slope + intercept

Reverse Conversion: The following conversion is applied if the given units are among the to_units and the desired units are among the from_units:

new_value = (given_value - intercept)/slope

Example:

>>> from quantiphy import Quantity, UnitConversion
>>> UnitConversion('m', 'pc parsec', 3.0857e16)
<...>

This establishes a conversion between meters (m) and parsecs (parsec, pc) that can go both ways:

>>> d_sol = Quantity('5 μpc', scale='m')
>>> print(d_sol)
154.28 Gm

>>> d_ac = Quantity(1.339848, units='pc')
>>> print(d_ac.render(scale='m'))
41.344e15 m

Constants and Unit Systems

quantiphy.add_constant(value, alias=None, unit_systems=None)

Saves a quantity in such a way that it can later be recalled by name when creating new quantities.

Parameters:
  • value (quantity) – The value of the constant. Must be a quantity or a string that can be directly converted to a quantity.
  • alias (str) – An alias for the constant. Can be used to access the constant from as an alternative to the name given in the value, which itself is optional. If the value has a name, specifying this name is optional. If both are given, the constant is accessible using either name.
  • unit_systems (list or str) – Name or names of the unit systems to which the constant should be added. If given as a string, string will be split at white space to create the list. If a constant is associated with a unit system, it is only available when that unit system is active. You need not limit yourself to the predefined ‘mks’ and ‘cgs’ unit systems. Giving a name creates the corresponding unit system if it does not already exist. If unit_systems is not given, the constant is not associated with a unit system, meaning that it is always available regardless of which unit system is active.
Raises:
  • ValueErrorvalue must be an instance of Quantity or it must be a string that can be converted to a quantity.
  • NameErroralias was not specified and no name was available from value.

The constant is saved under name if given, and under the name contained within value if available. It is not necessary to supply both names, one is sufficient.

Example:

>>> from quantiphy import Quantity, add_constant
>>> add_constant('f_hy = 1420.405751786 MHz -- Frequency of hydrogen line')
>>> print(Quantity('f_hy').render(show_label='f'))
f_hy = 1.4204 GHz -- Frequency of hydrogen line
quantiphy.set_unit_system(unit_system)

Activates a unit system.

The default unit system is ‘mks’. Calling this function changes the active unit system to the one with the specified name. Only constants associated with the active unit system or not associated with a unit system are available for use.

Parameters:unit_system (str) – Name of the desired unit system.

A KeyError is raised if unit_system does not correspond to a known unit system.

Example:

>>> from quantiphy import Quantity, set_unit_system
>>> set_unit_system('cgs')
>>> print(Quantity('h').render(show_label='f'))
h = 6.6261e-27 erg-s -- Plank's constant

>>> set_unit_system('mks')
>>> print(Quantity('h').render(show_label='f'))
h = 662.61e-36 J-s -- Plank's constant