def test_spherical_wave(self, do_plot=do_plot): # # plane wave # print("# ") print("# Tests for a 1D spherical wave ") print("# ") wavelength = 1.24e-10 wavefront_length_x = 400e-6 npixels_x = 1024 wavefront_x = numpy.linspace(-0.5 * wavefront_length_x, 0.5 * wavefront_length_x, npixels_x) wf1 = GenericWavefront1D.initialize_wavefront_from_steps( x_start=wavefront_x[0], x_step=numpy.abs(wavefront_x[1] - wavefront_x[0]), number_of_points=npixels_x, wavelength=wavelength) wf2 = GenericWavefront1D.initialize_wavefront_from_steps( x_start=wavefront_x[0], x_step=numpy.abs(wavefront_x[1] - wavefront_x[0]), number_of_points=npixels_x, wavelength=wavelength) # an spherical wavefront is obtained 1) by creation, 2) focusing a planewave wf1.set_spherical_wave(radius=-5.0, complex_amplitude=3 + 0j) wf1.clip(-50e-6, 10e-6) wf2.set_plane_wave_from_complex_amplitude(3 + 0j) ideal_lens = WOIdealLens1D("test", 5.0) ideal_lens.applyOpticalElement(wf2) wf2.clip(-50e-6, 10e-6) if do_plot: from srxraylib.plot.gol import plot plot(wf1.get_abscissas(), wf1.get_phase(), title="Phase of spherical wavefront", show=0) plot(wf2.get_abscissas(), wf2.get_phase(), title="Phase of focused plane wavefront", show=0) plot(wf1.get_abscissas(), wf1.get_phase(from_minimum_intensity=0.1), title="Phase of spherical wavefront (for intensity > 0.1)", show=0) plot( wf2.get_abscissas(), wf2.get_phase(from_minimum_intensity=0.1), title="Phase of focused plane wavefront (for intensity > 0.1)", show=1) numpy.testing.assert_almost_equal(wf1.get_phase(), wf2.get_phase(), 5)
def test_save_load_h5_file(self): wfr = GenericWavefront1D.initialize_wavefront_from_range( -2.0, 2.0, number_of_points=100) wfr.set_gaussian(.2, amplitude=5 + 8j) print("Saving 1D wavefront to file: tmp.h5") wfr.save_h5_file("tmp.h5", "wfr1", intensity=True, phase=True) print("Reading 1D wavefront from file: tmp.h5") wfr2 = GenericWavefront1D.load_h5_file("tmp.h5", "wfr1") print("Cleaning file tmp.h5") os.remove("tmp.h5") assert (wfr2.is_identical(wfr))
def get_Wavefront1D_from_profile(self, axis, coordinate): # swap axis - changed giovanni+manuel if axis == 1: # fixed X index = numpy.argmin(numpy.abs(self._electric_field_matrix.x_coord - coordinate)) return GenericWavefront1D(wavelength=self._wavelength, electric_field_array=ScaledArray(scale=self._electric_field_matrix.y_coord, np_array=self._electric_field_matrix.z_values[index, :])) elif axis == 0: index = numpy.argmin(numpy.abs(self._electric_field_matrix.y_coord - coordinate)) return GenericWavefront1D(wavelength=self._wavelength, electric_field_array=ScaledArray(scale=self._electric_field_matrix.x_coord, np_array=self._electric_field_matrix.z_values[:, index]))
def propagator1D_offaxis(input_wavefront, x2_oe, y2_oe, p, q, theta_grazing_in, theta_grazing_out=None, zoom_factor=1.0, normalize_intensities=False): from wofry.propagator.wavefront1D.generic_wavefront import GenericWavefront1D if theta_grazing_out is None: theta_grazing_out = theta_grazing_in x1 = input_wavefront.get_abscissas() field1 = input_wavefront.get_complex_amplitude() wavelength = input_wavefront.get_wavelength() x1_oe = -p * numpy.cos(theta_grazing_in) + x1 * numpy.sin(theta_grazing_in) y1_oe = p * numpy.sin(theta_grazing_in) + x1 * numpy.cos(theta_grazing_in) # field2 is the electric field in the mirror field2 = goFromToSequential(field1, x1_oe, y1_oe, x2_oe, y2_oe, wavelength=wavelength, normalize_intensities=normalize_intensities) x3 = x1 * zoom_factor x3_oe = q * numpy.cos(theta_grazing_out) + x3 * numpy.sin(theta_grazing_out) y3_oe = q * numpy.sin(theta_grazing_out) + x3 * numpy.cos(theta_grazing_out) # field2 is the electric field in the image plane field3 = goFromToSequential(field2, x2_oe, y2_oe, x3_oe, y3_oe, wavelength=wavelength, normalize_intensities=normalize_intensities) output_wavefront = GenericWavefront1D.initialize_wavefront_from_arrays(x3, field3 / numpy.sqrt(zoom_factor), wavelength=wavelength) return output_wavefront
def propagate_wavefront(cls, wavefront, propagation_distance, shift_half_pixel=False): shape = wavefront.size() delta = wavefront.delta() wavelength = wavefront.get_wavelength() wavenumber = wavefront.get_wavenumber() fft_scale = numpy.fft.fftfreq(shape, d=delta) fft_scale = numpy.fft.fftshift(fft_scale) x2 = fft_scale * propagation_distance * wavelength if shift_half_pixel: x2 = x2 - 0.5 * numpy.abs(x2[1] - x2[0]) p1 = numpy.exp(1.0j * wavenumber * propagation_distance) p2 = numpy.exp(1.0j * wavenumber / 2 / propagation_distance * x2**2) p3 = 1.0j * wavelength * propagation_distance fft = numpy.fft.fft(wavefront.get_complex_amplitude()) fft = fft * p1 * p2 / p3 fft2 = numpy.fft.fftshift(fft) wavefront_out = GenericWavefront1D.initialize_wavefront_from_arrays( x2, fft2, wavelength=wavefront.get_wavelength()) # added [email protected] 2018-03-23 to conserve energy - TODO: review method! wavefront_out.rescale_amplitude( numpy.sqrt(wavefront.get_intensity().sum() / wavefront_out.get_intensity().sum())) return wavefront_out
def get_eigenvector_wavefront(self, mode): complex_amplitude = self.get_eigenvectors()[mode, :] * np.sqrt( self.get_eigenvalue(mode)) wf = GenericWavefront1D.initialize_wavefront_from_arrays( self.abscissas, complex_amplitude) wf.set_photon_energy(self.photon_energy) return wf
def _calculate_far_field(self): # # undulator emission # out = self.calculate_undulator_emission( electron_energy=self.electron_energy, electron_current=self.electron_current, undulator_period=self.undulator_period, undulator_nperiods=self.undulator_nperiods, K=self.K, photon_energy=self.photon_energy, abscissas_interval_in_far_field=self. _abscissas_interval_in_far_field, number_of_points=self.number_of_points, distance_to_screen=self.distance_to_screen, scan_direction=self.scan_direction, ) # # # from wofry.propagator.wavefront1D.generic_wavefront import GenericWavefront1D input_wavefront = GenericWavefront1D.initialize_wavefront_from_arrays( out["abscissas"], out["electric_field"][:, 0]) input_wavefront.set_photon_energy(photon_energy=self.photon_energy) self.far_field_wavefront = input_wavefront
def calculate_wavefront1D(wavelength=1e-10, undulator_length=1.0, undulator_distance=10.0, x_min=-0.1, x_max=0.1, number_of_points=101, wavefront_position=0, add_random_phase=0): from wofry.propagator.wavefront1D.generic_wavefront import GenericWavefront1D sigma_r = 2.740 / 4 / numpy.pi * numpy.sqrt(wavelength * undulator_length) sigma_r_prime = 0.69 * numpy.sqrt(wavelength / undulator_length) wavefront1D = GenericWavefront1D.initialize_wavefront_from_range(x_min=x_min, x_max=x_max, number_of_points=number_of_points) wavefront1D.set_wavelength(wavelength) if wavefront_position == 0: # Gaussian source wavefront1D.set_gaussian(sigma_x=sigma_r, amplitude=1.0, shift=0.0) elif wavefront_position == 1: # Spherical source, Gaussian intensity wavefront1D.set_spherical_wave(radius=undulator_distance, center=0.0, complex_amplitude=complex(1, 0)) # weight with Gaussian X = wavefront1D.get_abscissas() A = wavefront1D.get_complex_amplitude() sigma = undulator_distance * sigma_r_prime sigma_amplitude = sigma * numpy.sqrt(2) Gx = numpy.exp(-X * X / 2 / sigma_amplitude ** 2) wavefront1D.set_complex_amplitude(A * Gx) if add_random_phase: wavefront1D.add_phase_shifts(2 * numpy.pi * numpy.random.random(wavefront1D.size())) return wavefront1D
def propagate_wavefront(cls, wavefront1, propagation_distance, magnification_x=1.0): wavefront = wavefront1.duplicate() shape = wavefront.size() delta = wavefront.delta() wavenumber = wavefront.get_wavenumber() wavelength = wavefront.get_wavelength() fft_scale = numpy.fft.fftfreq(shape) / delta x = wavefront.get_abscissas() x_rescaling = wavefront.get_abscissas() * magnification_x r1sq = x**2 * (1 - magnification_x) r2sq = x_rescaling**2 * ((magnification_x - 1) / magnification_x) fsq = (fft_scale**2 / magnification_x) Q1 = wavenumber / 2 / propagation_distance * r1sq Q2 = numpy.exp(-1.0j * numpy.pi * wavelength * propagation_distance * fsq) Q3 = numpy.exp(1.0j * wavenumber / 2 / propagation_distance * r2sq) wavefront.add_phase_shift(Q1) fft = numpy.fft.fft(wavefront.get_complex_amplitude()) ifft = numpy.fft.ifft(fft * Q2) * Q3 / numpy.sqrt(magnification_x) wf_propagated = GenericWavefront1D.initialize_wavefront_from_arrays( x_rescaling, ifft, wavelength=wavelength) return wf_propagated
def run_beamline_2(error_flag=0,error_file=""): # # main # create input_wavefront # # from wofry.propagator.wavefront1D.generic_wavefront import GenericWavefront1D input_wavefront = GenericWavefront1D.initialize_wavefront_from_range(x_min=-0.0002, x_max=0.0002, number_of_points=5000) input_wavefront.set_photon_energy(250) input_wavefront.set_gaussian(sigma_x=0.000012, amplitude=1.000000, shift=0.000000) output_wavefront, abscissas_on_mirror, height = calculate_output_wavefront_after_grazing_reflector1D( input_wavefront, shape=2, p_focus=15.0, q_focus=15.0, grazing_angle_in=0.02181661, p_distance=15.0, q_distance=15.0, zoom_factor=10, #0.3, error_flag=error_flag, error_file=error_file, write_profile=0) # from srxraylib.plot.gol import plot # plot(output_wavefront.get_abscissas(), output_wavefront.get_intensity()) return output_wavefront
def propagate_wavefront(cls, wavefront, propagation_distance, magnification_x=1.0, magnification_N=1.0): method = 0 wavenumber = numpy.pi * 2 / wavefront.get_wavelength() x = wavefront.get_abscissas() if magnification_N != 1.0: npoints_exit = int(magnification_N * x.size) else: npoints_exit = x.size detector_abscissas = numpy.linspace(magnification_x * x[0], magnification_x * x[-1], npoints_exit) if method == 0: # calculate via loop pver detector coordinates x1 = wavefront.get_abscissas() x2 = detector_abscissas fieldComplexAmplitude = numpy.zeros_like(x2, dtype=complex) for ix, x in enumerate(x2): r = numpy.sqrt( numpy.power(x1 - x, 2) + numpy.power(propagation_distance, 2)) distances_array = numpy.exp(1.j * wavenumber * r) fieldComplexAmplitude[ix] = ( wavefront.get_complex_amplitude() * distances_array).sum() elif method == 1: # calculate via outer product, it spreads over a lot of memory, but it is OK for 1D x1 = numpy.outer(wavefront.get_abscissas(), numpy.ones(detector_abscissas.size)) x2 = numpy.outer(numpy.ones(wavefront.size()), detector_abscissas) r = numpy.sqrt( numpy.power(x1 - x2, 2) + numpy.power(propagation_distance, 2)) distances_matrix = numpy.exp(1.j * wavenumber * r) fieldComplexAmplitude = numpy.dot( wavefront.get_complex_amplitude(), distances_matrix) wavefront_out = GenericWavefront1D( wavefront.get_wavelength(), ScaledArray.initialize_from_steps( fieldComplexAmplitude, detector_abscissas[0], detector_abscissas[1] - detector_abscissas[0])) # added [email protected] 2018-03-23 to conserve energy - TODO: review method! # wavefront_out.rescale_amplitude( numpy.sqrt(wavefront.get_intensity().sum() / # wavefront_out.get_intensity().sum() # / magnification_x)) wavefront_out.rescale_amplitude( (1/numpy.sqrt(1j*wavefront.get_wavelength()*propagation_distance))*(x1[1]-x1[0]) * \ numpy.exp(1j * wavenumber * propagation_distance)) return wavefront_out
def run_beamline(error_flag=1,error_file="/Users/srio/Oasys/dabam_profile_6010353992.dat"): # wf0 = calculate_wavefront1D(wavelength=4.9593679373280105e-09, # wavefront_position=0, # undulator_length=2.24, # undulator_distance=13.73, # x_min=-0.00025, # x_max=0.00025, # number_of_points=1000, # add_random_phase=0) # # create input_wavefront # # from wofry.propagator.wavefront1D.generic_wavefront import GenericWavefront1D input_wavefront = GenericWavefront1D.initialize_wavefront_from_range(x_min=-0.0002, x_max=0.0002, number_of_points=1000) input_wavefront.set_photon_energy(250) input_wavefront.set_gaussian(sigma_x=0.000012, amplitude=1.000000, shift=0.000000) wf0 = input_wavefront # from srxraylib.plot.gol import plot # plot(input_wavefront.get_abscissas(), input_wavefront.get_intensity()) # # # wf1 = propagate_in_vacuum(wf0) # plot(1e6 * wf1.get_abscissas(), wf1.get_intensity()) # # # wf2, abscissas_on_mirror, height = calculate_output_wavefront_after_reflector1D(wf1, shape=1,radius=687.6038987249137,grazing_angle=0.02181661, error_flag=error_flag, error_file=error_file, error_edge_management=0,write_profile="") # plot(1e6 * wf2.get_abscissas(),wf2.get_intensity()) # # # wf3 = propagate_in_vacuum(wf2,magnification_x=0.03,propagator_flag='i') return wf3
def toGenericWavefront(self): wavelength = self.wise_computation_result.Lambda position = self.wise_computation_result.S electric_field = numpy.real( self.wise_computation_result.Field) + 1j * numpy.imag( self.wise_computation_result.Field) return GenericWavefront1D.initialize_wavefront_from_arrays( x_array=position, y_array=electric_field, wavelength=wavelength)
def __init__(self, wofry_wavefront=GenericWavefront1D()): self.wofry_wavefront = wofry_wavefront wavelength = wofry_wavefront.get_wavelength() waist0 = fwhm(wofry_wavefront.get_abscissas(), wofry_wavefront.get_intensity()) * numpy.sqrt(2) / 1.66 print("WAIST", waist0) super(DummyElement, self).__init__(Lambda=wavelength, Waist0=waist0)
def test_initializers(self, do_plot=do_plot): print("# ") print("# Tests for initializars (1D) ") print("# ") x = numpy.linspace(-100, 100, 50) y = numpy.abs(x)**1.5 + 1j * numpy.abs(x)**1.8 wf0 = GenericWavefront1D.initialize_wavefront_from_steps( x[0], numpy.abs(x[1] - x[0]), y.size) wf0.set_complex_amplitude(y) wf1 = GenericWavefront1D.initialize_wavefront_from_range( x[0], x[-1], y.size) wf1.set_complex_amplitude(y) wf2 = GenericWavefront1D.initialize_wavefront_from_arrays(x, y) print("wavefront sizes: ", wf1.size(), wf1.size(), wf2.size()) if do_plot: from srxraylib.plot.gol import plot plot(wf0.get_abscissas(), wf0.get_intensity(), title="initialize_wavefront_from_steps", show=0) plot(wf1.get_abscissas(), wf1.get_intensity(), title="initialize_wavefront_from_range", show=0) plot(wf2.get_abscissas(), wf2.get_intensity(), title="initialize_wavefront_from_arrays", show=1) numpy.testing.assert_almost_equal(wf0.get_intensity(), numpy.abs(y)**2, 5) numpy.testing.assert_almost_equal(wf1.get_intensity(), numpy.abs(y)**2, 5) numpy.testing.assert_almost_equal(x, wf1.get_abscissas(), 11) numpy.testing.assert_almost_equal(x, wf2.get_abscissas(), 11)
def propagate_wavefront(cls, wavefront, propagation_distance): fft_scale = numpy.fft.fftfreq(wavefront.size()) / wavefront.delta() fft = numpy.fft.fft(wavefront.get_complex_amplitude()) fft *= numpy.exp((-1.0j) * numpy.pi * wavefront.get_wavelength() * propagation_distance * fft_scale**2) ifft = numpy.fft.ifft(fft) return GenericWavefront1D( wavefront.get_wavelength(), ScaledArray.initialize_from_steps(ifft, wavefront.offset(), wavefront.delta()))
def _back_propagation_for_size_calculation(self,theta,radiation_flux,photon_energy, distance=100.0,magnification=0.010000): """ Calculate the radiation_flux vs theta at a "distance" Back propagate to -distance The result is the size distrubution :param theta: :param radiation_flux: :param photon_energy: :param distance: :param magnification: :return: None; stores results in self._photon_size_distribution """ from wofry.propagator.wavefront1D.generic_wavefront import GenericWavefront1D from wofry.propagator.propagator import PropagationManager, PropagationElements, PropagationParameters from syned.beamline.beamline_element import BeamlineElement from syned.beamline.element_coordinates import ElementCoordinates from wofry.propagator.propagators1D.fresnel_zoom import FresnelZoom1D from wofry.beamline.optical_elements.ideal_elements.screen import WOScreen1D input_wavefront = GenericWavefront1D().initialize_wavefront_from_arrays(theta*distance,numpy.sqrt(radiation_flux)+0j) input_wavefront.set_photon_energy(photon_energy) input_wavefront.set_spherical_wave(radius=distance,complex_amplitude=numpy.sqrt(radiation_flux)+0j) # input_wavefront.save_h5_file("tmp2.h5","wfr") optical_element = WOScreen1D() # # propagating # # propagation_elements = PropagationElements() beamline_element = BeamlineElement(optical_element=optical_element, coordinates=ElementCoordinates(p=0.0,q=-distance, angle_radial=numpy.radians(0.000000), angle_azimuthal=numpy.radians(0.000000))) propagation_elements.add_beamline_element(beamline_element) propagation_parameters = PropagationParameters(wavefront=input_wavefront.duplicate(),propagation_elements = propagation_elements) propagation_parameters.set_additional_parameters('magnification_x', magnification) # propagator = PropagationManager.Instance() try: propagator.add_propagator(FresnelZoom1D()) except: pass output_wavefront = propagator.do_propagation(propagation_parameters=propagation_parameters,handler_name='FRESNEL_ZOOM_1D') self._result_photon_size_distribution = {"x":output_wavefront.get_abscissas(),"y":output_wavefront.get_intensity()}
def __init__(self, wofry_wavefront=GenericWavefront1D(), ZOrigin = 0, YOrigin = 0, Theta = 0, units_converter=1e-2): self.wofry_wavefront=wofry_wavefront self.Lambda = self.wofry_wavefront._wavelength self.Name = 'Wofry Wavefront @ %0.2fnm' % (self.Lambda *1e9) self.ZOrigin = ZOrigin self.YOrigin = YOrigin self.ThetaPropagation = Theta parameters, covariance_matrix_pv = WofryWavefrontSource_1d.gaussian_fit(self.wofry_wavefront.get_intensity(), self.wofry_wavefront.get_abscissas()) self.Waist0 = parameters[3] self.units_converter = units_converter
def gaussian_wavefront(center, angle): # # create input_wavefront # # input_wavefront = GenericWavefront1D.initialize_wavefront_from_range( x_min=-0.0028, x_max=0.0028, number_of_points=8192) input_wavefront.set_photon_energy(17225) input_wavefront.set_spherical_wave(radius=28.3, center=center, complex_amplitude=complex(1, 0)) # # apply Gaussian amplitude # input_wavefront = apply_gaussian(input_wavefront, shift=28.3 * angle) return input_wavefront
def test_interpolator(self, do_plot=do_plot): # # interpolator # print("# ") print("# Tests for 1D interpolator ") print("# ") x = numpy.linspace(-10, 10, 100) sigma = 3.0 Z = numpy.exp(-1.0 * x**2 / 2 / sigma**2) print("shape of Z", Z.shape) wf = GenericWavefront1D.initialize_wavefront_from_steps( x[0], numpy.abs(x[1] - x[0]), number_of_points=100) print("wf shape: ", wf.size()) wf.set_complex_amplitude(Z) x1 = 3.2 z1 = numpy.exp(x1**2 / -2 / sigma**2) print("complex ampl at (%g): %g+%gi (exact=%g)" % (x1, wf.get_interpolated_complex_amplitude(x1).real, wf.get_interpolated_complex_amplitude(x1).imag, z1)) self.assertAlmostEqual( wf.get_interpolated_complex_amplitude(x1).real, z1, 4) print("intensity at (%g): %g (exact=%g)" % (x1, wf.get_interpolated_intensity(x1), z1**2)) self.assertAlmostEqual(wf.get_interpolated_intensity(x1), z1**2, 4) if do_plot: from srxraylib.plot.gol import plot plot(wf.get_abscissas(), wf.get_intensity(), title="Original", show=1) xx = wf.get_abscissas() yy = wf.get_interpolated_intensities(wf.get_abscissas() - 1e-5) plot(xx, yy, title="interpolated on same grid", show=1)
def test_polarization(self): print("# ") print("# Tests polarization (1D) ") print("# ") wavefront = GenericWavefront1D.initialize_wavefront_from_range( x_min=-0.5e-3, x_max=0.5e-3, number_of_points=2048, wavelength=1.5e-10, polarization=Polarization.TOTAL) ca = numpy.zeros(wavefront.size()) wavefront.set_complex_amplitude(ca + (1 + 0j), ca + (0 + 1j)) numpy.testing.assert_almost_equal( wavefront.get_interpolated_phase(0.1e-3, polarization=Polarization.SIGMA), 0.0) numpy.testing.assert_almost_equal( wavefront.get_interpolated_phase(-0.1e-3, polarization=Polarization.PI), numpy.pi / 2) numpy.testing.assert_almost_equal( wavefront.get_interpolated_intensities( -0.111e-3, polarization=Polarization.TOTAL), 2.0) numpy.testing.assert_almost_equal( wavefront.get_interpolated_intensities( -0.111e-3, polarization=Polarization.SIGMA), 1.0) numpy.testing.assert_almost_equal( wavefront.get_interpolated_intensities( -0.111e-3, polarization=Polarization.PI), 1.0) numpy.testing.assert_almost_equal( wavefront.get_intensity(polarization=Polarization.SIGMA), (ca + 1)**2) numpy.testing.assert_almost_equal( wavefront.get_intensity(polarization=Polarization.PI), (ca + 1)**2) numpy.testing.assert_almost_equal( wavefront.get_intensity(polarization=Polarization.TOTAL), 2 * (ca + 1)**2)
def propagate_wavefront(cls, wavefront, propagation_distance): kernel = numpy.exp(1j * 2 * numpy.pi / wavefront.get_wavelength() * wavefront.get_abscissas()**2 / 2 / propagation_distance) kernel *= numpy.exp(1j * 2 * numpy.pi / wavefront.get_wavelength() * propagation_distance) kernel /= 1j * wavefront.get_wavelength() * propagation_distance tmp = numpy.convolve(wavefront.get_complex_amplitude(), kernel, mode='same') wavefront_out = GenericWavefront1D( wavefront.get_wavelength(), ScaledArray.initialize_from_steps(tmp, wavefront.offset(), wavefront.delta())) # added [email protected] 2018-03-23 to conserve energy - TODO: review method! wavefront_out.rescale_amplitude( numpy.sqrt(wavefront.get_intensity().sum() / wavefront_out.get_intensity().sum())) return wavefront_out
def test_gaussianhermite_mode(self, do_plot=do_plot): # # plane wave # print("# ") print("# Tests for a 1D Gaussian Hermite mode ") print("# ") wavelength = 1.24e-10 # 2D sigma_x = 100e-6 mode_x = 0 npixels_x = 100 wavefront_length_x = 10 * sigma_x x = numpy.linspace(-0.5 * wavefront_length_x, 0.5 * wavefront_length_x, npixels_x) wf1 = GenericWavefront1D.initialize_wavefront_from_steps( x_start=x[0], x_step=numpy.abs(x[1] - x[0]), number_of_points=npixels_x, wavelength=wavelength) wf1.set_gaussian_hermite_mode(sigma_x, mode_x, amplitude=1.0) numpy.testing.assert_almost_equal(wf1.get_amplitude()[30], 23.9419082194, 5) if do_plot: from srxraylib.plot.gol import plot plot(wf1.get_abscissas(), wf1.get_amplitude(), title="Amplitude of gaussianhermite", show=0)
def test_guess_wavefront_curvature(self): print("# ") print("# Tests guessing wavefront curvature ") print("# ") # # create source # wavefront = GenericWavefront1D.initialize_wavefront_from_range( x_min=-0.5e-3, x_max=0.5e-3, number_of_points=2048, wavelength=1.5e-10) radius = -50.0 # 50. wavefront.set_spherical_wave(radius=radius) if do_plot: from srxraylib.plot.gol import plot radii, fig_of_mer = wavefront.scan_wavefront_curvature(rmin=-1000, rmax=1000, rpoints=100) plot(radii, fig_of_mer) guess_radius = wavefront.guess_wavefront_curvature(rmin=-1000, rmax=1000, rpoints=100) assert (numpy.abs(radius - guess_radius) < 1e-3)
TODO: remove this file """ from wofry.propagator.wavefront1D.generic_wavefront import GenericWavefront1D from srxraylib.plot.gol import plot # # Import section # import numpy from wofry.propagator.propagator import PropagationManager, PropagationElements, PropagationParameters from syned.beamline.beamline_element import BeamlineElement from shadow4.syned.element_coordinates import ElementCoordinates from wofry.propagator.propagators1D.fresnel_zoom import FresnelZoom1D input_wavefront = GenericWavefront1D() input_wavefront = input_wavefront.load_h5_file( "/users/srio/OASYS1.1/minishadow/minishadow/undulator/tmp.h5", "wfr") # input_wavefront.rescale_amplitude( 1.0/numpy.sqrt(input_wavefront.get_intensity().max())) # input_wavefront.set_spherical_wave(radius=100,complex_amplitude=numpy.abs(input_wavefront.get_intensity()) ) # plot(input_wavefront.get_abscissas()*1e6,input_wavefront.get_intensity()) from wofry.beamline.optical_elements.ideal_elements.screen import WOScreen1D optical_element = WOScreen1D() # # propagating #
def test_propagate_1D_fraunhofer_phase(self, do_plot=do_plot): # aperture_type="square" # aperture_diameter = 40e-6 # wavefront_length = 800e-6 # wavelength = 1.24e-10 # npoints=1024 # propagation_distance=40 show = 1 aperture_type = "square" aperture_diameter = 40e-6 wavefront_length = 800e-6 wavelength = 1.24e-10 propagation_distance = 30.0 npoints = 1024 print( "\n# ") print( "# far field 1D (fraunhofer and zoom) diffraction from a %s aperture " % aperture_type) print("# ") wf = GenericWavefront1D.initialize_wavefront_from_range( x_min=-wavefront_length / 2, x_max=wavefront_length / 2, number_of_points=npoints, wavelength=wavelength) wf.set_plane_wave_from_complex_amplitude( (2.0 + 1.0j)) # an arbitraty value propagation_elements = PropagationElements() if aperture_type == 'square': slit = WOSlit1D(boundary_shape=Rectangle(-aperture_diameter / 2, aperture_diameter / 2, 0, 0)) else: raise Exception("Not implemented! ") propagation_elements.add_beamline_element( BeamlineElement(optical_element=slit, coordinates=ElementCoordinates( p=0, q=propagation_distance))) propagator = PropagationManager.Instance() propagation_parameters = PropagationParameters( wavefront=wf, propagation_elements=propagation_elements) wf1_franuhofer = propagator.do_propagation(propagation_parameters, Fraunhofer1D.HANDLER_NAME) propagation_parameters.set_additional_parameters( "shift_half_pixel", True) propagation_parameters.set_additional_parameters( "magnification_x", 1.5) wf1_zoom = propagator.do_propagation(propagation_parameters, FresnelZoom1D.HANDLER_NAME) intensity_fraunhofer = wf1_franuhofer.get_intensity( ) / wf1_franuhofer.get_intensity().max() intensity_zoom = wf1_zoom.get_intensity() / wf1_zoom.get_intensity( ).max() if do_plot: from srxraylib.plot.gol import plot plot( wf1_franuhofer.get_abscissas() * 1e6 / propagation_distance, intensity_fraunhofer, wf1_zoom.get_abscissas() * 1e6 / propagation_distance, intensity_zoom, legend=["Fraunhofer", "Zoom"], legend_position=(0.95, 0.95), title= "1D INTENSITY diffraction from aperture of %3.1f um at wavelength of %3.1f A" % (aperture_diameter * 1e6, wavelength * 1e10), xtitle="X (urad)", ytitle="Intensity", xrange=[-20, 20], show=show) plot( wf1_franuhofer.get_abscissas() * 1e6 / propagation_distance, wf1_franuhofer.get_phase(unwrap=1), wf1_zoom.get_abscissas() * 1e6 / propagation_distance, wf1_zoom.get_phase(unwrap=1), legend=["Fraunhofer", "Zoom"], legend_position=(0.95, 0.95), title= "1D diffraction from a %s aperture of %3.1f um at wavelength of %3.1f A" % (aperture_type, aperture_diameter * 1e6, wavelength * 1e10), xtitle="X (urad)", ytitle="Intensity", xrange=[-20, 20], show=show)
def propagate_1D( self, do_plot=do_plot, method='fft', wavelength=1.24e-10, aperture_type='square', aperture_diameter=40e-6, wavefront_length=100e-6, npoints=500, propagation_distance=30.0, normalization=True, # TODO put False show=1, amplitude=(0.0 + 1.0j)): print( "\n# ") print("# 1D (%s) propagation from a %s aperture " % (method, aperture_type)) print("# ") wf = GenericWavefront1D.initialize_wavefront_from_range( x_min=-wavefront_length / 2, x_max=wavefront_length / 2, number_of_points=npoints, wavelength=wavelength) wf.set_plane_wave_from_complex_amplitude( amplitude) # an arbitraty value deltax = wf.get_abscissas()[1] - wf.get_abscissas()[0] propagation_elements = PropagationElements() slit = None if aperture_type == 'square': slit = WOSlit1D(boundary_shape=Rectangle(-aperture_diameter / 2, aperture_diameter / 2, 0, 0)) elif aperture_type == 'gaussian': slit = WOGaussianSlit1D( boundary_shape=Rectangle(-aperture_diameter / 2, aperture_diameter / 2, 0, 0)) else: raise Exception( "Not implemented! (accepted: circle, square, gaussian)") propagation_elements.add_beamline_element( BeamlineElement(optical_element=slit, coordinates=ElementCoordinates( p=0, q=propagation_distance))) propagator = PropagationManager.Instance() propagation_parameters = PropagationParameters( wavefront=wf, propagation_elements=propagation_elements) print("Using propagator method: ", method) fresnel_analytical = True if method == 'fft': wf1 = propagator.do_propagation(propagation_parameters, Fresnel1D.HANDLER_NAME) elif method == 'convolution': wf1 = propagator.do_propagation(propagation_parameters, FresnelConvolution1D.HANDLER_NAME) elif method == 'integral': propagation_parameters.set_additional_parameters( "magnification_x", 1.5) propagation_parameters.set_additional_parameters( "magnification_N", 2.0) wf1 = propagator.do_propagation(propagation_parameters, Integral1D.HANDLER_NAME) elif method == 'fraunhofer': fresnel_analytical = False # propagation_parameters.set_additional_parameters("shift_half_pixel", 0) wf1 = propagator.do_propagation(propagation_parameters, Fraunhofer1D.HANDLER_NAME) elif method == 'zoom': propagation_parameters.set_additional_parameters( "magnification_x", 1.5) wf1 = propagator.do_propagation(propagation_parameters, FresnelZoom1D.HANDLER_NAME) else: raise Exception("Not implemented method: %s" % method) if fresnel_analytical: xx, alpha = fresnel_analytical_rectangle( fresnel_number=None, propagation_distance=propagation_distance, aperture_half=0.5 * aperture_diameter, wavelength=wavelength, detector_array=wf1.get_abscissas(), npoints=None) else: xx, alpha = fraunhofer_analytical_rectangle( fresnel_number=None, propagation_distance=propagation_distance, aperture_half=0.5 * aperture_diameter, wavelength=wavelength, detector_array=wf1.get_abscissas(), npoints=None) angle_x = xx / propagation_distance intensity_theory = numpy.abs(amplitude * alpha)**2 intensity_calculated = wf1.get_intensity() if normalization: intensity_calculated /= intensity_calculated.max() intensity_theory /= intensity_theory.max() if do_plot: from srxraylib.plot.gol import plot plot( wf1.get_abscissas() * 1e6 / propagation_distance, intensity_calculated, angle_x * 1e6, intensity_theory, legend=["%s " % method, "analytical"], legend_position=(0.95, 0.95), title= "1D (%s) diffraction from a %s aperture of %3.1f um at \n wavelength of %3.1f A" % (method, aperture_type, aperture_diameter * 1e6, wavelength * 1e10), xtitle="X (urad)", ytitle="Intensity", xrange=[-20, 20], ylog=True, show=show) plot( wf1.get_abscissas() * 1e6, wf1.get_phase(unwrap=True), 1e6 * xx, numpy.unwrap(numpy.angle(alpha)), legend=["%s " % method, "analytical"], title= "1D (%s) diffraction from a %s aperture of %3.1f um at \n wavelength of %3.1f A NOT ASSERTED!!" % (method, aperture_type, aperture_diameter * 1e6, wavelength * 1e10), xtitle="X (urad)", ytitle="Phase", # xrange=[-20, 20], ) return wf1.get_abscissas( ) / propagation_distance, intensity_calculated, intensity_theory
def propagate_wavefront_new( cls, wavefront, propagation_distance, fraunhofer_kernel=True, # set to False for far field propagator shift_half_pixel=None, # not more used, kept for version compatibility ): # # check validity # x = wavefront.get_abscissas() deltax = wavefront.delta() # # compute Fourier transform # # frequency for axis 1 npixels = wavefront.size() pixelsize = wavefront.delta() wavenumber = wavefront.get_wavenumber() wavelength = wavefront.get_wavelength() freq_nyquist = 0.5 / pixelsize if numpy.mod(npixels, 2) == 0: freq_n = numpy.arange(-npixels // 2, npixels // 2, 1) / (npixels // 2) else: freq_n = numpy.arange(-(npixels - 1) // 2, (npixels + 1) // 2, 1) / ((npixels - 1) // 2) freq_x = freq_n * freq_nyquist x2 = freq_x * propagation_distance * wavelength P1 = numpy.exp(1.0j * wavenumber * propagation_distance) # fsq = freq_x ** 2 # P2 = numpy.exp(-1.0j * wavenumber / 2 / propagation_distance * fsq) P2 = numpy.exp(1.0j * wavenumber / 2 / propagation_distance * x**2) P3 = 1.0j * wavelength * propagation_distance if fraunhofer_kernel: exponential = 1.0 + 0j else: exponential = numpy.exp(1j * wavenumber / 2 / propagation_distance * x**2) F1 = numpy.fft.fft(exponential * wavefront.get_complex_amplitude() ) # Take the fourier transform of the image. # Now shift the quadrants around so that low spatial frequencies are in # the center of the 2D fourier transformed image. F1 *= P1 F1 *= P2 F1 /= numpy.sqrt(P3) # this is 1D -> no sqrt for 2D F2 = numpy.fft.fftshift(F1) F2 *= deltax # why?? wavefront_out = GenericWavefront1D.initialize_wavefront_from_arrays( x_array=x2, y_array=F2, wavelength=wavelength) # added [email protected] 2018-03-23 to conserve energy - TODO: review method! # wavefront_out.rescale_amplitude(numpy.sqrt(wavefront.get_intensity().sum() / # wavefront_out.get_intensity().sum())) return wavefront_out
def propagate_wavefront(cls, wavefront1, propagation_distance1, magnification_x=1.0, radius=1e6): wavefront = wavefront1.duplicate() shape = wavefront.size() delta = wavefront.delta() wavenumber = wavefront.get_wavenumber() wavelength = wavefront.get_wavelength() # radius = -50.0 magnification = (propagation_distance1 + radius) / radius propagation_distance = propagation_distance1 / magnification # # make plane wave by adding a spherical wavefront with radius -R # new_phase = 1.0 * wavefront.get_wavenumber() * ( wavefront.get_abscissas()**2) / (-2 * radius) wavefront.add_phase_shifts(new_phase) # # main 2 FFT block # fft_scale = numpy.fft.fftfreq(shape) / delta x = wavefront.get_abscissas() x_rescaling = wavefront.get_abscissas() * magnification_x r1sq = x**2 * (1 - magnification_x) r2sq = x_rescaling**2 * ((magnification_x - 1) / magnification_x) fsq = (fft_scale**2 / magnification_x) Q1 = wavenumber / 2 / propagation_distance * r1sq Q2 = numpy.exp(-1.0j * numpy.pi * wavelength * propagation_distance * fsq) Q3 = numpy.exp(1.0j * wavenumber / 2 / propagation_distance * r2sq) wavefront.add_phase_shift(Q1) fft = numpy.fft.fft(wavefront.get_complex_amplitude()) ifft = numpy.fft.ifft(fft * Q2) * Q3 / numpy.sqrt(magnification_x) # # # # # calculate new phase term and scale coordinates # k = wavefront.get_wavenumber() PHASE1 = numpy.ones( wavefront.get_abscissas().size) * (k * propagation_distance * (1 - 1 / magnification)) PHASE2 = k / 2 / propagation_distance * ( magnification - 1) / magnification * (wavefront.get_abscissas() * magnification)**2 PHASE = PHASE2 + PHASE1 wf_propagated = GenericWavefront1D.initialize_wavefront_from_arrays( x_rescaling * magnification, ifft / numpy.sqrt(magnification) * numpy.exp(1j * PHASE), wavelength=wavelength) return wf_propagated
def test_plane_wave(self, do_plot=do_plot): # # plane wave # print("# ") print("# Tests for a 1D plane wave ") print("# ") wavelength = 1.24e-10 wavefront_length_x = 400e-6 npixels_x = 1024 wavefront_x = numpy.linspace(-0.5 * wavefront_length_x, 0.5 * wavefront_length_x, npixels_x) wavefront = GenericWavefront1D.initialize_wavefront_from_steps( x_start=wavefront_x[0], x_step=numpy.abs(wavefront_x[1] - wavefront_x[0]), number_of_points=npixels_x, wavelength=wavelength) numpy.testing.assert_almost_equal(wavefront_x, wavefront.get_abscissas(), 9) # possible modifications wavefront.set_plane_wave_from_amplitude_and_phase(5.0, numpy.pi / 2) numpy.testing.assert_almost_equal(wavefront.get_intensity(), 25, 5) wavefront.set_plane_wave_from_complex_amplitude(2.0 + 3j) numpy.testing.assert_almost_equal(wavefront.get_intensity(), 13, 5) phase_before = wavefront.get_phase() wavefront.add_phase_shift(numpy.pi / 2) phase_after = wavefront.get_phase() numpy.testing.assert_almost_equal(phase_before + numpy.pi / 2, phase_after, 5) intensity_before = wavefront.get_intensity() wavefront.rescale_amplitude(10.0) intensity_after = wavefront.get_intensity() numpy.testing.assert_almost_equal(intensity_before * 100, intensity_after, 5) # interpolation wavefront.set_plane_wave_from_complex_amplitude(2.0 + 3j) test_value1 = wavefront.get_interpolated_complex_amplitude(0.01) self.assertAlmostEqual((2.0 + 3j).real, test_value1.real, 5) self.assertAlmostEqual((2.0 + 3j).imag, test_value1.imag, 5) if do_plot: from srxraylib.plot.gol import plot plot(wavefront.get_abscissas(), wavefront.get_intensity(), title="Intensity (plane wave)", show=0) plot(wavefront.get_abscissas(), wavefront.get_phase(), title="Phase (plane wave)", show=1)