From a9c529d8d35c1e3b15fc8d8db981f14213063b6d Mon Sep 17 00:00:00 2001 From: Nick Murphy Date: Tue, 23 Jul 2024 15:32:53 -0400 Subject: [PATCH] Copy over astropy units notebook --- notebooks/astropy-units.ipynb | 893 ++++++++++++++++++++++++++++++++++ 1 file changed, 893 insertions(+) create mode 100644 notebooks/astropy-units.ipynb diff --git a/notebooks/astropy-units.ipynb b/notebooks/astropy-units.ipynb new file mode 100644 index 0000000..14910a9 --- /dev/null +++ b/notebooks/astropy-units.ipynb @@ -0,0 +1,893 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "6e8f0d92", + "metadata": {}, + "source": [ + "# Using Astropy Units" + ] + }, + { + "cell_type": "markdown", + "id": "fbdc1fd8-6542-45a6-9375-c8016a15ac67", + "metadata": { + "nbsphinx": "hidden" + }, + "source": [ + "[`astropy.units`]: https://docs.astropy.org/en/stable/units/index.html\n", + "\n", + "This tutorial introduces us to [`astropy.units`], which is heavily used in PlasmaPy." + ] + }, + { + "cell_type": "markdown", + "id": "6d4214ce-e9a3-4e4a-a51c-6dcf3f00357b", + "metadata": {}, + "source": [ + "Let's start with some preliminary imports. To execute a cell in a Jupyter notebook, press **Shift + Enter**. If you need to restart the notebook, please execute this cell again.\n", + "\n", + "If using Google Colab, click **Run anyway** when prompted. (If prompted again, select **Restart runtime** when the installation finishes.)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "33fe81d8-c1e6-4fe2-97a4-d62ce59b94b3", + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "\n", + "import sys\n", + "\n", + "if 'google.colab' in str(get_ipython()):\n", + " if 'plasmapy' not in sys.modules:\n", + " !pip install plasmapy==2024.5.0\n", + "\n", + "import numpy as np\n", + "import astropy.units as u\n", + "import matplotlib.pyplot as plt\n", + "from astropy import visualization" + ] + }, + { + "cell_type": "markdown", + "id": "7c7ff8c4-5846-4cfd-9634-8b2aa8d871fa", + "metadata": {}, + "source": [ + "## Motivation" + ] + }, + { + "cell_type": "markdown", + "id": "c566fe1c", + "metadata": {}, + "source": [ + "In scientific computing, we often represent physical quantities as numbers." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ee456b33", + "metadata": {}, + "outputs": [], + "source": [ + "distance_in_miles = 50\n", + "time_in_hours = 2\n", + "velocity_in_mph = distance_in_miles / time_in_hours\n", + "print(velocity_in_mph)" + ] + }, + { + "cell_type": "markdown", + "id": "93658d4f", + "metadata": {}, + "source": [ + "[astropy.units]: https://docs.astropy.org/en/stable/units/index.html\n", + "[plasmapy.particles]: ../../particles/index.rst\n", + "[plasmapy.formulary]: ../../formulary/index.rst\n", + "\n", + "Representing a physical quantity as a number has risks. We might unknowingly perform operations with different units, like `time_in_seconds + time_in_hours`. We might even accidentally perform operations with physically incompatible units, like `length + time`, without catching our mistake. We can avoid these problems by using a units package.\n", + "\n", + "This notebook introduces [astropy.units] with an emphasis on the functionality needed to work with [plasmapy.particles] and [plasmapy.formulary]. We typically import this subpackage as `u`." + ] + }, + { + "cell_type": "markdown", + "id": "a9fad673", + "metadata": {}, + "source": [ + "## Unit essentials" + ] + }, + { + "cell_type": "markdown", + "id": "e9ccbb06", + "metadata": {}, + "source": [ + "We can create a _physical quantity_ by multiplying or dividing a number or array with a unit." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8437650a", + "metadata": {}, + "outputs": [], + "source": [ + "distance = 60 * u.km\n", + "print(distance)" + ] + }, + { + "cell_type": "markdown", + "id": "ccc6659f", + "metadata": {}, + "source": [ + "[`Quantity`]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity\n", + "\n", + "This operation creates a [`Quantity`] object: a number, sequence, or array that has been assigned a physical unit." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a6354b93", + "metadata": {}, + "outputs": [], + "source": [ + "type(distance)" + ] + }, + { + "cell_type": "markdown", + "id": "744a9b01", + "metadata": {}, + "source": [ + "[`Quantity`]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity\n", + "\n", + "We can create an object by using the [`Quantity`] class itself." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8d2bb681", + "metadata": {}, + "outputs": [], + "source": [ + "time = u.Quantity(120, u.min)" + ] + }, + { + "cell_type": "markdown", + "id": "1bb28951", + "metadata": {}, + "source": [ + "[`Quantity`]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity\n", + "\n", + "We can create [`Quantity`] objects with compound units." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4932159b", + "metadata": {}, + "outputs": [], + "source": [ + "88 * u.imperial.mile / u.hour" + ] + }, + { + "cell_type": "markdown", + "id": "9cc9adba", + "metadata": {}, + "source": [ + "[`Quantity`]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity\n", + "\n", + "We can even create [`Quantity`] objects that are explicitly dimensionless. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "09e9752c", + "metadata": {}, + "outputs": [], + "source": [ + "3 * u.dimensionless_unscaled" + ] + }, + { + "cell_type": "markdown", + "id": "4cffc8a0", + "metadata": {}, + "source": [ + "[`Quantity`]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity\n", + "\n", + "We can also create a [`Quantity`] based off of a NumPy array or a list." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e3235d80", + "metadata": {}, + "outputs": [], + "source": [ + "np.array([2.5, 3.2, 1.1]) * u.kg" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a686fd93", + "metadata": {}, + "outputs": [], + "source": [ + "[2, 3, 4] * u.m / u.s" + ] + }, + { + "cell_type": "markdown", + "id": "a60e9ea9", + "metadata": {}, + "source": [ + "## Unit operations\n", + "\n", + "[`Quantity`]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity\n", + "\n", + "Operations between [`Quantity`] objects handle unit conversions automatically. We can add [`Quantity`] objects together as long as their units have the same physical type." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "65e08284", + "metadata": {}, + "outputs": [], + "source": [ + "1 * u.m + 25 * u.cm" + ] + }, + { + "cell_type": "markdown", + "id": "edb43067", + "metadata": {}, + "source": [ + "Units get handled automatically during operations like multiplication, division, and exponentiation." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c36788db", + "metadata": {}, + "outputs": [], + "source": [ + "velocity = distance / time\n", + "print(velocity)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "04b48a57", + "metadata": {}, + "outputs": [], + "source": [ + "area = distance**2\n", + "print(area)" + ] + }, + { + "cell_type": "markdown", + "id": "98331629", + "metadata": {}, + "source": [ + "Attempting an operation between physically incompatible units gives us an error, which we can use to find bugs in our code." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0877feb6", + "metadata": { + "tags": [ + "raises-exception" + ] + }, + "outputs": [], + "source": [ + "3 * u.m + 3 * u.s" + ] + }, + { + "cell_type": "markdown", + "id": "4f0c461e", + "metadata": {}, + "source": [ + "[`Quantity`]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity\n", + "[`numpy.ndarray`]: https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html\n", + "\n", + "[`Quantity`] arrays behave very similarly to NumPy arrays. In fact, [`Quantity`] is a subclass of [`numpy.ndarray`]." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "59389429", + "metadata": {}, + "outputs": [], + "source": [ + "balmer_series = [656, 486, 434, 410] * u.nm\n", + "Hα = balmer_series[0]\n", + "print(Hα)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a6545132", + "metadata": {}, + "outputs": [], + "source": [ + "np.max(balmer_series)" + ] + }, + { + "cell_type": "markdown", + "id": "e1bb9434", + "metadata": {}, + "source": [ + "[NumPy]: https://numpy.org/\n", + "[SciPy]: https://scipy.org/\n", + "\n", + "[`Quantity`]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity\n", + "[lose their units]: https://docs.astropy.org/en/stable/known_issues.html#quantities-lose-their-units-with-some-operations\n", + "\n", + "⚠️ Most frequently encountered [NumPy] and [SciPy] functions can be used with [`Quantity`] objects. However, there are some functions that cause [`Quantity`] objects to [lose their units]!" + ] + }, + { + "cell_type": "markdown", + "id": "b910a84b", + "metadata": {}, + "source": [ + "## Unit conversions\n", + "\n", + "[`Quantity`]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity\n", + "[`to`]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity.to\n", + "\n", + "The [`to`] method allows us to convert a [`Quantity`] to different units of the same physical type. This method accepts strings that represent a unit (including compound units) or a unit object." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "80f4f133", + "metadata": {}, + "outputs": [], + "source": [ + "velocity.to(\"m/s\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "21c46ef1", + "metadata": {}, + "outputs": [], + "source": [ + "velocity.to(u.m / u.s)" + ] + }, + { + "cell_type": "markdown", + "id": "c1e742ca", + "metadata": {}, + "source": [ + "[`Quantity`]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity\n", + "[`si`]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity.si\n", + "[`cgs`]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity.cgs\n", + "\n", + "The [`si`] and [`cgs`] attributes convert the [`Quantity`] to SI or CGS units, respectively. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "02bda4d2", + "metadata": {}, + "outputs": [], + "source": [ + "velocity.si" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "560a0cfe", + "metadata": {}, + "outputs": [], + "source": [ + "velocity.cgs" + ] + }, + { + "cell_type": "markdown", + "id": "1429d5a2", + "metadata": {}, + "source": [ + "## Detaching units and values\n", + "\n", + "[`value`]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity.value \n", + "[`Quantity`]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity\n", + "\n", + "The [`value`] attribute of a [`Quantity`] provides the number or array *without* the unit." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "24e8403c", + "metadata": {}, + "outputs": [], + "source": [ + "time.value" + ] + }, + { + "cell_type": "markdown", + "id": "4c6c027b", + "metadata": {}, + "source": [ + "[`unit`]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity.unit\n", + "[`Quantity`]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity\n", + "\n", + "The [`unit`] attribute of a [`Quantity`] provides the unit without the value." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2c41a2fa", + "metadata": {}, + "outputs": [], + "source": [ + "time.unit" + ] + }, + { + "cell_type": "markdown", + "id": "be0c5349", + "metadata": {}, + "source": [ + "## Equivalencies" + ] + }, + { + "cell_type": "markdown", + "id": "07c3b9c1", + "metadata": {}, + "source": [ + "[electron-volt]: https://en.wikipedia.org/wiki/Electronvolt\n", + "[Boltzmann constant]: https://en.wikipedia.org/wiki/Boltzmann_constant\n", + "\n", + "Plasma scientists often use the [electron-volt] (eV) as a unit of temperature. This is a shortcut for describing the thermal energy per particle, or more accurately the temperature multiplied by the [Boltzmann constant], $k_B$. Because an electron-volt is a unit of energy rather than temperature, we cannot directly convert electron-volts to kelvin." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6b6fafd6", + "metadata": { + "tags": [ + "raises-exception" + ] + }, + "outputs": [], + "source": [ + "u.eV.to(\"K\")" + ] + }, + { + "cell_type": "markdown", + "id": "9299c8a1", + "metadata": {}, + "source": [ + "[`astropy.units`]: https://docs.astropy.org/en/stable/units/index.html\n", + "[equivalencies]: https://docs.astropy.org/en/stable/units/equivalencies.html\n", + "[`temperature_energy()`]: https://docs.astropy.org/en/stable/units/equivalencies.html#temperature-energy-equivalency\n", + "\n", + "To handle non-standard unit conversions, [`astropy.units`] allows the use of [equivalencies]. The conversion from eV to K can be done by using the [`temperature_energy()`] equivalency." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "afac5b4a", + "metadata": {}, + "outputs": [], + "source": [ + "(1 * u.eV).to(\"K\", equivalencies=u.temperature_energy())" + ] + }, + { + "cell_type": "markdown", + "id": "b4c492cc", + "metadata": {}, + "source": [ + "[`dimensionless_angles()`]: https://docs.astropy.org/en/stable/api/astropy.units.equivalencies.dimensionless_angles.html#dimensionless-angles\n", + "\n", + "[frequency]: https://en.wikipedia.org/wiki/Frequency\n", + "[angular frequency]: https://en.wikipedia.org/wiki/Angular_frequency\n", + "\n", + "Radians are treated dimensionlessly when the [`dimensionless_angles()`] equivalency is in effect. Note that this equivalency does not account for the multiplicative factor of $2π$ that is used when converting between [frequency] and [angular frequency]." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9735710b", + "metadata": {}, + "outputs": [], + "source": [ + "(3.2 * u.rad / u.s).to(\"1 / s\", equivalencies=u.dimensionless_angles())" + ] + }, + { + "cell_type": "markdown", + "id": "7ec6d857", + "metadata": {}, + "source": [ + "## Physical constants" + ] + }, + { + "cell_type": "markdown", + "id": "b714de6a", + "metadata": {}, + "source": [ + "[`astropy.constants`]: https://docs.astropy.org/en/stable/constants/index.html\n", + "\n", + "fWe can use [`astropy.constants`] to access the most commonly needed physical constants." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "746a79a7", + "metadata": {}, + "outputs": [], + "source": [ + "from astropy import constants\n", + "print(constants.c)" + ] + }, + { + "cell_type": "markdown", + "id": "c3ee9feb", + "metadata": {}, + "source": [ + "[`Constant`]: https://docs.astropy.org/en/stable/api/astropy.constants.Constant.html#astropy.constants.Constant\n", + "[`Quantity`]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity\n", + "[`u.temperature_energy()`]: https://docs.astropy.org/en/stable/units/equivalencies.html#temperature-energy-equivalency\n", + "\n", + "A [`Constant`] behaves very similarly to a [`Quantity`]. For example, we can use the Boltzmann constant to mimic the behavior of [`u.temperature_energy()`]." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d2d59d08", + "metadata": {}, + "outputs": [], + "source": [ + "thermal_energy_per_particle = 0.6 * u.keV\n", + "temperature = thermal_energy_per_particle / constants.k_B\n", + "print(temperature.to(\"MK\"))" + ] + }, + { + "cell_type": "markdown", + "id": "7c145497", + "metadata": {}, + "source": [ + "Electromagnetic constants often need the unit system to be specified, or will result in an exception." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "015de7fc", + "metadata": { + "tags": [ + "raises-exception" + ] + }, + "outputs": [], + "source": [ + "2 * constants.e" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1a90c979", + "metadata": {}, + "outputs": [], + "source": [ + "2 * constants.e.si" + ] + }, + { + "cell_type": "markdown", + "id": "41d93ce4-d0d5-4146-8e2e-5461c6ba12ce", + "metadata": {}, + "source": [ + "Code within PlasmaPy generally uses SI units." + ] + }, + { + "cell_type": "markdown", + "id": "cd539f42-ce70-4ecf-9bdc-e1f56a86dd07", + "metadata": {}, + "source": [ + "\n", + "## Plotting quantities" + ] + }, + { + "cell_type": "markdown", + "id": "90ced3d3-aa0d-47b7-b526-359e466e5cb5", + "metadata": {}, + "source": [ + "[`Quantity`]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity\n", + "\n", + "Astropy has built-in support for plotting [`Quantity`] objects. Let's plot the number density of electrons in the solar wind using an empirical formula given by [Kruparova et al. (2023)](https://iopscience.iop.org/article/10.3847/1538-4357/acf572), which has a range of validity from 13 to 50 solar radii." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2fce5587-16cf-40ea-baa5-dbd9023281c3", + "metadata": {}, + "outputs": [], + "source": [ + "radii = np.linspace(13, 50, num=50) * constants.R_sun" + ] + }, + { + "cell_type": "markdown", + "id": "d73d6343-d563-4f3d-ae41-a1eefaed4618", + "metadata": {}, + "source": [ + "Next we can apply the formula to get the electron density:\n", + "\n", + "$$ n_e(R) = \\left( 343466\\ \\mbox{cm}^{-3} \\right) × \\left( \\frac{R}{R_☉} \\right)^{-1.87} $$" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7a734940-a970-4991-9ada-f0844ae80567", + "metadata": {}, + "outputs": [], + "source": [ + "n_e = 343_466 * u.cm**-3 * (radii / constants.R_sun) ** -1.87" + ] + }, + { + "cell_type": "markdown", + "id": "1ed451a9-909f-40ae-bec7-c67d8767545c", + "metadata": {}, + "source": [ + "We can use the [`astropy.visualization.quantity_support`] to help with plotting `Quantity` objects against each other.\n", + "\n", + "Let's do some imports." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "60a5352b-b0ff-46fd-91c5-7acdab398412", + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "from astropy.visualization import quantity_support" + ] + }, + { + "cell_type": "markdown", + "id": "07547260-da42-40b7-98de-693b60dbb788", + "metadata": {}, + "source": [ + "Will make use make use of [`astropy.visualization.quantity_support`](https://docs.astropy.org/en/stable/api/astropy.visualization.quantity_support.html). This is a [_context manager_](https://realpython.com/python-with-statement/), which means that we use the `with` statement." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a4563556-64d3-4b7e-80f6-7df22ccf4488", + "metadata": {}, + "outputs": [], + "source": [ + "with quantity_support():\n", + " plt.figure()\n", + " plt.plot(radii.to(u.R_sun), n_e)\n", + " plt.draw()" + ] + }, + { + "cell_type": "markdown", + "id": "f4da2ab0", + "metadata": {}, + "source": [ + "## Optimizing unit operations (if time)\n", + "\n", + "[performance tips]: https://docs.astropy.org/en/stable/units/index.html#performance-tips\n", + "[`astropy.units`]: https://docs.astropy.org/en/stable/units/index.html\n", + "[`%timeit`]: https://ipython.readthedocs.io/en/stable/interactive/magics.html#magic-timeit\n", + "\n", + "Astropy's documentation includes [performance tips] for using [`astropy.units`] in computationally intensive situations. We can test it with [`%timeit`], which runs a command repeatedly to see how long it takes.\n", + "\n", + "Putting compound units in parentheses speeds things up by reducing the number of copies made by the operation." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e3bc2348", + "metadata": {}, + "outputs": [], + "source": [ + "%timeit 1.6 * u.barn * u.Mpc\n", + "%timeit 1.6 * (u.barn * u.Mpc)" + ] + }, + { + "cell_type": "markdown", + "id": "4ff6e798-91dd-460d-bf29-172a95bf34b7", + "metadata": {}, + "source": [ + "[`Quantity`]: https://docs.astropy.org/en/stable/api/astropy.units.Quantity.html#astropy.units.Quantity\n", + "\n", + "We can assign a unit to a value using the [`Quantity`] class directly." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "868b008e-1560-4edd-96ee-7ec1c00aca16", + "metadata": {}, + "outputs": [], + "source": [ + "%timeit u.Quantity(1.6, u.barn * u.Mpc)" + ] + }, + { + "cell_type": "markdown", + "id": "0f6bcf83-70d4-42e3-9392-9eaa73d3f3f9", + "metadata": {}, + "source": [ + "Can we do anything else to save time from the above operation?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3ecb16da-9dc3-4a62-a03a-e3afb312ae84", + "metadata": {}, + "outputs": [], + "source": [ + "volume_unit = u.barn * u.Mpc # pre-define the unit\n", + "%timeit u.Quantity(1.6, volume_unit)" + ] + }, + { + "cell_type": "markdown", + "id": "55b8dcd1", + "metadata": {}, + "source": [ + "## Physical types (if time)" + ] + }, + { + "cell_type": "markdown", + "id": "0421ee56", + "metadata": {}, + "source": [ + "[physical type]: https://docs.astropy.org/en/stable/units/physical_types.html\n", + "[`physical_type`]: https://docs.astropy.org/en/stable/api/astropy.units.UnitBase.html#astropy.units.UnitBase.physical_type\n", + "[`get_physical_type()`]: https://docs.astropy.org/en/stable/api/astropy.units.get_physical_type.html#astropy.units.get_physical_type\n", + "\n", + "A [physical type] corresponds to physical quantities with dimensionally compatible units. Astropy has functionality that represents different physical types. These physical type objects can be accessed using either the [`physical_type`] attribute of a unit or [`get_physical_type()`]." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "da6c9c7d", + "metadata": {}, + "outputs": [], + "source": [ + "(u.m**2 / u.s).physical_type" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f0d49b03", + "metadata": {}, + "outputs": [], + "source": [ + "u.get_physical_type(\"number density\")" + ] + }, + { + "cell_type": "markdown", + "id": "8cd7e09a", + "metadata": {}, + "source": [ + "These physical type objects can be used for dimensional analysis." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d03b8eb0", + "metadata": {}, + "outputs": [], + "source": [ + "energy_density = (u.J * u.m**-3).physical_type\n", + "velocity = u.get_physical_type(\"velocity\")\n", + "print(energy_density * velocity)" + ] + }, + { + "cell_type": "markdown", + "id": "ff6c5c8d-2a21-4314-8b03-5b1096e94232", + "metadata": {}, + "source": [ + "There are some pretty obscure physical types in here too!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2371647f-f29d-41cb-b89d-226d4743ce26", + "metadata": {}, + "outputs": [], + "source": [ + "u.get_physical_type(u.m * u.s)" + ] + } + ], + "metadata": { + "celltoolbar": "Tags", + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.1" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}