Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions autoarray/mask/abstract_mask.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ def __init__(
converted to a (float, float) structure.
origin
The origin of the mask's coordinate system in scaled units.
xp
The array module to use (default `numpy`; pass `jax.numpy` for JAX support). Controls
whether internal index arrays are computed on CPU or GPU.
"""

# noinspection PyArgumentList
Expand All @@ -62,6 +65,10 @@ def __init__(

@property
def _xp(self):
"""
Returns the array module in use (`numpy` or `jax.numpy`), determined by whether the mask was
constructed with `xp=jnp`.
"""
if self.use_jax:
import jax.numpy as jnp

Expand All @@ -70,6 +77,10 @@ def _xp(self):

@property
def mask(self):
"""
The boolean ndarray of the mask, where `False` entries are unmasked (used in calculations)
and `True` entries are masked (excluded from calculations).
"""
return self._array

def __array_finalize__(self, obj):
Expand All @@ -82,8 +93,10 @@ def __array_finalize__(self, obj):
@property
def pixel_scale(self) -> float:
"""
For a mask with dimensions two or above check that are pixel scales are the same, and if so return this
single value as a float.
The pixel scale of the mask as a single float value.

For masks with two or more dimensions this assumes all pixel scales are equal and returns
the first entry of ``pixel_scales``.
"""
return self.pixel_scales[0]

Expand All @@ -102,6 +115,9 @@ def header_dict(self) -> Dict:

@property
def dimensions(self) -> int:
"""
The number of dimensions of the mask (e.g. 1 for a 1D mask, 2 for a 2D mask).
"""
return len(self.shape)

def output_to_fits(self, file_path, overwrite=False):
Expand Down Expand Up @@ -154,7 +170,7 @@ def is_all_true(self) -> bool:
@property
def is_all_false(self) -> bool:
"""
Returns `False` if all pixels in a mask are `False`, else returns `True`.
Returns `True` if all pixels in a mask are `False` (i.e. every pixel is unmasked), else returns `False`.
"""
return self.pixels_in_mask == np.size(self._array)

Expand Down
36 changes: 15 additions & 21 deletions autoarray/mask/derive/grid_1d.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,18 @@ def __init__(self, mask: Mask1D):
omitted (for a full description see
the :meth:`Mask1D class API documentation <autoarray.mask.mask_1d.Mask1D.__new__>`).

From a ``Mask1D``,``Grid1D``s can be derived, which represent the (y,x) Cartesian coordinates of a subset of
From a ``Mask1D``, ``Grid1D``s can be derived, which represent the (x,) Cartesian coordinates of a subset of
pixels with significance.

For example:

- An ``all_false`` ``Grid1D``: the same shape as the original ``Mask1D`` but has unmasked ``False`` values
everywhere.
- An ``all_false`` ``Grid1D``: the (x,) coordinates of every pixel in the ``Mask1D`` regardless of whether
each pixel is masked or unmasked.

Parameters
----------
mask
The ``Mask2D`` from which new ``Grid2D`` objects are derived.
The ``Mask1D`` from which new ``Grid1D`` objects are derived.

Examples
--------
Expand All @@ -43,42 +43,36 @@ def __init__(self, mask: Mask1D):

import autoarray as aa

mask_2d = aa.Mask2D(
mask=[
[True, True, True, True, True],
[True, False, False, False, True],
[True, False, False, False, True],
[True, False, False, False, True],
[True, True, True, True, True],
],
mask_1d = aa.Mask1D(
mask=[True, False, False, False, True],
pixel_scales=1.0,
)

derive_grid_2d = aa.DeriveGrid2D(mask=mask_2d)
derive_grid_1d = aa.DeriveGrid1D(mask=mask_1d)

print(derive_grid_2d.border)
print(derive_grid_1d.all_false)
"""
self.mask = mask

@property
def all_false(self) -> Grid1D:
"""
Returns a ``Grid1D`` which uses the ``Mask1D``
geometry (``shape_native`` / ``pixel_scales`` / ``origin``) and every pixel in the ``Mask2D``
irrespective of whether pixels are masked or unmasked (given by ``True`` or``False``).
geometry (``shape_native`` / ``pixel_scales`` / ``origin``) and includes every pixel in the ``Mask1D``,
irrespective of whether pixels are masked or unmasked (given by ``True`` or ``False``).

For example, for the following ``Mask2D``:
For example, for the following ``Mask1D``:

::
mask_2d = aa.Mask1D(
mask=[False, False, True, True]
mask_1d = aa.Mask1D(
mask=[False, False, True, True],
pixel_scales=1.0,
)

The ``all_false`` ``Grid1D`` (given via ``mask_1d.derive_grid.all_false``) is:

::
[-2.0, -1.0, 1.0, 2.0]
[-1.5, -0.5, 0.5, 1.5]

Examples
--------
Expand All @@ -87,7 +81,7 @@ def all_false(self) -> Grid1D:

import autoarray as aa

mask_1d = aa.Mask2D(
mask_1d = aa.Mask1D(
mask=[False, False, True, True],
pixel_scales=1.0,
)
Expand Down
2 changes: 1 addition & 1 deletion autoarray/mask/derive/grid_2d.py
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ def border(self) -> Grid2D:
pixel_scales=1.0,
)

The ``edge`` grid (given via ``mask_2d.derive_grid.edge``) is given by:
The ``border`` grid (given via ``mask_2d.derive_grid.border``) is given by:

::
[[3.0, -3.0], [3.0, -2.0], [3.0, -1.0], [3.0, 0.0], [3.0, 1.0], [3.0, 2.0], [ 3.0, 3.0],
Expand Down
2 changes: 1 addition & 1 deletion autoarray/mask/derive/indexes_2d.py
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ def border_native(self) -> np.ndarray:
[
[1,1], [1,2], [1,3], [1,4], [1,5], [1,6], [1,7],
[2,1], [2,7], [3,1], [3,7], [4,1], [4,7], [5,1], [5,7], [6,1], [6,7],
[7,1], [7,2], 71,3], [7,4], [7,5], [7,6], [7,7]
[7,1], [7,2], [7,3], [7,4], [7,5], [7,6], [7,7]
]

The interior 8 ``False`` values (e.g. ``native`` index ``[3,3]``) are omitted, because although they are edge
Expand Down
2 changes: 1 addition & 1 deletion autoarray/mask/derive/mask_1d.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def to_mask_2d(self) -> Mask2D:
::
[True, False, False, False, True]

The corresponding ``Mask2D`` (given via ``mask_1d.derive_mask.to_mask_1d``) is:
The corresponding ``Mask2D`` (given via ``mask_1d.derive_mask.to_mask_2d``) is:

::
[[False, False, False, False, False]]
Expand Down
5 changes: 4 additions & 1 deletion autoarray/mask/derive/mask_2d.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,9 @@ def blurring_from(
----------
kernel_shape_native
The 2D shape of the 2D convolution ``Convolver`` which defines the blurring region.
allow_padding
If ``True``, blurring pixels that extend beyond the mask boundary are allowed. If ``False`` (default),
an exception is raised if the blurring region extends beyond the mask boundary.

Examples
--------
Expand Down Expand Up @@ -277,7 +280,7 @@ def edge_buffed(self) -> Mask2D:
"""
Returns a buffed edge ``Mask2D``, representing all unmasked pixels (given by ``False``) which neighbor any
masked value (give by ``True``) and therefore are on the edge of the 2D mask, but with a buffer of 1 pixel
applied such that everu pixel 1 pixel further out are included.
applied such that every pixel 1 pixel further out is included.

For example, for the following ``Mask2D``:

Expand Down
34 changes: 17 additions & 17 deletions autoarray/mask/derive/zoom_2d.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ def __init__(self, mask: Union[np.ndarray, List]):
omitted (for a full description see the :meth:`Mask2D` class API
documentation <autoarray.mask.mask_2d.Mask2D.__new__>`).

The `Zoom2D` object calculations many different zoomed in qu
The ``Zoom2D`` object computes the zoomed region around the unmasked pixels, including its centre,
pixel offsets, scaled offsets, and extracted sub-arrays for visualization.

Parameters
----------
Expand Down Expand Up @@ -90,15 +91,14 @@ def centre(self) -> Tuple[float, float]:
@property
def offset_pixels(self) -> Tuple[float, float]:
"""
Returns the offset of the centred of the zoomed in region from the centre of the `Mask2D` object in pixel
units.
Returns the (y,x) pixel offset of the centre of the zoomed region from the centre of the ``Mask2D``.

This is computed by subtracting the pixel coordinates of the `Mask2D` object from the pixel coordinates of
the zoomed in region.
This is the difference between the pixel coordinates of the zoomed region's centre and the pixel
coordinates of the full mask's central pixel.

Returns
-------
The offset of the zoomed in region from the centre of the `Mask2D` object in pixel units.
The (y,x) offset of the zoomed region centre from the mask centre in pixel units.
"""
if self.mask.pixel_scales is None:
return self.mask.geometry.central_pixel_coordinates
Expand All @@ -111,15 +111,13 @@ def offset_pixels(self) -> Tuple[float, float]:
@property
def offset_scaled(self) -> Tuple[float, float]:
"""
Returns the offset of the centred of the zoomed in region from the centre of the `Mask2D` object in scaled
units.
Returns the (y,x) scaled offset of the centre of the zoomed region from the centre of the ``Mask2D``.

This is computed by subtracting the pixel coordinates of the `Mask2D` object from the pixel coordinates of
the zoomed in region.
This converts ``offset_pixels`` to scaled units using the mask's ``pixel_scales``.

Returns
-------
The offset of the zoomed in region from the centre of the `Mask2D` object in scaled units.
The (y,x) offset of the zoomed region centre from the mask centre in scaled units.
"""
return (
-self.mask.pixel_scales[0] * self.offset_pixels[0],
Expand Down Expand Up @@ -173,17 +171,19 @@ def shape_native(self) -> Tuple[int, int]:

def extent_from(self, buffer: int = 1) -> np.ndarray:
"""
For an extracted zoomed array computed from the method *zoomed_around_mask* compute its extent in scaled
coordinates.
Compute the extent of the zoomed region in scaled coordinates, including an optional pixel buffer.

The extent of the grid in scaled units returned as an ``ndarray`` of the form [x_min, x_max, y_min, y_max].

This is used visualize zoomed and extracted arrays via the imshow() method.
The extent is returned as a tuple of the form ``(x_min, x_max, y_min, y_max)`` which matches the
``extent`` format expected by ``matplotlib.imshow``.

Parameters
----------
buffer
The number pixels around the extracted array used as a buffer.
The number of pixels around the unmasked region used as a buffer when computing the extent.

Returns
-------
The extent of the zoomed region as ``(x_min, x_max, y_min, y_max)`` in scaled units.
"""
from autoarray.mask.mask_2d import Mask2D

Expand Down
42 changes: 37 additions & 5 deletions autoarray/mask/mask_1d.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,13 @@ def __init__(
pixel_scales
The scaled units to pixel units conversion factor of each pixel.
origin
The x origin of the mask's coordinate system in scaled units.
The (x,) origin of the mask's coordinate system in scaled units.
invert
If `True`, the `bool`'s of the input `mask` are inverted, so `False` entries become `True`
and vice versa.
xp
The array module to use (default `numpy`; pass `jax.numpy` for JAX support). Controls
whether internal index arrays are computed on CPU or GPU.
"""

if type(mask) is list:
Expand Down Expand Up @@ -102,10 +108,18 @@ def geometry(self) -> Geometry1D:

@property
def derive_mask(self) -> DeriveMask1D:
"""
Returns the ``DeriveMask1D`` object associated with the mask, which computes derived masks such as
the edge mask.
"""
return DeriveMask1D(mask=self)

@property
def derive_grid(self) -> DeriveGrid1D:
"""
Returns the ``DeriveGrid1D`` object associated with the mask, which computes derived grids of (x,)
coordinates such as the unmasked pixel grid.
"""
return DeriveGrid1D(mask=self)

@classmethod
Expand All @@ -122,9 +136,14 @@ def all_false(
Parameters
----------
shape_slim
The (y,x) shape of the mask in units of pixels.
The 1D shape of the mask in units of pixels.
pixel_scales
The scaled units to pixel units conversion factor of each pixel.
origin
The (x,) scaled units origin of the mask's coordinate system.
invert
If `True`, the `bool`'s of the input `mask` are inverted, so `False` entries become `True`
and vice versa.
"""
return cls(
mask=np.full(shape=shape_slim, fill_value=False),
Expand All @@ -149,9 +168,16 @@ def from_fits(
file_path
The full path of the fits file.
hdu
The HDU number in the fits file containing the image image.
The HDU number in the ``.fits`` file containing the mask array.
pixel_scales
The scaled units to pixel units conversion factor of each pixel.
origin
The (x,) scaled units origin of the mask's coordinate system.

Returns
-------
Mask1D
The mask loaded from the ``.fits`` file.
"""

return cls(
Expand All @@ -164,19 +190,25 @@ def from_fits(

@property
def shape_native(self) -> Tuple[int]:
"""
The 1D shape of the mask in its native representation, equal to the shape of the underlying boolean ndarray.
"""
return self.shape

@property
def shape_slim(self) -> Tuple[int]:
"""
The 1D shape of the mask in its slim representation. For a 1D mask this is the same as ``shape_native``
since there is no native/slim distinction — every pixel is on the same 1D line.
"""
return self.shape

@property
def header_dict(self) -> Dict:
"""
Returns the pixel scales of the mask as a header dictionary, which can be written to a .fits file.

A 2D mask has different pixel scale variables for each dimension, the header therefore contain both pixel
scales as separate y and x entries.
A 1D mask has a single pixel scale, so the header contains one pixel scale entry alongside the origin.

Returns
-------
Expand Down
Loading
Loading