def main(): """main""" syris.init(double_precision=True) n = 512 ps = 0.5 * q.um energy = 10 * q.keV lam = energy_to_wavelength(energy) # Compute the sampling limit for given n, ps and lam ca = (lam / 2 / ps).simplified.magnitude tga = np.tan(np.arccos(ca)) distance = (tga * n * ps / 2).simplified print 'Propagation distance:', distance propagator = compute_propagator(n, distance, lam, ps, apply_phase_factor=True, mollified=False).get() full_propagator = compute_propagator(n, distance, lam, ps, fresnel=False, mollified=False).get() np_propagator = compute_fourier_propagator(n, lam, distance, ps) np_full_propagator = compute_fourier_propagator(n, lam, distance, ps, fresnel=False) diff = propagator - np_propagator full_diff = full_propagator - np_full_propagator show(np.fft.fftshift(propagator.real), 'Syris Fresnel Propagator (Real Part)') show(np.fft.fftshift(np_propagator.real), 'Numpy Fresnel propagator (Real Part)') show(np.fft.fftshift(diff.real), 'Fresnel Syris - Fresnel Numpy (Real Part)') show(np.fft.fftshift(full_propagator.real), 'Syris Full Propagator (Real Part)') show(np.fft.fftshift(np_full_propagator.real), 'Numpy Full propagator (Real Part)') show(np.fft.fftshift(full_diff.real), 'Full Syris - Full Numpy (Real Part)') plt.show()
def _get_propagator(self, apply_phase_factor=False, fresnel=True): return physics.compute_propagator( self.size, self.distance, self.lam, self.pixel_size, fresnel=fresnel, apply_phase_factor=apply_phase_factor, mollified=False).get()
def propagate_numerically(n, w, ps, d, lam): """Propagate square aperture numerically.""" LOG.info('Numerical propagation with n: {}, ps: {}'.format(n, ps)) u_0 = np.zeros((n, n), dtype=cfg.PRECISION.np_cplx) wp = int(np.round(w / ps).simplified.magnitude) region = slice(n / 2 - wp, n / 2 + wp, 1) u_0[region, region] = 1 + 0j fp = compute_propagator(n, d, lam, ps, mollified=False) u_0 = fft_2(u_0) u_0 *= fp ifft_2(u_0) res = abs(u_0) ** 2 return crop_to_aperture(res, w, ps)
def get_propagator_psf(n, d, ps, energy): lam = energy_to_wavelength(energy) propagator = compute_propagator(n, d, lam, ps).get() return np.fft.fftshift(np.fft.ifft2(propagator))
def compute_intensity(self, t_0, t_1, shape, pixel_size, queue=None, block=False, flat=False): """Compute intensity between times *t_0* and *t_1*.""" exp_time = (t_1 - t_0).simplified.magnitude if queue is None: queue = cfg.OPENCL.queue u = cl_array.Array(queue, shape, dtype=cfg.PRECISION.np_cplx) u_sample = cl_array.zeros(queue, shape, cfg.PRECISION.np_cplx) intensity = cl_array.zeros(queue, shape, cfg.PRECISION.np_float) for energy in self.energies: u.fill(1) for oeid, oe in enumerate(self.oe): if flat and oe == self.sample: continue u *= oe.transfer(shape, pixel_size, energy, t=t_0, queue=queue, out=u_sample, check=False, block=block) # Propagate and blur optical element when not source if self.distances[oeid] != 0 * q.m and oe != self.source: lam = energy_to_wavelength(energy) propagator = compute_propagator(u.shape[0], self.distances[oeid], lam, pixel_size, queue=queue, block=block, mollified=True) ip.fft_2(u, queue=queue, block=block) sdistance = np.sum(self.distances[:oeid + 1]) fwhm = (self.distances[oeid] * self.source.size / sdistance).simplified sigma = smath.fwnm_to_sigma(fwhm, n=2) psf = ip.get_gauss_2d(shape, sigma, pixel_size=pixel_size, fourier=True, queue=queue, block=block) u *= psf u *= propagator ip.ifft_2(u, queue=queue, block=block) intensity += self.detector.convert(abs(u)**2, energy) return intensity * exp_time
def _get_propagator(self, apply_phase_factor=False, fresnel=True): return physics.compute_propagator(self.size, self.distance, self.lam, self.pixel_size, fresnel=fresnel, apply_phase_factor=apply_phase_factor, mollified=False).get()