Skip to content

Commit 1bcd97f

Browse files
committed
First commit of docs explaining arithmetic operations.
1 parent 4baa3b0 commit 1bcd97f

File tree

2 files changed

+137
-0
lines changed

2 files changed

+137
-0
lines changed
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
.. _arithmetic:
2+
3+
*********************
4+
Arithmetic Operations
5+
*********************
6+
7+
Arithmetic operations are a crucial tool in n-dimensional data analysis.
8+
Applications include subtracting a background from a 1-D timeseries or spectrum, scaling an image by a vignetting function, any many others.
9+
To aid with such workflows, `~ndcube.NDCube` supports addition, subtraction, multiplication, and division with scalars, arrays, `~astropy.units.Quantity`.
10+
Raising an `~ndcube.NDCube` to a power is also supported.
11+
These operations return a new `~ndcube.NDCube` with the data array (and where appropriate, the uncertainties) altered in accordance with the arithmetic operation.
12+
Other attributes of the `~ndcube.NDCube` remain unchanged.
13+
14+
In addition, combining `~ndcube.NDCube` with coordinate-less `~astropy.nddata.NDData` subclasses via these operations is important.
15+
Such operations can be more complicated. Hence see the :ref:`arithmetic_nddata` section below for a discussion separate, more detailed discussion.
16+
17+
.. _arithmetic_standard:
18+
19+
Standard Arithmetic Operations
20+
==============================
21+
22+
Addition and Subtraction with Scalars, Arrays and Quantities
23+
------------------------------------------------------------
24+
25+
Let's demonstrate how we can add and subtract scalars, arrays and `~astropy.units.Quantity` to/from an `~ndcube.NDCube` called ``cube``.
26+
Note that addition and subtraction only changes the data values of the `~ndcube.NDCube`.
27+
28+
.. expanding-code-block:: python
29+
:summary: Expand to see my_cube instantiated.
30+
31+
>>> import astropy.units as u
32+
>>> import astropy.wcs
33+
>>> import numpy as np
34+
>>> from astropy.nddata import StdDevUncertainty
35+
36+
>>> from ndcube import NDCube
37+
38+
>>> # Define data array.
39+
>>> data = np.arange(2*3).reshape((2, 3)) + 10
40+
41+
>>> # Define WCS transformations in an astropy WCS object.
42+
>>> wcs = astropy.wcs.WCS(naxis=2)
43+
>>> wcs.wcs.ctype = 'HPLT-TAN', 'HPLN-TAN'
44+
>>> wcs.wcs.cunit = 'deg', 'deg'
45+
>>> wcs.wcs.cdelt = 0.5, 0.4
46+
>>> wcs.wcs.crpix = 2, 2
47+
>>> wcs.wcs.crval = 0.5, 1
48+
49+
>>> # Define mask. Initially set all elements unmasked.
50+
>>> mask = np.zeros_like(data, dtype=bool)
51+
>>> mask[0, :] = True # Now mask some values.
52+
>>> # Define uncertainty, metadata and unit.
53+
>>> uncertainty = StdDevUncertainty(np.sqrt(np.abs(data)))
54+
>>> meta = {"Description": "This is example NDCube metadata."}
55+
>>> unit = u.ct
56+
57+
>>> # Instantiate NDCube with supporting data.
58+
>>> cube = NDCube(data, wcs=wcs, uncertainty=uncertainty, mask=mask, meta=meta)
59+
60+
.. code-block:: python
61+
62+
>>> cube.data
63+
array([[10, 11, 12],
64+
[13, 14, 15]])
65+
>>> new_cube = cube + 1
66+
>>> new_cube.data
67+
array([[11, 12, 13],
68+
[14, 15, 16]])
69+
70+
Note that all the data values have been increased by 1.
71+
We can also add an array if we want to add a different number to each data element:
72+
73+
.. code-block:: python
74+
75+
>>> import numpy as np
76+
>>> arr = np.arange(cube.data.size).reshape(cube.data.shape)
77+
>>> arr
78+
array([[0, 1, 2],
79+
[3, 4, 5]])
80+
>>> new_cube = cube + arr
81+
>>> new_cube.data
82+
array([[10, 12, 14],
83+
[16, 18, 20]])
84+
85+
Subtraction works in the same way.
86+
87+
.. code-block:: python
88+
89+
>>> new_cube = cube - 1
90+
>>> new_cube.data
91+
array([[ 9, 10, 11],
92+
[12, 13, 14]])
93+
>>> new_cube = cube - arr
94+
>>> new_cube.data
95+
array([[10, 10, 10],
96+
[10, 10, 10]])
97+
98+
Note that ``cube`` has no unit, which is why we are able to add and subtract scalars and arrays.
99+
If, however, we have an `~ndcube.NDCube` with a unit assigned,
100+
101+
.. code-block:: python
102+
103+
>>> cube_unitful = NDCube(cube, unit=u.ct)
104+
105+
then adding or subtracting an array or unitless scalar will raise an error.
106+
In such cases, we must use a `~astropy.unit.Quantity` with a compatible unit:
107+
108+
.. code-block:: python
109+
110+
>>> cube.data
111+
array([[10, 11, 12],
112+
[13, 14, 15]])
113+
>>> new_cube = cube_unitful + 1 * u.ct # Adding a scalar quantity
114+
>>> new_cube.data
115+
array([[11, 12, 13],
116+
[14, 15, 16]])
117+
>>> new_cube = cube_unitful - 1 * u.ct # Subtracting a scalar quantity
118+
>>> new_cube.data
119+
array([[ 9, 10, 11],
120+
[12, 13, 14]])
121+
>>> new_cube = cube_unitful + arr * u.ct # Adding an array-like quantity
122+
>>> new_cube.data
123+
array([[10, 12, 14],
124+
[16, 18, 20]])
125+
>>> new_cube = cube_unitful - arr * u.ct # Subtracting an array-like quantity
126+
>>> new_cube.data
127+
array([[10, 10, 10],
128+
[10, 10, 10]])
129+
130+
Multiplying and Dividing with Scalars, Arrays and Quantities
131+
------------------------------------------------------------
132+
133+
.. _arithmetic_nddata:
134+
135+
Arithmetic Operations with Coordinate-less NDData
136+
=================================================

docs/explaining_ndcube/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ Explaining ``ndcube``
1414
tabular_coordinates
1515
reproject
1616
visualization
17+
arithmetic_operations

0 commit comments

Comments
 (0)