lsst.scarlet.lite gee10cc3b42+90ebb246c7
Loading...
Searching...
No Matches
Public Member Functions | Static Public Member Functions | Public Attributes | Protected Member Functions | List of all members
lsst.scarlet.lite.bbox.Box Class Reference

Public Member Functions

 __init__ (self, tuple[int,...] shape, tuple[int,...]|None origin=None)
 
bool contains (self, Sequence[int] p)
 
int ndim (self)
 
tuple[int,...] start (self)
 
tuple[int,...] stop (self)
 
tuple[float,...] center (self)
 
tuple[tuple[int, int],...] bounds (self)
 
tuple[slice,...] slices (self)
 
Box grow (self, int|tuple[int,...] radius)
 
Box shifted_by (self, Sequence[int] shift)
 
bool intersects (self, Box other)
 
tuple[tuple[slice,...], tuple[slice,...]] overlapped_slices (self, Box other)
 
Box __or__ (self, Box other)
 
Box __and__ (self, Box other)
 
Box __getitem__ (self, int|slice|tuple[int,...] index)
 
str __repr__ (self)
 
Box __add__ (self, int|Sequence[int] offset)
 
Box __sub__ (self, int|Sequence[int] offset)
 
Box __matmul__ (self, Box bbox)
 
Box __copy__ (self)
 
Box copy (self)
 
bool __eq__ (self, object other)
 
int __hash__ (self)
 

Static Public Member Functions

Box from_bounds (*tuple[int,...] bounds)
 
Box from_data (np.ndarray x, float threshold=0)
 

Public Attributes

 shape
 
 origin
 
 ndim
 

Protected Member Functions

tuple[int,...] _offset_to_tuple (self, int|Sequence[int] offset)
 

Detailed Description

Bounding Box for an object

A Bounding box describes the location of a data unit in the
global/model coordinate system, using the row-major
(default numpy/C++) ordering convention.
So, for example, a 2D image will have shape ``(height, width)``,
however the bounding `Box` code is agnostic as to number of dimensions
or the meaning of those dimensions.

Examples
--------

At a minimum a new `Box` can be initialized using the ``shape`` of the
region it describes:

>>> from lsst.scarlet.lite import Box
>>> bbox = Box((3, 4, 5, 6))
>>> print(bbox)
Box(shape=(3, 4, 5, 6), origin=(0, 0, 0, 0))

If the region described by the `Box` is offset from the zero origin,
a new ``origin`` can be passed to the constructor

>>> bbox = Box((3, 4, 5, 6), (2, 4, 7, 9))
>>> print(bbox)
Box(shape=(3, 4, 5, 6), origin=(2, 4, 7, 9))

It is also possible to initialize a `Box` from a collection of tuples,
where tuple is a pair of integers representing the
first and last index in each dimension. For example:

>>> bbox = Box.from_bounds((3, 6), (11, 21))
>>> print(bbox)
Box(shape=(3, 10), origin=(3, 11))

It is also possible to initialize a `Box` by thresholding a numpy array
and including only the region of the image above the threshold in the
resulting `Box`. For example

>>> from lsst.scarlet.lite.utils import integrated_circular_gaussian
>>> data = integrated_circular_gaussian(sigma=1.0)
>>> bbox = Box.from_data(data, 1e-2)
>>> print(bbox)
Box(shape=(5, 5), origin=(5, 5))

The `Box` class contains a number of convenience methods that can be used
to extract subsets of an array, combine bounding boxes, etc.

For example, using the ``data`` and ``bbox`` from the end of the previous
section, the portion of the data array that is contained in the bounding
box can be extraced usng the `Box.slices` method:

>>> subset = data[bbox.slices]

The intersection of two boxes can be calcualted using the ``&`` operator,
for example

>>> bbox = Box((5, 5)) & Box((5, 5), (2, 2))
>>> print(bbox)
Box(shape=(3, 3), origin=(2, 2))

Similarly, the union of two boxes can be calculated using the ``|``
operator:

>>> bbox = Box((5, 5)) | Box((5, 5), (2, 2))
>>> print(bbox)
Box(shape=(7, 7), origin=(0, 0))

To find out of a point is located in a `Box` use

>>> contains = bbox.contains((3, 3))
>>> print(contains)
True

To find out if two boxes intersect (in other words ``box1 & box2`` has a
non-zero size) use

>>> intersects = bbox.intersects(Box((10, 10), (100, 100)))
>>> print(intersects)
False

It is also possible to shift a box by a vector (sequence):

>>> bbox = bbox + (50, 60)
>>> print(bbox)
Box(shape=(7, 7), origin=(50, 60))

which can also be negative

>>> bbox = bbox - (5, -5)
>>> print(bbox)
Box(shape=(7, 7), origin=(45, 65))

Boxes can also be converted into higher dimensions using the
``@`` operator:

>>> bbox1 = Box((10,), (3, ))
>>> bbox2 = Box((101, 201), (18, 21))
>>> bbox = bbox1 @ bbox2
>>> print(bbox)
Box(shape=(10, 101, 201), origin=(3, 18, 21))

Boxes are equal when they have the same shape and the same origin, so

>>> print(Box((10, 10), (5, 5)) == Box((10, 10), (5, 5)))
True

>>> print(Box((10, 10), (5, 5)) == Box((10, 10), (4, 4)))
False

Finally, it is common to insert one array into another when their bounding
boxes only partially overlap.
In order to correctly insert the overlapping portion of the array it is
convenient to calculate the slices from each array that overlap.
For example:

>>> import numpy as np
>>> x = np.arange(12).reshape(3, 4)
>>> y = np.arange(9).reshape(3, 3)
>>> print(x)
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
>>> print(y)
[[0 1 2]
 [3 4 5]
 [6 7 8]]
>>> x_box = Box.from_data(x) + (3, 4)
>>> y_box = Box.from_data(y) + (1, 3)
>>> slices = x_box.overlapped_slices(y_box)
>>> x[slices[0]] += y[slices[1]]
>>> print(x)
[[ 7  9  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]

Parameters
----------
shape:
    Size of the box in each dimension.
origin:
    Minimum corner coordinate of the box.
    This defaults to ``(0, ...)``.

Member Function Documentation

◆ __add__()

Box lsst.scarlet.lite.bbox.Box.__add__ ( self,
int | Sequence[int] offset )
Generate a new Box with a shifted offset

Parameters
----------
offset:
    The amount to shift the current offset

Returns
-------
result:
    The shifted box.

◆ __and__()

Box lsst.scarlet.lite.bbox.Box.__and__ ( self,
Box other )
Intersection of two bounding boxes

If there is no intersection between the two bounding
boxes then an empty bounding box is returned.

Parameters
----------
other:
    The other bounding box in the intersection

Returns
-------
result:
    The rectangular box that is in the overlap region
    of both boxes.

◆ __copy__()

Box lsst.scarlet.lite.bbox.Box.__copy__ ( self)
Copy of the box

◆ __eq__()

bool lsst.scarlet.lite.bbox.Box.__eq__ ( self,
object other )
Check for equality.

Two boxes are equal when they have the same shape and origin.

◆ __matmul__()

Box lsst.scarlet.lite.bbox.Box.__matmul__ ( self,
Box bbox )
Combine two Boxes into a higher dimensional box

Parameters
----------
bbox:
    The box to append to this box.

Returns
-------
result:
    The combined Box.

◆ __or__()

Box lsst.scarlet.lite.bbox.Box.__or__ ( self,
Box other )
Union of two bounding boxes

Parameters
----------
other:
    The other bounding box in the union

Returns
-------
result:
    The smallest rectangular box that contains *both* boxes.

◆ __sub__()

Box lsst.scarlet.lite.bbox.Box.__sub__ ( self,
int | Sequence[int] offset )
Generate a new Box with a shifted offset in the negative direction

Parameters
----------
offset:
    The amount to shift the current offset

Returns
-------
result:
    The shifted box.

◆ _offset_to_tuple()

tuple[int, ...] lsst.scarlet.lite.bbox.Box._offset_to_tuple ( self,
int | Sequence[int] offset )
protected
Expand an integer offset into a tuple

Parameters
----------
offset:
    The offset to (potentially) convert into a tuple.

Returns
-------
offset:
    The offset as a tuple.

◆ bounds()

tuple[tuple[int, int], ...] lsst.scarlet.lite.bbox.Box.bounds ( self)
Bounds of the box

◆ center()

tuple[float, ...] lsst.scarlet.lite.bbox.Box.center ( self)
Tuple of center coordinates

◆ contains()

bool lsst.scarlet.lite.bbox.Box.contains ( self,
Sequence[int] p )
Whether the box contains a given coordinate `p`

◆ copy()

Box lsst.scarlet.lite.bbox.Box.copy ( self)
Copy of the box

◆ from_bounds()

Box lsst.scarlet.lite.bbox.Box.from_bounds ( *tuple[int, ...] bounds)
static
Initialize a box from its bounds

Parameters
----------
bounds:
    Min/Max coordinate for every dimension

Returns
-------
bbox:
    A new box bounded by the input bounds.

◆ from_data()

Box lsst.scarlet.lite.bbox.Box.from_data ( np.ndarray x,
float threshold = 0 )
static
Define range of `x` above `min_value`.

This method creates the smallest `Box` that contains all of the
elements in `x` that are above `min_value`.

Parameters
----------
x:
    Data to threshold to specify the shape/dimensionality of `x`.
threshold:
    Threshold for the data.
    The box is trimmed so that all elements bordering `x` smaller than
    `min_value` are ignored.

Returns
-------
bbox:
    Bounding box for the thresholded `x`

◆ grow()

Box lsst.scarlet.lite.bbox.Box.grow ( self,
int | tuple[int, ...] radius )
Grow the Box by the given radius in each direction

◆ intersects()

bool lsst.scarlet.lite.bbox.Box.intersects ( self,
Box other )
Check if two boxes overlap

Parameters
----------
other:
    The boxes to check for overlap

Returns
-------
result:
    True when the two boxes overlap.

◆ ndim()

int lsst.scarlet.lite.bbox.Box.ndim ( self)
Dimensionality of this BBox

◆ overlapped_slices()

tuple[tuple[slice, ...], tuple[slice, ...]] lsst.scarlet.lite.bbox.Box.overlapped_slices ( self,
Box other )
Return `slice` for the box that contains the overlap of this and
another `Box`

Parameters
----------
other:

Returns
-------
slices:
    The slice of an array bounded by `self` and
    the slice of an array bounded by `other` in the
    overlapping region.

◆ shifted_by()

Box lsst.scarlet.lite.bbox.Box.shifted_by ( self,
Sequence[int] shift )
Generate a shifted copy of this box

Parameters
----------
shift:
    The amount to shift each axis to create the new box

Returns
-------
result:
    The resulting bounding box.

◆ slices()

tuple[slice, ...] lsst.scarlet.lite.bbox.Box.slices ( self)
Bounds of the box as slices

◆ start()

tuple[int, ...] lsst.scarlet.lite.bbox.Box.start ( self)
Tuple of start coordinates

◆ stop()

tuple[int, ...] lsst.scarlet.lite.bbox.Box.stop ( self)
Tuple of stop coordinates

The documentation for this class was generated from the following file: