112 """Transform a tuple of slice objects into a Box2I, correctly handling negative indices.
114 see `interpretSliceArgs` for a description of parameters
118 box : `Box2I` or `None`
119 A box to use to create a subimage, or None if the slice refers to a
121 index: `tuple` or `None`
122 An ``(x, y)`` tuple of integers, or None if the slice refers to a
124 origin : `ImageOrigin`
125 Enum indicating whether to account for xy0.
128 if isinstance(slices, Point2I):
129 return None, slices, origin
130 elif isinstance(slices, Box2I):
131 return slices,
None, origin
135 if isinstance(x, slice):
136 assert isinstance(y, slice)
137 if x.step
is not None or y.step
is not None:
138 raise ValueError(
"Slices with steps are not supported in image indexing.")
139 begin = Point2I(x.start, y.start)
140 end = Point2I(x.stop, y.stop)
141 return Box2I(begin, end - begin),
None, origin
143 assert not isinstance(y, slice)
144 return None, Point2I(x, y), origin
148 """Transform arguments to __getitem__ or __setitem__ to a standard form.
152 sliceArgs : `tuple`, `Box2I`, or `Point2I`
153 Slice arguments passed directly to `__getitem__` or `__setitem__`.
154 bboxGetter : callable
155 Callable that accepts an ImageOrigin enum value and returns the
156 appropriate image bounding box. Usually the bound getBBox method
157 of an Image, Mask, or MaskedImage object.
162 Index or slice in the x dimension
164 Index or slice in the y dimension
165 origin : `ImageOrigin`
166 Either `PARENT` (coordinates respect XY0) or LOCAL
167 (coordinates do not respect XY0)
170 if isinstance(slices, Point2I):
171 return slices.getX(), slices.getY(), origin
172 elif isinstance(slices, Box2I):
173 x0 = slices.getMinX()
174 y0 = slices.getMinY()
175 return slice(x0, x0 + slices.getWidth()), slice(y0, y0 + slices.getHeight()), origin
176 elif isinstance(slices, slice):
177 if slices.start
is not None or slices.stop
is not None or slices.step
is not None:
178 raise TypeError(
"Single-dimension slices must not have bounds.")
185 bbox = bboxGetter(origin)
186 if isinstance(x, slice):
187 if isinstance(y, slice):
188 xSlice = slice(
handleNegativeIndex(x.start, bbox.getWidth(), origin, default=bbox.getBeginX()),
190 ySlice = slice(
handleNegativeIndex(y.start, bbox.getHeight(), origin, default=bbox.getBeginY()),
192 return xSlice, ySlice, origin
193 raise TypeError(
"Mixed indices of the form (slice, int) are not supported for images.")
195 if isinstance(y, slice):
196 raise TypeError(
"Mixed indices of the form (int, slice) are not supported for images.")
203 """Convert slicing format to numpy
205 LSST `afw` image-like objects use an `[x,y]` coordinate
206 convention, accept `Point2I` and `Box2I`
207 objects for slicing, and slice relative to the
208 bounding box `XY0` location;
209 while python and numpy use the convention `[y,x]`
210 with no `XY0`, so this method converts the `afw`
211 indices or slices into numpy indices or slices
215 sliceArgs: `sequence`, `Point2I` or `Box2I`
216 An `(xIndex, yIndex)` pair, or a single `(xIndex,)` tuple,
217 where `xIndex` and `yIndex` can be a `slice` or `int`,
218 or list of `int` objects, and if only a single `xIndex` is
219 given, a `Point2I` or `Box2I`.
220 bboxGetter : callable
221 Callable that accepts an ImageOrigin enum value and returns the
222 appropriate image bounding box. Usually the bound getBBox method
223 of an Image, Mask, or MaskedImage object.
228 Index or `slice` in the y dimension
230 Index or `slice` in the x dimension
232 Bounding box of the image.
233 If `bbox` is `None` then the result is a point and
234 not a subset of an image.
238 x0 = bboxGetter().getMinX()
239 y0 = bboxGetter().getMinY()
242 if isinstance(x, slice):
243 assert isinstance(y, slice)
244 bbox =
Box2I(Point2I(x.start, y.start), Extent2I(x.stop-x.start, y.stop-y.start))
245 x = slice(x.start - x0, x.stop - x0)
246 y = slice(y.start - y0, y.stop - y0)
252 elif origin != LOCAL:
253 raise ValueError(
"Unrecognized value for origin")
256 if isinstance(x, slice):
257 assert isinstance(y, slice)
258 bbox =
Box2I(Point2I(x.start + x0, y.start + y0),
259 Extent2I(x.stop-x.start, y.stop-y.start))
266 """Support image slicing
269 def Factory(self, *args, **kwargs):
270 """Return an object of this type
272 return cls(*args, **kwargs)
273 cls.Factory = Factory
276 """Return a deep copy of self"""
277 return cls(self,
True)
280 def __getitem__(self, imageSlice):
283 return self.subset(box, origin=origin)
284 return self._get(index, origin=origin)
285 cls.__getitem__ = __getitem__
287 def __setitem__(self, imageSlice, rhs):
290 if self.assign(rhs, box, origin)
is NotImplemented:
291 lhs = self.subset(box, origin=origin)
294 self._set(index, origin=origin, value=rhs)
295 cls.__setitem__ = __setitem__