Beispiel #1
0
 def __init__(self,
              array: np.ndarray,
              wavelength: float,
              pixel_size: Tuple[float, float, float] = None,
              photons_flux: float = None):
     super().__init__(wavelength, array.shape, pixel_size, photons_flux)
     self.wavefront = Wavefront(array, wavelength=wavelength)
Beispiel #2
0
    def _calculateWavefront(self) -> None:
        """Calculate a wavefront with gaussian intensity, then modulate the wavefront using a speckle pattern."""
        sigma_x = self.width_dist[1]
        sigma_y = self.width_dist[0]

        nx = self.shape[-1]
        ny = self.shape[-2]
        x = np.arange(-nx // 2, nx // 2) * self.pixel_size[1]
        y = np.arange(-ny // 2, ny // 2) * self.pixel_size[0]
        xx, yy = np.meshgrid(x, y)
        intensity = utils.generalized2dGaussian(np.stack(
            (xx.flatten(), yy.flatten()), axis=1),
                                                amplitude=1,
                                                center_x=self.center_dist[0],
                                                center_y=self.center_dist[1],
                                                sigma_x=sigma_x,
                                                sigma_y=sigma_y,
                                                theta=self.theta,
                                                offset=0)
        amplitude = np.sqrt(intensity).astype('complex64').reshape(ny, nx)

        speckle = utils.getSpeckle((ny, nx), self.speckle_window_npix)
        wavefront_array = np.fft.fftshift(amplitude * speckle)
        scaling_factor = np.sqrt(self.n_photons /
                                 np.sum(np.abs(wavefront_array)**2))
        #self.wavefront = self.wavefront.update(array=scaling_factor * wavefront_array)
        self.wavefront = Wavefront(scaling_factor * wavefront_array,
                                   wavelength=self.wavelength,
                                   pixel_size=self.pixel_size)
        self._propagateWavefront()
Beispiel #3
0
    def _calculateWavefront(self) -> None:
        """Calculate the probe wavefront with constant phase and with a gaussian intensity. Propagate the wavefront."""
        sigma_x = self.width_dist[1]
        sigma_y = self.width_dist[0]

        nx = self.shape[-1]
        ny = self.shape[-2]
        x = np.arange(-nx // 2, nx // 2) * self.pixel_size[1]
        y = np.arange(-ny // 2, ny // 2) * self.pixel_size[0]
        xx, yy = np.meshgrid(x, y)
        xdata = np.stack((xx.flatten(), yy.flatten()), axis=1)
        intensity = utils.generalized2dGaussian(xdata,
                                                amplitude=1,
                                                center_x=self.center_dist[1],
                                                center_y=self.center_dist[0],
                                                sigma_x=sigma_x,
                                                sigma_y=sigma_y,
                                                theta=self.theta,
                                                offset=0).reshape((ny, nx))

        scaling_factor = np.sqrt(self.n_photons / intensity.sum())
        wavefront_array = scaling_factor * np.sqrt(intensity).astype(
            'complex64')
        wavefront_array = np.fft.fftshift(np.reshape(wavefront_array,
                                                     (ny, nx)))
        #self.wavefront = self.wavefront.update(array=wavefront_array)
        self.wavefront = Wavefront(wavefront_array,
                                   wavelength=self.wavelength,
                                   pixel_size=self.pixel_size)
        self._propagateWavefront()
Beispiel #4
0
    def _calculateWavefront(self) -> None:
        """Calculating the airy pattern then propagating it by `defocus_dist`."""
        if self.width_dist[0] > 0:
            logger.warning(
                "Warning: if width at the focus is supplied, " +
                "any supplied focal_length and aperture radius are ignored.")
            self.aperture_radius = None
            self.focal_length = None
            # Assuming resolution equal to pixel pitch and focal length of 10.0 m.
            focal_length = 10.0
            focus_radius = self.width_dist[0] / 2
            # note that jinc(1,1) = 1.22 * np.pi
            aperture_radius = (self.wavelength * 1.22 * np.pi * focal_length /
                               2 / np.pi / focus_radius)
        else:
            if None in [self.aperture_radius, self.focal_length]:
                e = ValueError(
                    'Either focus_radius_npix or BOTH aperture_radius and focal_length must be supplied.'
                )
                logger.error(e)
                raise e
            aperture_radius = self.aperture_radius
            focal_length = self.focal_length

        npix_oversampled = max(
            self.oversampling_npix,
            self.shape[-1]) if self.oversampling else self.shape[0]
        pixel_pitch_aperture = self.wavelength * focal_length / (
            npix_oversampled * self.pixel_size[0])

        x = np.arange(-npix_oversampled // 2,
                      npix_oversampled // 2) * pixel_pitch_aperture

        r = np.sqrt(x**2 + x[:, np.newaxis]**2).astype('float32')
        circ_wavefront = np.zeros(r.shape)
        circ_wavefront[r < aperture_radius] = 1.0
        circ_wavefront[r == aperture_radius] = 0.5

        probe_vals = np.fft.fftshift(
            np.fft.fft2(np.fft.fftshift(circ_wavefront), norm='ortho'))

        n1 = npix_oversampled // 2 - self.shape[0] // 2
        n2 = npix_oversampled // 2 + self.shape[1] // 2

        scaling_factor = np.sqrt(self.n_photons /
                                 np.sum(np.abs(probe_vals)**2))
        wavefront_array = probe_vals[n1:n2, n1:n2].astype(
            'complex64') * scaling_factor
        wavefront_array = np.fft.fftshift(wavefront_array)
        #self.wavefront = self.wavefront.update(array=wavefront_array)
        self.wavefront = Wavefront(wavefront_array,
                                   wavelength=self.wavelength,
                                   pixel_size=self.pixel_size)
        self._propagateWavefront()
Beispiel #5
0
 def __init__(self,
              wavefront_array: np.ndarray,
              wavelength: float,
              pixel_size: Tuple[float, float],
              defocus_dist: float = 0) -> None:
     super().__init__(wavelength=wavelength,
                      pixel_size=pixel_size,
                      shape=wavefront_array.shape,
                      n_photons=np.sum(np.abs(wavefront_array)**2),
                      defocus_dist=defocus_dist)
     #self.wavefront = self.wavefront.update(array = wavefront_array.copy())
     self.wavefront = Wavefront(wavefront_array,
                                wavelength=self.wavefront.wavelength,
                                pixel_size=self.wavefront.pixel_size)
     self._calculateWavefront()
Beispiel #6
0
    def __init__(self,
                 wavelength: float,
                 pixel_size: Tuple[float, ...],
                 shape: Tuple[int, ...],
                 n_photons: float,
                 defocus_dist: float = 0,
                 center_dist: Tuple[float, float] = (0, 0),
                 width_dist: Tuple[float, float] = (0, 0),
                 center_npix: Tuple[int, int] = None,
                 width_npix: Tuple[int, int] = None,
                 check_propagation_with_gaussian_fit: bool = False,
                 apodize: bool = False) -> None:
        self.wavelength = wavelength
        self.shape = shape
        self.pixel_size = pixel_size
        self.n_photons = n_photons
        self.defocus_dist = defocus_dist
        self.center_dist = center_dist
        self.width_dist = width_dist
        self.apodize = apodize

        if center_npix is not None:
            logger.warning(
                'If center_npix is supplied, then any supplied center_dist is ignored.'
            )
            self.center_npix = center_npix
            self.center_dist = np.array(center_npix) * np.array(
                self.pixel_size)
        if width_npix is not None:
            logger.warning(
                'If width_npix is supplied, then any supplied width_dist is ignored.'
            )
            self.width_npix = width_npix
            self.width_dist = np.array(width_npix) * np.array(self.pixel_size)

        #wavefront_array = np.zeros((npix, npix), dtype='complex64')

        #self.wavefront = propagators.Wavefront(wavefront_array,
        self.wavefront = Wavefront(np.zeros(shape),
                                   wavelength=wavelength,
                                   pixel_size=pixel_size)

        self.photons_flux = n_photons / (shape[-1] * shape[-2])
        self.check_propagation_with_gaussian_fit = check_propagation_with_gaussian_fit
Beispiel #7
0
    def _calculateWavefront(self) -> None:
        """Calculates and propagates the exit wave from a rectangular aperture of the supplied dimensions."""
        nx = self.shape[-1]
        ny = self.shape[-2]

        x = np.arange(-nx // 2, nx // 2) * self.pixel_size[1]
        y = np.arange(-ny // 2, ny // 2)[:, np.newaxis] * self.pixel_size[0]
        xarr = np.where(
            np.abs(x - self.center_dist[1]) <= self.width_dist[1] / 2, 1, 0)
        yarr = np.where(
            np.abs(y - self.center_dist[0]) <= self.width_dist[0] / 2, 1, 0)
        array = np.fft.fftshift((xarr * yarr).astype('complex64'))

        scaling_factor = np.sqrt(self.n_photons / (np.abs(array)**2).sum())
        #self.wavefront = self.wavefront.update(array = scaling_factor * array)
        self.wavefront = Wavefront(scaling_factor * array,
                                   wavelength=self.wavelength,
                                   pixel_size=self.pixel_size)
        self._propagateWavefront()
Beispiel #8
0
    def _calculateWavefront(self):
        """Calculates and propagates the exit wave from a circular aperture of the supplied radius.
        """
        a = self.width_dist[1] / 2
        b = self.width_dist[0] / 2
        nx = self.shape[1]
        ny = self.shape[0]
        x = np.arange(-nx // 2, nx // 2) * self.pixel_size[1]
        y = np.arange(-ny // 2, ny // 2)[:, np.newaxis] * self.pixel_size[0]

        lhs = b**2 * (x - self.center_dist[1])**2 + a**2 * (
            y - self.center_dist[0])**2
        rhs = a**2 * b**2

        wavefront_array = np.zeros(lhs.shape, dtype='complex64')
        wavefront_array[lhs <= rhs] = 1.0
        wavefront_array = np.fft.fftshift(wavefront_array)
        scaling_factor = np.sqrt(self.n_photons /
                                 (np.abs(wavefront_array)**2).sum())
        #self.wavefront = self.wavefront.update(array=scaling_factor * wavefront_array)
        self.wavefront = Wavefront(scaling_factor * wavefront_array,
                                   wavelength=self.wavelength,
                                   pixel_size=self.pixel_size)
        self._propagateWavefront()