{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Physical units\n", "\n", "All variables in Scipp have a physical unit.\n", "Variables are used for coordinates, data, and attributes, therefore, all of these have a unit.\n", "\n", "## Basic Operations\n", "\n", "Units are encoded by the [scipp.Unit](../generated/classes/scipp.Unit.rst) class.\n", "Instances of this class can be constructed from strings:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import scipp as sc\n", "\n", "length = sc.Unit('m')\n", "length" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[scipp.Unit](../generated/classes/scipp.Unit.rst) defines mathematical operators for combining units:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "area = length * length\n", "area" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "volume = length * length * length\n", "volume" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "also_volume = length**3\n", "also_volume" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sc.Unit('dimensionless') / length" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "speed = length / sc.Unit('s')\n", "speed" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Invalid operations raise exceptions:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [ "raises-exception" ] }, "outputs": [], "source": [ "speed + length" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It is also possible to construct composite units directly from strings:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sc.Unit('km')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sc.Unit('m/s')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sc.Unit('counts')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sc.Unit('kg*m^2/s^2')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For convenience, the [scipp.units](../generated/modules/scipp.units.rst) module provides some frequently used units.\n", "See [scipp.units](../generated/modules/scipp.units.rst) for a list of those units." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sc.units.kg" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sc.units.m / sc.units.s" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sc.units.dimensionless" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Use `repr` to see a unit in terms of SI (plus extensions) base units:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "repr(sc.Unit('V/L'))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is especially helpful when it is unclear what a particular unit represents." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Constructing Variables with Units\n", "\n", "[Variables](../generated/classes/scipp.Variable.rst#scipp.Variable) with units can be constructed using the `units` argument in the constructor or in [creation functions](./creation-functions.rst).\n", "When not specified explicitly, the unit of a variable usually (see below) defaults to `dimensionless` (a.k.a. `one`).\n", "That is, the variable is considered dimensionless in terms of units (not to be confused with array dimensions)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# same as sc.array(dims=['x'], values=[1, 2])\n", "# and sc.array(dims=['x'], values=[1, 2], unit='dimensionless')\n", "sc.array(dims=['x'], values=[1, 2], unit='one')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sc.array(dims=['x'], values=[1, 2], unit='m')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sc.array(dims=['x'], values=[1, 2], unit=sc.units.m)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sc.arange('x', 0, 3, unit=sc.units.s)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Scalars can also be constructed using multiplication or division of a number and a unit (in addition to [scipp.scalar](../generated/functions/scipp.scalar.rst#scipp.scalar)):" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "1.2 * sc.Unit('kg/m^3')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "3.4 / sc.units.K" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Variables Without Units\n", "\n", "It is not always meaningful to assign a unit to a variable.\n", "For example, what is the unit of a string or a truth value?\n", "For this reason, Scipp allows variables to have no unit by setting `unit=None`:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "jupyter": { "outputs_hidden": false }, "tags": [] }, "outputs": [], "source": [ "sc.array(dims=['x'], values=[2, 4, 6], unit=None)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For non-numeric dtypes, the unit defaults to `None`:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "jupyter": { "outputs_hidden": false } }, "outputs": [], "source": [ "sc.array(dims=['x'], values=[False, True, False])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "jupyter": { "outputs_hidden": false } }, "outputs": [], "source": [ "sc.scalar('a string')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Indices are also non-physical quantities, so they should typically be defined without a unit, too.\n", "To help with this, Scipp provides `sc.index`:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "jupyter": { "outputs_hidden": false } }, "outputs": [], "source": [ "sc.index(123)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Variables without units can interoperate like variables with units.\n", "But the two groups cannot be combined:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "jupyter": { "outputs_hidden": false }, "tags": [ "raises-exception" ] }, "outputs": [], "source": [ "sc.scalar(1, unit='one') * sc.scalar(2, unit=None)" ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "## Supported Units\n", "\n", "Scipp supports a great number of units through LLNL's [Units](https://units.readthedocs.io/en/latest/index.html) library.\n", "See in particular [Defined Units](https://units.readthedocs.io/en/latest/user-guide/defined_units.html).\n", "\n", "