@@ -103,16 +103,48 @@ def _fetch_data(self) -> typing.Optional[np.ndarray]:
103103 self ._triggered -= 1
104104 _logger .info ("Creating image" )
105105
106- # Use stage position to compute bounding box.
107- width = self ._roi .width // self ._binning .h
108- height = self ._roi .height // self ._binning .v
109- x = int ((self ._stage .position ["x" ] / self ._pixel_size ) - (width / 2 ))
110- y = int ((self ._stage .position ["y" ] / self ._pixel_size ) - (height / 2 ))
111-
112106 # Use filter wheel position to select the image channel.
113107 channel = self ._filterwheel .position
114108
115- subsection = self ._image [y : y + height , x : x + width , channel ]
109+ width = self ._roi .width // self ._binning .h
110+ height = self ._roi .height // self ._binning .v
111+
112+ # Use stage position to compute bounding box.
113+ xstart = int (
114+ (self ._stage .position ["x" ] / self ._pixel_size ) - (width / 2 )
115+ )
116+ ystart = int (
117+ (self ._stage .position ["y" ] / self ._pixel_size ) - (height / 2 )
118+ )
119+ xend = xstart + width
120+ yend = ystart + height
121+
122+ # Need to check that the bounding box in entirely within the
123+ # source image (see #231).
124+ if (
125+ xstart < 0
126+ or ystart < 0
127+ or xend > self ._image .shape [1 ]
128+ or yend > self ._image .shape [0 ]
129+ ):
130+ # If part of image is out of bounds, pad with zeros, ...
131+ subsection = np .zeros ((height , width ), dtype = self ._image .dtype )
132+ # work out the relevant parts of input image ...
133+ img_x0 = max (0 , xstart )
134+ img_x1 = min (xend , self ._image .shape [1 ])
135+ img_y0 = max (0 , ystart )
136+ img_y1 = min (yend , self ._image .shape [0 ])
137+ # and work out where to place it in output image.
138+ sub_x0 = max (- xstart , 0 )
139+ sub_y0 = max (- ystart , 0 )
140+ sub_x1 = sub_x0 + (img_x1 - img_x0 )
141+ sub_y1 = sub_y0 + (img_y1 - img_y0 )
142+
143+ subsection [sub_y0 :sub_y1 , sub_x0 :sub_x1 ] = self ._image [
144+ img_y0 :img_y1 , img_x0 :img_x1 , channel
145+ ]
146+ else :
147+ subsection = self ._image [ystart :yend , xstart :xend , channel ]
116148
117149 # Gaussian filter on abs Z position to simulate being out of
118150 # focus (Z position zero is in focus).
0 commit comments