Bounding boxes

class galsim.Bounds[source]

A class for representing image bounds as 2D rectangles.

Bounds is a base class for two slightly different kinds of bounds: BoundsD describes bounds with floating point values in x and y. BoundsI described bounds with integer values in x and y.

The bounds are stored as four numbers in each instance, (xmin, xmax, ymin, ymax), with an additional boolean switch to say whether or not the Bounds rectangle has been defined. The rectangle is undefined if the min value > the max value in either direction.

Initialization:

A BoundsI or BoundsD instance can be initialized in a variety of ways. The most direct is via four scalars:

>>> bounds = galsim.BoundsD(xmin, xmax, ymin, ymax)
>>> bounds = galsim.BoundsI(imin, imax, jmin, jmax)

In the BoundsI example above, imin, imax, jmin and jmax must all be integers to avoid a TypeError exception.

Another way to initialize a Bounds instance is using two Position instances, the first for (xmin,ymin) and the second for (xmax,ymax):

>>> bounds = galsim.BoundsD(galsim.PositionD(xmin, ymin), galsim.PositionD(xmax, ymax))
>>> bounds = galsim.BoundsI(galsim.PositionI(imin, jmin), galsim.PositionI(imax, jmax))

In both the examples above, the I/D type of PositionI/PositionD must match that of BoundsI/BoundsD.

Finally, there are a two ways to lazily initialize a bounds instance with xmin = xmax, ymin = ymax, which will have an undefined rectangle and the instance method isDefined() will return False. The first sets xmin = xmax = ymin = ymax = 0:

>>> bounds = galsim.BoundsD()
>>> bounds = galsim.BoundsI()

The second method sets both upper and lower rectangle bounds to be equal to some position:

>>> bounds = galsim.BoundsD(galsim.PositionD(xmin, ymin))
>>> bounds = galsim.BoundsI(galsim.PositionI(imin, jmin))

Once again, the I/D type of PositionI/PositionD must match that of BoundsI/BoundsD.

For the latter two initializations, you would typically then add to the bounds with:

>>> bounds += pos1
>>> bounds += pos2
>>> [etc.]

Then the bounds will end up as the bounding box of all the positions that were added to it.

You can also find the intersection of two bounds with the & operator:

>>> overlap = bounds1 & bounds2

This is useful for adding one image to another when part of the first image might fall off the edge of the other image:

>>> overlap = stamp.bounds & image.bounds
>>> image[overlap] += stamp[overlap]
area()[source]

Return the area of the enclosed region.

The area is a bit different for integer-type BoundsI and float-type BoundsD instances. For floating point types, it is simply (xmax-xmin)*(ymax-ymin). However, for integer types, we add 1 to each size to correctly count the number of pixels being described by the bounding box.

property center

The central position of the Bounds.

For a BoundsI, this will return an integer PositionI, which will be above and/or to the right of the true center if the x or y ranges have an even number of pixels.

For a BoundsD, this is equivalent to true_center.

expand(factor_x, factor_y=None)[source]

Grow the Bounds by the supplied factor about the center.

If two arguments are given, then these are separate x and y factors to expand by.

getXMax()[source]

Get the value of xmax.

getXMin()[source]

Get the value of xmin.

getYMax()[source]

Get the value of ymax.

getYMin()[source]

Get the value of ymin.

includes(*args)[source]

Test whether a supplied (x,y) pair, Position, or Bounds lie within a defined Bounds rectangle of this instance.

Examples:

>>> bounds = galsim.BoundsD(0., 100., 0., 100.)
>>> bounds.includes(50., 50.)
True
>>> bounds.includes(galsim.PositionD(50., 50.))
True
>>> bounds.includes(galsim.BoundsD(-50., -50., 150., 150.))
False

The type of the PositionI/PositionD and BoundsI/BoundsD instances (i.e. integer or float type) should match that of the bounds instance.

isDefined()[source]

Test whether Bounds rectangle is defined.

property origin

The lower left position of the Bounds.

shift(delta)[source]

Shift the Bounds instance by a supplied Position.

Examples:

The shift method takes either a PositionI or PositionD instance, which must match the type of the Bounds instance:

>>> bounds = BoundsI(1,32,1,32)
>>> bounds = bounds.shift(galsim.PositionI(3, 2))
>>> bounds = BoundsD(0, 37.4, 0, 49.9)
>>> bounds = bounds.shift(galsim.PositionD(3.9, 2.1))
property true_center

The central position of the Bounds as a PositionD.

This is always (xmax + xmin)/2., (ymax + ymin)/2., even for integer BoundsI, where this may not necessarily be an integer PositionI.

withBorder(dx, dy=None)[source]

Return a new Bounds object that expands the current bounds by the specified width.

If two arguments are given, then these are separate dx and dy borders.

class galsim.BoundsI(*args, **kwargs)[source]

Bases: Bounds

A Bounds that takes only integer values.

Typically used to define the bounding box of an image.

See the Bounds doc string for more details.

numpyShape()[source]

A simple utility function to get the numpy shape that corresponds to this Bounds object.

class galsim.BoundsD(*args, **kwargs)[source]

Bases: Bounds

A Bounds that takes floating point values.

See the Bounds doc string for more details.

galsim._BoundsI(xmin, xmax, ymin, ymax)[source]

Equivalent to BoundsI constructor, but skips some sanity checks and argument parsing. This requires that the four values be int types.

galsim._BoundsD(xmin, xmax, ymin, ymax)[source]

Equivalent to BoundsD constructor, but skips some sanity checks and argument parsing. This requires that the four values be float types.