LSST Applications g0f08755f38+c89d42e150,g1635faa6d4+b6cf076a36,g1653933729+a8ce1bb630,g1a0ca8cf93+4c08b13bf7,g28da252d5a+f33f8200ef,g29321ee8c0+0187be18b1,g2bbee38e9b+9634bc57db,g2bc492864f+9634bc57db,g2cdde0e794+c2c89b37c4,g3156d2b45e+41e33cbcdc,g347aa1857d+9634bc57db,g35bb328faa+a8ce1bb630,g3a166c0a6a+9634bc57db,g3e281a1b8c+9f2c4e2fc3,g414038480c+077ccc18e7,g41af890bb2+e740673f1a,g5fbc88fb19+17cd334064,g7642f7d749+c89d42e150,g781aacb6e4+a8ce1bb630,g80478fca09+f8b2ab54e1,g82479be7b0+e2bd23ab8b,g858d7b2824+c89d42e150,g9125e01d80+a8ce1bb630,g9726552aa6+10f999ec6a,ga5288a1d22+065360aec4,gacf8899fa4+9553554aa7,gae0086650b+a8ce1bb630,gb58c049af0+d64f4d3760,gbd46683f8f+ac57cbb13d,gc28159a63d+9634bc57db,gcf0d15dbbd+e37acf7834,gda3e153d99+c89d42e150,gda6a2b7d83+e37acf7834,gdaeeff99f8+1711a396fd,ge2409df99d+cb1e6652d6,ge79ae78c31+9634bc57db,gf0baf85859+147a0692ba,gf3967379c6+02b11634a5,w.2024.45
LSST Data Management Base Package
Loading...
Searching...
No Matches
Public Member Functions | Static Public Member Functions | Public Attributes | Protected Attributes | List of all members
lsst.scarlet.lite.fft.Fourier Class Reference

Public Member Functions

 __init__ (self, np.ndarray image, dict[Sequence[Sequence[int]], np.ndarray]|None image_fft=None)
 
np.ndarray image (self)
 
tuple[int,...] shape (self)
 
np.ndarray fft (self, Sequence[int] fft_shape, int|Sequence[int] axes)
 
int __len__ (self)
 
Fourier __getitem__ (self, int|Sequence[int]|slice index)
 

Static Public Member Functions

Fourier from_fft (np.ndarray image_fft, Sequence[int] fft_shape, Sequence[int] image_shape, int|Sequence[int]|None axes=None, DTypeLike dtype=float)
 

Public Attributes

 image
 

Protected Attributes

 _fft
 
 _image
 

Detailed Description

An array that stores its Fourier Transform

The `Fourier` class is used for images that will make
use of their Fourier Transform multiple times.
In order to prevent numerical artifacts the same image
convolved with different images might require different
padding, so the FFT for each different shape is stored
in a dictionary.

Parameters
----------
image: np.ndarray
    The real space image.
image_fft: dict[Sequence[int], np.ndarray]
    A dictionary of {shape: fft_value} for which each different
    shape has a precalculated FFT.

Definition at line 220 of file fft.py.

Constructor & Destructor Documentation

◆ __init__()

lsst.scarlet.lite.fft.Fourier.__init__ ( self,
np.ndarray image,
dict[Sequence[Sequence[int]], np.ndarray] | None image_fft = None )

Definition at line 239 of file fft.py.

243 ):
244 if image_fft is None:
245 self._fft: dict[Sequence[Sequence[int]], np.ndarray] = {}
246 else:
247 self._fft = image_fft
248 self._image = image
249

Member Function Documentation

◆ __getitem__()

Fourier lsst.scarlet.lite.fft.Fourier.__getitem__ ( self,
int | Sequence[int] | slice index )

Definition at line 347 of file fft.py.

347 def __getitem__(self, index: int | Sequence[int] | slice) -> Fourier:
348 # Make the index a tuple
349 if isinstance(index, int):
350 index = tuple([index])
351
352 # Axes that are removed from the shape of the new object
353 if isinstance(index, slice):
354 removed = np.array([])
355 else:
356 removed = np.array([n for n, idx in enumerate(index) if idx is not None])
357
358 # Create views into the fft transformed values, appropriately adjusting
359 # the shapes for the new axes
360
361 fft_kernels = {
362 (
363 tuple([s for idx, s in enumerate(key[0]) if key[0][idx] not in removed]),
364 tuple([s for idx, s in enumerate(key[1]) if key[1][idx] not in removed]),
365 tuple([s for idx, s in enumerate(key[2]) if key[2][idx] not in removed]),
366 ): kernel[index]
367 for key, kernel in self._fft.items()
368 }
369 # mpypy doesn't recognize that tuple[int, ...]
370 # is a valid Sequence[int] for some reason
371 return Fourier(self.image[index], fft_kernels) # type: ignore
372
373
std::vector< SchemaItem< Flag > > * items

◆ __len__()

int lsst.scarlet.lite.fft.Fourier.__len__ ( self)
Length of the image

Definition at line 343 of file fft.py.

343 def __len__(self) -> int:
344 """Length of the image"""
345 return len(self.image)
346

◆ fft()

np.ndarray lsst.scarlet.lite.fft.Fourier.fft ( self,
Sequence[int] fft_shape,
int | Sequence[int] axes )
The FFT of an image for a given `fft_shape` along desired `axes`

Parameters
----------
fft_shape:
    "Fast" shape of the image used to generate the FFT.
    This will be different than `image_fft.shape` if
    any of the dimensions are odd, since `np.fft.rfft`
    requires an even number of dimensions (for symmetry),
    so this tells `np.fft.irfft` how to go from
    complex k-space to real space.
axes:
    The dimension(s) of the array that will be transformed.

Definition at line 313 of file fft.py.

313 def fft(self, fft_shape: Sequence[int], axes: int | Sequence[int]) -> np.ndarray:
314 """The FFT of an image for a given `fft_shape` along desired `axes`
315
316 Parameters
317 ----------
318 fft_shape:
319 "Fast" shape of the image used to generate the FFT.
320 This will be different than `image_fft.shape` if
321 any of the dimensions are odd, since `np.fft.rfft`
322 requires an even number of dimensions (for symmetry),
323 so this tells `np.fft.irfft` how to go from
324 complex k-space to real space.
325 axes:
326 The dimension(s) of the array that will be transformed.
327 """
328 if isinstance(axes, int):
329 axes = (axes,)
330 all_axes = range(len(self.image.shape))
331 fft_key = (tuple(fft_shape), tuple(axes), tuple(all_axes))
332
333 # If this is the first time calling `fft` for this shape,
334 # generate the FFT.
335 if fft_key not in self._fft:
336 if len(fft_shape) != len(axes):
337 msg = f"fft_shape self.axes must have the same number of dimensions, got {fft_shape}, {axes}"
338 raise ValueError(msg)
339 image = _pad(self.image, fft_shape, axes)
340 self._fft[fft_key] = np.fft.rfftn(np.fft.ifftshift(image, axes), axes=axes)
341 return self._fft[fft_key]
342

◆ from_fft()

Fourier lsst.scarlet.lite.fft.Fourier.from_fft ( np.ndarray image_fft,
Sequence[int] fft_shape,
Sequence[int] image_shape,
int | Sequence[int] | None axes = None,
DTypeLike dtype = float )
static
Generate a new Fourier object from an FFT dictionary

If the fft of an image has been generated but not its
real space image (for example when creating a convolution kernel),
this method can be called to create a new `Fourier` instance
from the k-space representation.

Parameters
----------
image_fft:
    The FFT of the image.
fft_shape:
    "Fast" shape of the image used to generate the FFT.
    This will be different than `image_fft.shape` if
    any of the dimensions are odd, since `np.fft.rfft`
    requires an even number of dimensions (for symmetry),
    so this tells `np.fft.irfft` how to go from
    complex k-space to real space.
image_shape:
    The shape of the image *before padding*.
    This will regenerate the image with the extra
    padding stripped.
axes:
    The dimension(s) of the array that will be transformed.

Returns
-------
result:
    A `Fourier` object generated from the FFT.

Definition at line 251 of file fft.py.

257 ) -> Fourier:
258 """Generate a new Fourier object from an FFT dictionary
259
260 If the fft of an image has been generated but not its
261 real space image (for example when creating a convolution kernel),
262 this method can be called to create a new `Fourier` instance
263 from the k-space representation.
264
265 Parameters
266 ----------
267 image_fft:
268 The FFT of the image.
269 fft_shape:
270 "Fast" shape of the image used to generate the FFT.
271 This will be different than `image_fft.shape` if
272 any of the dimensions are odd, since `np.fft.rfft`
273 requires an even number of dimensions (for symmetry),
274 so this tells `np.fft.irfft` how to go from
275 complex k-space to real space.
276 image_shape:
277 The shape of the image *before padding*.
278 This will regenerate the image with the extra
279 padding stripped.
280 axes:
281 The dimension(s) of the array that will be transformed.
282
283 Returns
284 -------
285 result:
286 A `Fourier` object generated from the FFT.
287 """
288 if axes is None:
289 axes = range(len(image_shape))
290 if isinstance(axes, int):
291 axes = [axes]
292 all_axes = range(len(image_shape))
293 image = np.fft.irfftn(image_fft, fft_shape, axes=axes).astype(dtype)
294 # Shift the center of the image from the bottom left to the center
295 image = np.fft.fftshift(image, axes=axes)
296 # Trim the image to remove the padding added
297 # to reduce fft artifacts
298 image = centered(image, image_shape)
299 key = (tuple(fft_shape), tuple(axes), tuple(all_axes))
300
301 return Fourier(image, {key: image_fft})
302

◆ image()

np.ndarray lsst.scarlet.lite.fft.Fourier.image ( self)
The real space image

Definition at line 304 of file fft.py.

304 def image(self) -> np.ndarray:
305 """The real space image"""
306 return self._image
307
afw::table::Key< afw::table::Array< ImagePixelT > > image

◆ shape()

tuple[int, ...] lsst.scarlet.lite.fft.Fourier.shape ( self)
The shape of the real space image

Definition at line 309 of file fft.py.

309 def shape(self) -> tuple[int, ...]:
310 """The shape of the real space image"""
311 return self._image.shape
312

Member Data Documentation

◆ _fft

lsst.scarlet.lite.fft.Fourier._fft
protected

Definition at line 247 of file fft.py.

◆ _image

lsst.scarlet.lite.fft.Fourier._image
protected

Definition at line 248 of file fft.py.

◆ image

lsst.scarlet.lite.fft.Fourier.image

Definition at line 345 of file fft.py.


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