def test_save_load_h5_file(self): wfr = GenericWavefront2D.initialize_wavefront_from_range( -0.004, 0.004, -0.001, 0.001, (500, 200)) wfr.set_gaussian(0.002 / 6, 0.001 / 12) wfr.save_h5_file("tmp_wofry.h5", subgroupname="wfr", intensity=True, phase=True, overwrite=True) wfr.set_gaussian(0.002 / 6 / 2, 0.001 / 12 / 2) print("Writing file: tmp_wofry.h5") wfr.save_h5_file("tmp_wofry.h5", subgroupname="wfr2", intensity=True, phase=False, overwrite=False) # test same amplitudes: print("Accessing file, path: ", "tmp_wofry.h5", "wfr2") wfr2 = GenericWavefront2D.load_h5_file("tmp_wofry.h5", "wfr2") print("Cleaning file tmp_wofry.h5") os.remove("tmp_wofry.h5") assert (wfr2.is_identical(wfr))
def propagate_numpy_wavefront(cls, filename_in, filename_out, beamline, mypropagator, return_wavefront_list=True): file_content = numpy.load(filename_in) e_field = file_content["e_field"] coordinates = file_content["coordinates"] energies = file_content["energies"] x = numpy.linspace(coordinates[0], coordinates[1], e_field.shape[1]) y = numpy.linspace(coordinates[2], coordinates[3], e_field.shape[2]) wofry_wf_in = GenericWavefront2D.initialize_wavefront_from_arrays(x, y, e_field[0, :, :, 0].copy()) wofry_wf_in.set_photon_energy(energies[0]) # wofry_wf_out_list = cls.propagate_classmethod(wofry_wf_in,beamline,mypropagator) wofry_wf_out = beamline.propagate(wofry_wf_in, mypropagator, return_wavefront_list=return_wavefront_list) if return_wavefront_list: wofry_wf_out_list = wofry_wf_out wofry_wf_out = wofry_wf_out_list[-1] e_field[0, :, :, 0] = wofry_wf_out.get_complex_amplitude() coordinates[0] = wofry_wf_out.get_coordinate_x()[0] coordinates[1] = wofry_wf_out.get_coordinate_x()[-1] coordinates[2] = wofry_wf_out.get_coordinate_y()[0] coordinates[3] = wofry_wf_out.get_coordinate_y()[-1] numpy.savez(filename_out, e_field=e_field, coordinates=coordinates, energies=energies) if return_wavefront_list: return wofry_wf_out_list else: return wofry_wf_out
def propagate_single_mode(af, i, beamline): 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.propagators2D.fresnel_zoom_xy import FresnelZoomXY2D from wofry.propagator.wavefront2D.generic_wavefront import GenericWavefront2D from wofry.beamline.optical_elements.ideal_elements.screen import WOScreen mi = af.coherentMode(i) evi = af.eigenvalue(i) print("propagating mode index", i, evi, mi.shape) input_wavefront = GenericWavefront2D.initialize_wavefront_from_arrays( x_array=af.xCoordinates(), y_array=af.yCoordinates(), z_array=mi * numpy.sqrt(evi), ) i0 = input_wavefront.get_integrated_intensity() input_wavefront.set_photon_energy(17226.0) propagator = PropagationManager.Instance() try: propagator.add_propagator(FresnelZoomXY2D()) except: pass wfp = beamline.propagate(input_wavefront, propagator) i1 = wfp[-1].get_integrated_intensity() return wfp, i1 / i0
def create_wavefront_generic(size_factor=1,pixel_size=1e-6,wavelength=1.5e-10): w = GenericWavefront2D.initialize_wavefront_from_steps(x_start=-0.5*pixel_size*512*size_factor,x_step=pixel_size, y_start=-0.5*pixel_size*512*size_factor,y_step=pixel_size, number_of_points=(512*size_factor,512*size_factor),wavelength=wavelength) w.set_plane_wave_from_complex_amplitude(complex_amplitude=(1.0+0.0j)) w.clip_square(x_min=-100e-6,x_max=100e-6,y_min=-10e-6,y_max=10e-6) return w
def toGenericWavefront(self): wavefront = GenericWavefront2D.initialize_wavefront_from_range(self.mesh.xStart, self.mesh.xFin, self.mesh.yStart, self.mesh.yFin, number_of_points=(self.mesh.nx, self.mesh.ny), wavelength=self.get_wavelength(), polarization=Polarization.TOTAL) wavefront.set_complex_amplitude(SRWEFieldAsNumpy(srwwf=self)[0, :, :, 0], SRWEFieldAsNumpy(srwwf=self)[0, :, :, 1]) return wavefront
def test_multiple_slit(self): print("# ") print( "# Tests multiple slit (2D) ") print("# ") wavefront = GenericWavefront2D.initialize_wavefront_from_range( x_min=-0.5e-3, x_max=0.5e-3, y_min=-0.5e-3, y_max=0.5e-3, number_of_points=(2048, 1024), wavelength=1.5e-10, polarization=Polarization.TOTAL) ca = numpy.zeros(wavefront.size()) wavefront.set_complex_amplitude(ca + (10 + 0j), ca + (0 + 1j)) # window_circle = wavefront.clip_circle(50e-6, -2e-4, -2e-4, apply_to_wavefront=False) window_rectangle = wavefront.clip_square(2e-4, 3e-4, 2e-4, 3e-4, apply_to_wavefront=False) window_ellipse = wavefront.clip_ellipse(50e-6, 25e-6, -2e-4, 2e-4, apply_to_wavefront=False) window_ellipse2 = wavefront.clip_ellipse(50e-6, 100e-6, 2e-4, -2e-4, apply_to_wavefront=False) wavefront.clip_window(window_circle + window_rectangle + window_ellipse + window_ellipse2) if True: from srxraylib.plot.gol import plot_image plot_image(wavefront.get_intensity(), 1e6 * wavefront.get_coordinate_x(), 1e6 * wavefront.get_coordinate_y()) numpy.testing.assert_almost_equal( wavefront.get_interpolated_intensities( 0, 0, polarization=Polarization.TOTAL), 0.0)
def test_gaussianhermite_mode(self, do_plot=do_plot): # # plane wave # print("# ") print("# Tests for a 2D Gaussian Hermite mode ") print("# ") wavelength = 1.24e-10 # 2D sigma_x = 100e-6 mode_x = 0 npixels_x = 100 sigma_y = 50e-6 mode_y = 3 npixels_y = 100 wavefront_length_x = 10 * sigma_x wavefront_length_y = 10 * sigma_y x = numpy.linspace(-0.5 * wavefront_length_x, 0.5 * wavefront_length_x, npixels_x) y = numpy.linspace(-0.5 * wavefront_length_y, 0.5 * wavefront_length_y, npixels_y) wf1 = GenericWavefront2D.initialize_wavefront_from_steps( x_start=x[0], x_step=numpy.abs(x[1] - x[0]), y_start=y[0], y_step=numpy.abs(y[1] - y[0]), number_of_points=(npixels_x, npixels_y), wavelength=wavelength) wf1.set_gaussian_hermite_mode(sigma_x, sigma_y, mode_x, mode_y, amplitude=1.0) numpy.testing.assert_almost_equal(wf1.get_amplitude()[30, 40], 1383.76448118, 3) if do_plot: from srxraylib.plot.gol import plot_image plot_image(wf1.get_amplitude(), wf1.get_coordinate_x(), wf1.get_coordinate_y(), title="Amplitude of gaussianhermite mode", show=1)
def toGenericWavefront(self): x,y = self.get_x_y() wavefront = GenericWavefront2D.initialize_wavefront_from_range(x.min(), x.max(), y.min(), y.max(), number_of_points=(x.shape[0], y.shape[0]), wavelength=self.wavelength) print("Shape", wavefront.size()) print("WL", m_to_eV, wavefront.get_wavelength(), wavefront.get_photon_energy()) wavefront.set_complex_amplitude((numpy.fft.fftshift(self.d)).T) return wavefront
def load_h5_file(filename, filepath): try: f = h5py.File(filename, 'r') mesh_X = f[filepath + "/wfr_mesh_X"].value mesh_Y = f[filepath + "/wfr_mesh_Y"].value complex_amplitude_s = f[filepath + "/wfr_complex_amplitude_s"].value.T wfr = GenericWavefront2D.initialize_wavefront_from_arrays( x_array=numpy.linspace(mesh_X[0], mesh_X[1], int(mesh_X[2])), y_array=numpy.linspace(mesh_Y[0], mesh_Y[1], int(mesh_Y[2])), z_array=complex_amplitude_s) wfr.set_photon_energy(f[filepath + "/wfr_photon_energy"].value) f.close() return wfr except: raise Exception("Failed to load 2D wavefront to h5 file: " + filename)
def create_wavefront(): # # create input_wavefront # # from wofry.propagator.wavefront2D.generic_wavefront import GenericWavefront2D input_wavefront = GenericWavefront2D.initialize_wavefront_from_range( x_min=-0.001200, x_max=0.001200, y_min=-0.001200, y_max=0.001200, number_of_points=(2048, 2048)) input_wavefront.set_photon_energy(17225) input_wavefront.set_spherical_wave(radius=28.3, complex_amplitude=complex(1, 0)) return input_wavefront
def test_polarization(self): print("# ") print("# Tests polarization (2D) ") print("# ") wavefront = GenericWavefront2D.initialize_wavefront_from_range( x_min=-0.5e-3, x_max=0.5e-3, y_min=-0.5e-3, y_max=0.5e-3, number_of_points=(2048, 1024), 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, 0.1e-3, polarization=Polarization.SIGMA), 0.0) numpy.testing.assert_almost_equal( wavefront.get_interpolated_phase(-0.1e-3, 0.1e-3, polarization=Polarization.PI), numpy.pi / 2) numpy.testing.assert_almost_equal( wavefront.get_interpolated_intensities( -0.111e-3, -0.111e-3, polarization=Polarization.TOTAL), 2.0) numpy.testing.assert_almost_equal( wavefront.get_interpolated_intensities( -0.111e-3, -0.111e-3, polarization=Polarization.SIGMA), 1.0) numpy.testing.assert_almost_equal( wavefront.get_interpolated_intensities( -0.111e-3, -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_numpy_wavefront(cls, filename_in, filename_out, beamline, mypropagator, return_wavefront_list=True): file_content = numpy.load(filename_in) e_field = file_content["e_field"] coordinates = file_content["coordinates"] energies = file_content["energies"] x = numpy.linspace(coordinates[0], coordinates[1], e_field.shape[1]) y = numpy.linspace(coordinates[2], coordinates[3], e_field.shape[2]) wofry_wf_in = GenericWavefront2D.initialize_wavefront_from_arrays( x, y, e_field[0, :, :, 0].copy()) wofry_wf_in.set_photon_energy(energies[0]) # wofry_wf_out_list = cls.propagate_classmethod(wofry_wf_in,beamline,mypropagator) wofry_wf_out = beamline.propagate( wofry_wf_in, mypropagator, return_wavefront_list=return_wavefront_list) if return_wavefront_list: wofry_wf_out_list = wofry_wf_out wofry_wf_out = wofry_wf_out_list[-1] e_field[0, :, :, 0] = wofry_wf_out.get_complex_amplitude() coordinates[0] = wofry_wf_out.get_coordinate_x()[0] coordinates[1] = wofry_wf_out.get_coordinate_x()[-1] coordinates[2] = wofry_wf_out.get_coordinate_y()[0] coordinates[3] = wofry_wf_out.get_coordinate_y()[-1] numpy.savez(filename_out, e_field=e_field, coordinates=coordinates, energies=energies) if return_wavefront_list: return wofry_wf_out_list else: return wofry_wf_out
def fresnel(wavefront, propagation_distance, shift_half_pixel=False): wavelength = wavefront.get_wavelength() # # convolving with the Fresnel kernel via FFT multiplication # fft = numpy.fft.fft2(wavefront.get_complex_amplitude()) # frequency for axis 1 shape = wavefront.size() delta = wavefront.delta() pixelsize = delta[0] # p_x[1] - p_x[0] npixels = shape[0] freq_nyquist = 0.5 / pixelsize freq_n = numpy.linspace(-1.0, 1.0, npixels) freq_x = freq_n * freq_nyquist # frequency for axis 2 pixelsize = delta[1] npixels = shape[1] freq_nyquist = 0.5 / pixelsize freq_n = numpy.linspace(-1.0, 1.0, npixels) freq_y = freq_n * freq_nyquist if shift_half_pixel: freq_x = freq_x - 0.5 * numpy.abs(freq_x[1] - freq_x[0]) freq_y = freq_y - 0.5 * numpy.abs(freq_y[1] - freq_y[0]) freq_xy = numpy.array(numpy.meshgrid(freq_y, freq_x)) # fft *= numpy.exp((-1.0j) * numpy.pi * wavelength * propagation_distance * # numpy.fft.fftshift(freq_xy[0]*freq_xy[0] + freq_xy[1]*freq_xy[1]) ) fft *= numpy.exp( (-1.0j) * numpy.pi * wavelength * propagation_distance * numpy.fft.fftshift(freq_xy[0] * freq_xy[0] + freq_xy[1] * freq_xy[1])) wf_propagated = GenericWavefront2D.initialize_wavefront_from_arrays( x_array=wavefront.get_coordinate_x(), y_array=wavefront.get_coordinate_y(), z_array=numpy.fft.ifft2(fft), wavelength=wavelength) return wf_propagated
def send_mode(self): wf = GenericWavefront2D.initialize_wavefront_from_arrays( self.af.x_coordinates(), self.af.y_coordinates(), self.af.mode(self.MODE_INDEX)) wf.set_photon_energy(self.af.photon_energy()) ampl = wf.get_complex_amplitude() if self.TYPE_PRESENTATION == 5: eigen = self.af.eigenvalues_old() wf.set_complex_amplitude(ampl * numpy.sqrt(eigen[self.MODE_INDEX])) else: wf.set_complex_amplitude(ampl) beamline = WOBeamline(light_source=self.get_light_source()) print(">>> sending mode: ", int(self.MODE_INDEX)) self.send("WofryData", WofryData(wavefront=wf, beamline=beamline)) # script self.wofry_python_script.set_code(beamline.to_python_code())
def propagate_wavefront(cls, wavefront, propagation_distance, shift_half_pixel=False): from scipy.signal import fftconvolve wavelength = wavefront.get_wavelength() X = wavefront.get_mesh_x() Y = wavefront.get_mesh_y() if shift_half_pixel: x = wavefront.get_coordinate_x() y = wavefront.get_coordinate_y() X += 0.5 * numpy.abs(x[0] - x[1]) Y += 0.5 * numpy.abs(y[0] - y[1]) kernel = numpy.exp(1j * 2 * numpy.pi / wavefront.get_wavelength() * (X**2 + Y**2) / 2 / propagation_distance) kernel *= numpy.exp(1j * 2 * numpy.pi / wavefront.get_wavelength() * propagation_distance) kernel /= 1j * wavefront.get_wavelength() * propagation_distance wavefront_out = GenericWavefront2D.initialize_wavefront_from_arrays( x_array=wavefront.get_coordinate_x(), y_array=wavefront.get_coordinate_y(), z_array=fftconvolve(wavefront.get_complex_amplitude(), kernel, mode='same'), 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 test_plane_wave(self, do_plot=do_plot): # # plane wave # print("# ") print( "# Tests for a 2D plane wave " ) print("# ") wavelength = 1.24e-10 wavefront_length_x = 400e-6 wavefront_length_y = wavefront_length_x npixels_x = 1024 npixels_y = npixels_x x = numpy.linspace(-0.5 * wavefront_length_x, 0.5 * wavefront_length_x, npixels_x) y = numpy.linspace(-0.5 * wavefront_length_y, 0.5 * wavefront_length_y, npixels_y) wavefront = GenericWavefront2D.initialize_wavefront_from_steps( x_start=x[0], x_step=numpy.abs(x[1] - x[0]), y_start=y[0], y_step=numpy.abs(y[1] - y[0]), number_of_points=(npixels_x, npixels_y), wavelength=wavelength) # 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, 1.3) 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_image plot_image(wavefront.get_intensity(), wavefront.get_coordinate_x(), wavefront.get_coordinate_y(), title="Intensity (plane wave)", show=0) plot_image(wavefront.get_phase(), wavefront.get_coordinate_x(), wavefront.get_coordinate_y(), title="Phase (plane wave)", show=1)
(-2 * radius)) if __name__ == "__main__": try: initialize_default_propagator_2D() except: pass propagator = PropagationManager.Instance() wavefront = GenericWavefront2D.initialize_wavefront_from_range( x_min=-2.5e-3, x_max=2.5e-3, y_min=-1e-3, y_max=1e-3, number_of_points=(2 * 1024, 1024), wavelength=73e-12) radius = 28.3 wavefront.set_spherical_wave(radius=radius) scale_factor = 1 screen = WOScreen(name="PIRRONE") coordinates = ElementCoordinates(p=0.0, q=-scale_factor * radius) propagation_elements = PropagationElements() propagation_elements.add_beamline_element(
label.set_color('white') label.set_fontsize(1) self.plot_canvas._histoHPlot.setGraphYLabel('') self.plot_canvas._histoVPlot.setGraphXLabel('') self.plot_canvas._histoHPlot.replot() self.plot_canvas._histoVPlot.replot() self.info_box.clear() if __name__ == "__main__": from wofry.propagator.wavefront2D.generic_wavefront import GenericWavefront2D w = GenericWavefront2D.initialize_wavefront_from_range( -0.002, 0.002, -0.001, 0.001, (200, 200)) w.set_gaussian(0.00055, 0.0002) from PyQt5.QtWidgets import QApplication app = QApplication([]) widget = QWidget() layout = QVBoxLayout() oo = ImageViewWithFWHM() oo.plot_2D(w.get_intensity(), w.get_coordinate_x(), w.get_coordinate_y(), factor1=1e6, factor2=1e6,
def test_propagate_2D_fraunhofer(self,do_plot=do_plot,aperture_type='square',aperture_diameter=40e-6, pixelsize_x=1e-6,pixelsize_y=1e-6,npixels_x=1024,npixels_y=1024,wavelength=1.24e-10): """ :param do_plot: 0=No plot, 1=Do plot :param aperture_type: 'circle' 'square' 'gaussian' (Gaussian sigma = aperture_diameter/2.35) :param aperture_diameter: :param pixelsize_x: :param pixelsize_y: :param npixels_x: :param npixels_y: :param wavelength: :return: """ print("\n# ") print("# far field 2D (fraunhofer) diffraction from a square aperture ") print("# ") method = "fraunhofer" print("Fraunhoffer diffraction valid for distances > > a^2/lambda = %f m"%((aperture_diameter/2)**2/wavelength)) wf = GenericWavefront2D.initialize_wavefront_from_range(x_min=-pixelsize_x*npixels_x/2,x_max=pixelsize_x*npixels_x/2, y_min=-pixelsize_y*npixels_y/2,y_max=pixelsize_y*npixels_y/2, number_of_points=(npixels_x,npixels_y),wavelength=wavelength) wf.set_plane_wave_from_complex_amplitude((1.0+0j)) propagation_elements = PropagationElements() slit = None if aperture_type == 'square': slit = WOSlit(boundary_shape=Rectangle(-aperture_diameter/2, aperture_diameter/2, -aperture_diameter/2, aperture_diameter/2)) elif aperture_type == 'gaussian': slit = WOGaussianSlit(boundary_shape=Rectangle(-aperture_diameter/2, aperture_diameter/2, -aperture_diameter/2, aperture_diameter/2)) else: raise Exception("Not implemented! (accepted: circle, square, gaussian)") propagation_elements.add_beamline_element(BeamlineElement(optical_element=slit, coordinates=ElementCoordinates(p=0, q=1.0))) propagator = PropagationManager.Instance() propagation_parameters = PropagationParameters(wavefront=wf, propagation_elements=propagation_elements) propagation_parameters.set_additional_parameters("shift_half_pixel", True) wf1 = propagator.do_propagation(propagation_parameters, Fraunhofer2D.HANDLER_NAME) if aperture_type == 'circle': wf.clip_circle(aperture_diameter/2) elif aperture_type == 'square': wf.clip_square(-aperture_diameter/2, aperture_diameter/2,-aperture_diameter/2, aperture_diameter/2) elif aperture_type == 'gaussian': X = wf.get_mesh_x() Y = wf.get_mesh_y() window = numpy.exp(- (X*X + Y*Y)/2/(aperture_diameter/2.35)**2) wf.rescale_amplitudes(window) else: raise Exception("Not implemented! (accepted: circle, square, gaussian)") if do_plot: plot_image(wf.get_intensity(),1e6*wf.get_coordinate_x(),1e6*wf.get_coordinate_y(), title="aperture intensity (%s), Diameter=%5.1f um"% (aperture_type,1e6*aperture_diameter),xtitle="X [um]",ytitle="Y [um]", show=0) plot_image(wf1.get_intensity(),1e6*wf1.get_coordinate_x(),1e6*wf1.get_coordinate_y(), title="2D Diffracted intensity (%s) by a %s slit of aperture %3.1f um"% (aperture_type,method,1e6*aperture_diameter), xtitle="X [urad]",ytitle="Y [urad]", show=0) angle_x = wf1.get_coordinate_x() # + 0.5*wf1.delta()[0] # shifted of half-pixel!!! intensity_theory = get_theoretical_diffraction_pattern(angle_x, aperture_type=aperture_type,aperture_diameter=aperture_diameter, wavelength=wavelength,normalization=True) intensity_calculated = wf1.get_intensity()[:,int(wf1.size()[1]/2)] intensity_calculated /= intensity_calculated.max() if do_plot: plot(wf1.get_coordinate_x()*1e6,intensity_calculated, angle_x*1e6,intensity_theory, legend=["Calculated (FT) H profile","Theoretical"],legend_position=(0.95, 0.95), title="2D Fraunhofer Diffraction of a %s slit of %3.1f um at wavelength of %3.1f A"% (aperture_type,aperture_diameter*1e6,wavelength*1e10), xtitle="X (urad)", ytitle="Intensity",xrange=[-80,80]) numpy.testing.assert_almost_equal(intensity_calculated,intensity_theory,1)
def test_propagate_2D_fraunhofer_phase(self,do_plot=do_plot,aperture_type='square', aperture_diameter=40e-6, pixelsize_x=1e-6,pixelsize_y=1e-6,npixels_x=1024,npixels_y=1024, propagation_distance=30.0,wavelength=1.24e-10): print("\n# ") print("# far field 2D (fraunhofer) diffraction from a square aperture ") print("# ") method = "fraunhofer" print("Fraunhoffer diffraction valid for distances > > a^2/lambda = %f m"%((aperture_diameter/2)**2/wavelength)) wf = GenericWavefront2D.initialize_wavefront_from_range(x_min=-pixelsize_x*npixels_x/2,x_max=pixelsize_x*npixels_x/2, y_min=-pixelsize_y*npixels_y/2,y_max=pixelsize_y*npixels_y/2, number_of_points=(npixels_x,npixels_y),wavelength=wavelength) wf.set_plane_wave_from_complex_amplitude((1.0+0j)) propagation_elements = PropagationElements() slit = None if aperture_type == 'square': slit = WOSlit(boundary_shape=Rectangle(-aperture_diameter/2, aperture_diameter/2, -aperture_diameter/2, aperture_diameter/2)) elif aperture_type == 'gaussian': slit = WOGaussianSlit(boundary_shape=Rectangle(-aperture_diameter/2, aperture_diameter/2, -aperture_diameter/2, aperture_diameter/2)) 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) propagation_parameters.set_additional_parameters("shift_half_pixel", True) wf1_fraunhofer = propagator.do_propagation(propagation_parameters, Fraunhofer2D.HANDLER_NAME) propagation_parameters.set_additional_parameters("shift_half_pixel", True) propagation_parameters.set_additional_parameters("magnification_x", 1.5) propagation_parameters.set_additional_parameters("magnification_y", 2.5) wf1_zoom = propagator.do_propagation(propagation_parameters, FresnelZoomXY2D.HANDLER_NAME) if aperture_type == 'circle': wf.clip_circle(aperture_diameter/2) elif aperture_type == 'square': wf.clip_square(-aperture_diameter/2, aperture_diameter/2,-aperture_diameter/2, aperture_diameter/2) elif aperture_type == 'gaussian': X = wf.get_mesh_x() Y = wf.get_mesh_y() window = numpy.exp(- (X*X + Y*Y)/2/(aperture_diameter/2.35)**2) wf.rescale_amplitudes(window) else: raise Exception("Not implemented! (accepted: circle, square, gaussian)") if do_plot: plot_image(wf.get_intensity(),1e6*wf.get_coordinate_x(),1e6*wf.get_coordinate_y(), title="aperture intensity (%s), Diameter=%5.1f um"% (aperture_type,1e6*aperture_diameter),xtitle="X [um]",ytitle="Y [um]", show=0) plot_image(wf1_fraunhofer.get_intensity(),1e6*wf1_fraunhofer.get_coordinate_x(),1e6*wf1_fraunhofer.get_coordinate_y(), title="2D Diffracted intensity (%s) by a %s slit of aperture %3.1f um"% (aperture_type,"Fraunhofer",1e6*aperture_diameter), xtitle="X [urad]",ytitle="Y [urad]", show=0) plot_image(wf1_zoom.get_intensity(),1e6*wf1_zoom.get_coordinate_x(),1e6*wf1_zoom.get_coordinate_y(), title="2D Diffracted intensity (%s) by a %s slit of aperture %3.1f um"% (aperture_type,"Zoom",1e6*aperture_diameter), xtitle="X [urad]",ytitle="Y [urad]", show=0) intensity_calculated_fraunhofer = wf1_fraunhofer.get_intensity()[:,int(wf1_fraunhofer.size()[1]/2)] intensity_calculated_fraunhofer /= intensity_calculated_fraunhofer.max() intensity_calculated_zoom = wf1_zoom.get_intensity()[:,int(wf1_fraunhofer.size()[1]/2)] intensity_calculated_zoom /= intensity_calculated_zoom.max() phase_calculated_fraunhofer = wf1_fraunhofer.get_phase()[:,int(wf1_fraunhofer.size()[1]/2)] phase_calculated_fraunhofer = numpy.unwrap(phase_calculated_fraunhofer) phase_calculated_zoom = wf1_zoom.get_phase()[:,int(wf1_zoom.size()[1]/2)] phase_calculated_zoom = numpy.unwrap(phase_calculated_zoom) if do_plot: plot(wf1_fraunhofer.get_coordinate_x()*1e6/propagation_distance, intensity_calculated_fraunhofer, wf1_zoom.get_coordinate_x()*1e6 /propagation_distance, intensity_calculated_zoom, legend=["Fraunhofer H profile","Zoom H profile"],legend_position=(0.95, 0.95), title="2D Diffraction of a %s slit of %3.1f um at wavelength of %3.1f A"% (aperture_type,aperture_diameter*1e6,wavelength*1e10), xtitle="X (urad)", ytitle="Intensity",xrange=[-80,80],show=0) plot(wf1_fraunhofer.get_coordinate_x()*1e6/propagation_distance, phase_calculated_fraunhofer, wf1_zoom.get_coordinate_x()*1e6 /propagation_distance, phase_calculated_zoom, legend=["Fraunhofer H profile","Zoom H profile"],legend_position=(0.95, 0.95), title="2D Diffraction of a %s slit of %3.1f um at wavelength of %3.1f A"% (aperture_type,aperture_diameter*1e6,wavelength*1e10), xtitle="X (urad)", ytitle="Phase",xrange=[-80,80]) numpy.testing.assert_almost_equal(1e-3*intensity_calculated_fraunhofer,1e-3*intensity_calculated_zoom,1)
def propagate_2D_fresnel(self,do_plot=do_plot,method='fft', wavelength=1.24e-10,aperture_type='square',aperture_diameter=40e-6, pixelsize_x=1e-6,pixelsize_y=1e-6,npixels_x=1024,npixels_y=1024, propagation_distance = 30.0,show=1, use_additional_parameters_input_way=1, # 0=default (common), 1=new (specific)) ): method_label = "fresnel (%s)"%method print("\n# ") print("# 2D near field fresnel (%s) diffraction from a %s aperture "%(method_label,aperture_type)) print("# ") # wf = Wavefront2D.initialize_wavefront_from_steps(x_start=-pixelsize_x*npixels_x/2, # x_step=pixelsize_x, # y_start=-pixelsize_y*npixels_y/2, # y_step=pixelsize_y, # wavelength=wavelength, # number_of_points=(npixels_x,npixels_y)) wf = GenericWavefront2D.initialize_wavefront_from_range(x_min=-pixelsize_x*npixels_x/2,x_max=pixelsize_x*npixels_x/2, y_min=-pixelsize_y*npixels_y/2,y_max=pixelsize_y*npixels_y/2, number_of_points=(npixels_x,npixels_y),wavelength=wavelength) wf.set_plane_wave_from_complex_amplitude((1.0+0j)) propagation_elements = PropagationElements() slit = None if aperture_type == 'square': slit = WOSlit(boundary_shape=Rectangle(-aperture_diameter/2, aperture_diameter/2, -aperture_diameter/2, aperture_diameter/2)) elif aperture_type == 'gaussian': slit = WOGaussianSlit(boundary_shape=Rectangle(-aperture_diameter/2, aperture_diameter/2, -aperture_diameter/2, aperture_diameter/2)) else: raise Exception("Not implemented! (accepted: circle, square, gaussian)") if use_additional_parameters_input_way == 0: 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) if method == 'fft': propagation_parameters.set_additional_parameters("shift_half_pixel", True) wf1 = propagator.do_propagation(propagation_parameters, Fresnel2D.HANDLER_NAME) elif method == 'convolution': propagation_parameters.set_additional_parameters("shift_half_pixel", True) wf1 = propagator.do_propagation(propagation_parameters, FresnelConvolution2D.HANDLER_NAME) elif method == 'integral': propagation_parameters.set_additional_parameters("shuffle_interval", 0) propagation_parameters.set_additional_parameters("calculate_grid_only", 1) wf1 = propagator.do_propagation(propagation_parameters, Integral2D.HANDLER_NAME) elif method == 'zoom': propagation_parameters.set_additional_parameters("shift_half_pixel", True) propagation_parameters.set_additional_parameters("magnification_x", 2.0) propagation_parameters.set_additional_parameters("magnification_y", 0.5) wf1 = propagator.do_propagation(propagation_parameters, FresnelZoomXY2D.HANDLER_NAME) else: raise Exception("Not implemented method: %s"%method) else: if method == 'fft': additional_parameters = {"shift_half_pixel":True} elif method == 'convolution': additional_parameters = {"shift_half_pixel":True} elif method == 'integral': additional_parameters = {"shuffle_interval":0, "calculate_grid_only":1} elif method == 'zoom': additional_parameters = {"shift_half_pixel":True, "magnification_x":2.0, "magnification_y":0.5} else: raise Exception("Not implemented method: %s"%method) propagation_elements.add_beamline_element( BeamlineElement(optical_element=slit,coordinates=ElementCoordinates(p=0, q=propagation_distance)), element_parameters=additional_parameters) propagator = PropagationManager.Instance() propagation_parameters = PropagationParameters(wavefront=wf, propagation_elements=propagation_elements) if method == 'fft': wf1 = propagator.do_propagation(propagation_parameters, Fresnel2D.HANDLER_NAME) elif method == 'convolution': wf1 = propagator.do_propagation(propagation_parameters, FresnelConvolution2D.HANDLER_NAME) elif method == 'integral': wf1 = propagator.do_propagation(propagation_parameters, Integral2D.HANDLER_NAME) elif method == 'zoom': wf1 = propagator.do_propagation(propagation_parameters, FresnelZoomXY2D.HANDLER_NAME) else: raise Exception("Not implemented method: %s"%method) if do_plot: from srxraylib.plot.gol import plot_image plot_image(wf.get_intensity(),1e6*wf.get_coordinate_x(),1e6*wf.get_coordinate_y(), title="aperture intensity (%s), Diameter=%5.1f um"% (aperture_type,1e6*aperture_diameter),xtitle="X [um]",ytitle="Y [um]", show=0) plot_image(wf1.get_intensity(), 1e6*wf1.get_coordinate_x()/propagation_distance, 1e6*wf1.get_coordinate_y()/propagation_distance, title="Diffracted intensity (%s) by a %s slit of aperture %3.1f um"% (aperture_type,method_label,1e6*aperture_diameter), xtitle="X [urad]",ytitle="Y [urad]", show=0) # get the theoretical value angle_x = wf1.get_coordinate_x() / propagation_distance intensity_theory = get_theoretical_diffraction_pattern(angle_x,aperture_type=aperture_type,aperture_diameter=aperture_diameter, wavelength=wavelength,normalization=True) intensity_calculated = wf1.get_intensity()[:,int(wf1.size()[1]/2)] intensity_calculated /= intensity_calculated.max() if do_plot: from srxraylib.plot.gol import plot plot(wf1.get_coordinate_x()*1e6/propagation_distance,intensity_calculated, angle_x*1e6,intensity_theory, legend=["%s H profile"%method_label,"Theoretical (far field)"], legend_position=(0.95, 0.95), title="%s diffraction of a %s slit of %3.1f um at wavelength of %3.1f A"% (method_label,aperture_type,aperture_diameter*1e6,wavelength*1e10), xtitle="X (urad)", ytitle="Intensity",xrange=[-20,20], show=show) return wf1.get_coordinate_x()/propagation_distance,intensity_calculated,angle_x,intensity_theory
def propagation_with_lens(self,do_plot=do_plot,method='fft', wavelength=1.24e-10, pixelsize_x=1e-6,npixels_x=2000,pixelsize_y=1e-6,npixels_y=2000, propagation_distance=30.0,defocus_factor=1.0,propagation_steps=1,show=1): method_label = "fresnel (%s)"%method print("\n# ") print("# near field fresnel (%s) diffraction and focusing "%(method_label)) print("# ") # \ | / # * | | | * # / | \ # <------- d ---------------><--------- d -------> # d is propagation_distance # wf = Wavefront2D.initialize_wavefront_from_steps(x_start=-pixelsize_x*npixels_x/2, # x_step=pixelsize_x, # y_start=-pixelsize_y*npixels_y/2, # y_step=pixelsize_y, # wavelength=wavelength, # number_of_points=(npixels_x,npixels_y)) wf = GenericWavefront2D.initialize_wavefront_from_range(x_min=-pixelsize_x*npixels_x/2,x_max=pixelsize_x*npixels_x/2, y_min=-pixelsize_y*npixels_y/2,y_max=pixelsize_y*npixels_y/2, number_of_points=(npixels_x,npixels_y),wavelength=wavelength) propagation_elements = PropagationElements() spherical_or_plane_and_lens = 1 if spherical_or_plane_and_lens == 0: # set spherical wave at the lens entrance (radius=distance) wf.set_spherical_wave(complex_amplitude=1.0,radius=-propagation_distance) propagation_elements.add_beamline_element(BeamlineElement(optical_element=WOScreen(), coordinates=ElementCoordinates(p=0, q=propagation_distance))) else: # apply lens that will focus at propagation_distance downstream the lens. # Note that the vertical is a bit defocused wf.set_plane_wave_from_complex_amplitude(1.0+0j) focal_length = propagation_distance # / 2 propagation_elements.add_beamline_element(BeamlineElement(optical_element= WOIdealLens("IdealLens",focal_x=focal_length, focal_y=focal_length), coordinates=ElementCoordinates(p=0, q=propagation_distance))) print("Incident intensity: ", wf.get_intensity().sum()) propagator = PropagationManager.Instance() propagation_parameters = PropagationParameters(wavefront=wf, propagation_elements=propagation_elements) if method == 'fft': propagation_parameters.set_additional_parameters("shift_half_pixel", True) wf1 = propagator.do_propagation(propagation_parameters, Fresnel2D.HANDLER_NAME) elif method == 'convolution': propagation_parameters.set_additional_parameters("shift_half_pixel", True) wf1 = propagator.do_propagation(propagation_parameters, FresnelConvolution2D.HANDLER_NAME) elif method == 'fraunhofer': propagation_parameters.set_additional_parameters("shift_half_pixel", True) wf1 = propagator.do_propagation(propagation_parameters, Fraunhofer2D.HANDLER_NAME) elif method == 'zoom': propagation_parameters.set_additional_parameters("shift_half_pixel", True) propagation_parameters.set_additional_parameters("magnification_x", 1.5) propagation_parameters.set_additional_parameters("magnification_y", 2.5) wf1 = propagator.do_propagation(propagation_parameters, FresnelZoomXY2D.HANDLER_NAME) else: raise Exception("Not implemented method: %s"%method) horizontal_profile = wf1.get_intensity()[:, int(wf.size()[1]/2)] horizontal_profile /= horizontal_profile.max() print("FWHM of the horizontal profile: %g um"%(1e6*line_fwhm(horizontal_profile)*wf1.delta()[0])) vertical_profile = wf1.get_intensity()[int(wf1.size()[0]/2),:] vertical_profile /= vertical_profile.max() print("FWHM of the vertical profile: %g um"%(1e6*line_fwhm(vertical_profile)*wf1.delta()[1])) if do_plot: from srxraylib.plot.gol import plot,plot_image plot_image(wf1.get_intensity(),wf1.get_coordinate_x(),wf1.get_coordinate_y(),title='intensity (%s)'%method,show=0) plot_image(wf1.get_phase(),wf1.get_coordinate_x(),wf1.get_coordinate_y(),title='phase (%s)'%method,show=0) plot(wf1.get_coordinate_x(),horizontal_profile, wf1.get_coordinate_y(),vertical_profile, legend=['Horizontal profile','Vertical profile'],title="%s"%method,show=show) print("Output intensity: ",wf1.get_intensity().sum()) return wf1.get_coordinate_x(),horizontal_profile
def test_initializers(self, do_plot=do_plot): print("# ") print("# Tests for initializars (2D) ") print("# ") x = numpy.linspace(-100, 100, 50) y = numpy.linspace(-50, 50, 200) XY = numpy.meshgrid(x, y) X = XY[0].T Y = XY[1].T sigma = 10 Z = numpy.exp(-(X**2 + Y**2) / 2 / sigma**2) * 1j print("Shapes x,y,z: ", x.shape, y.shape, Z.shape) wf0 = GenericWavefront2D.initialize_wavefront_from_steps( x[0], numpy.abs(x[1] - x[0]), y[0], numpy.abs(y[1] - y[0]), number_of_points=Z.shape) wf0.set_complex_amplitude(Z) wf1 = GenericWavefront2D.initialize_wavefront_from_range( x[0], x[-1], y[0], y[-1], number_of_points=Z.shape) wf1.set_complex_amplitude(Z) wf2 = GenericWavefront2D.initialize_wavefront_from_arrays(x, y, Z) if do_plot: from srxraylib.plot.gol import plot_image plot_image(wf0.get_intensity(), wf0.get_coordinate_x(), wf0.get_coordinate_y(), title="initialize_wavefront_from_steps", show=0) plot_image(wf1.get_intensity(), wf1.get_coordinate_x(), wf1.get_coordinate_y(), title="initialize_wavefront_from_range", show=0) plot_image(wf2.get_intensity(), wf2.get_coordinate_x(), wf2.get_coordinate_y(), title="initialize_wavefront_from_arrays", show=1) numpy.testing.assert_almost_equal( numpy.abs(Z)**2, wf0.get_intensity(), 11) numpy.testing.assert_almost_equal( numpy.abs(Z)**2, wf1.get_intensity(), 11) numpy.testing.assert_almost_equal( numpy.abs(Z)**2, wf2.get_intensity(), 11) numpy.testing.assert_almost_equal(x, wf0.get_coordinate_x(), 11) numpy.testing.assert_almost_equal(x, wf1.get_coordinate_x(), 11) numpy.testing.assert_almost_equal(x, wf2.get_coordinate_x(), 11) numpy.testing.assert_almost_equal(y, wf0.get_coordinate_y(), 11) numpy.testing.assert_almost_equal(y, wf1.get_coordinate_y(), 11) numpy.testing.assert_almost_equal(y, wf2.get_coordinate_y(), 11)
def main(mode_wavefront_before_lens): # \ | / # * | | | * # / | \ # <------- d ---------------><--------- d -------> # d is propagation_distance # wavefron names at different positions # wf1 wf2 wf3 wf4 lens_diameter = 0.002 # 0.001 # 0.002 if mode_wavefront_before_lens == 'Undulator with lens': npixels_x = 512 else: npixels_x = int(2048 * 1.5) pixelsize_x = lens_diameter / npixels_x print("pixelsize: ", pixelsize_x) pixelsize_y = pixelsize_x npixels_y = npixels_x wavelength = 1.24e-10 propagation_distance = 30.0 defocus_factor = 1.0 # 1.0 is at focus propagation_steps = 1 # for Gaussian source sigma_x = lens_diameter / 400 # 5e-6 sigma_y = sigma_x # 5e-6 # for Hermite-Gauss, the H and V mode index (start from 0) hm = 3 hn = 1 if mode_wavefront_before_lens == 'convergent spherical': # no need to propagate nor define lens wf3 = GenericWavefront2D.initialize_wavefront_from_range( x_min=-pixelsize_x * npixels_x / 2, x_max=pixelsize_x * npixels_x / 2, y_min=-pixelsize_y * npixels_y / 2, y_max=pixelsize_y * npixels_y / 2, number_of_points=(npixels_x, npixels_y), wavelength=wavelength) wf3.set_spherical_wave(complex_amplitude=1.0, radius=-propagation_distance) elif mode_wavefront_before_lens == 'divergent spherical with lens': # define wavefront at zero distance upstream the lens and apply lens focal_length = propagation_distance / 2. wf2 = GenericWavefront2D.initialize_wavefront_from_range( x_min=-pixelsize_x * npixels_x / 2, x_max=pixelsize_x * npixels_x / 2, y_min=-pixelsize_y * npixels_y / 2, y_max=pixelsize_y * npixels_y / 2, number_of_points=(npixels_x, npixels_y), wavelength=wavelength) wf2.set_spherical_wave(complex_amplitude=1.0, radius=propagation_distance) wf3 = apply_lens(wf2, focal_length) elif mode_wavefront_before_lens == 'plane with lens': # define wavefront at zero distance upstream the lens and apply lens focal_length = propagation_distance wf2 = GenericWavefront2D.initialize_wavefront_from_range( x_min=-pixelsize_x * npixels_x / 2, x_max=pixelsize_x * npixels_x / 2, y_min=-pixelsize_y * npixels_y / 2, y_max=pixelsize_y * npixels_y / 2, number_of_points=(npixels_x, npixels_y), wavelength=wavelength) wf2.set_plane_wave_from_complex_amplitude(1.0 + 0j) wf3 = apply_lens(wf2, focal_length) elif mode_wavefront_before_lens == 'Gaussian with lens': # define wavefront at source point, propagate to the lens and apply lens wf1 = GenericWavefront2D.initialize_wavefront_from_range( x_min=-pixelsize_x * npixels_x / 2, x_max=pixelsize_x * npixels_x / 2, y_min=-pixelsize_y * npixels_y / 2, y_max=pixelsize_y * npixels_y / 2, number_of_points=(npixels_x, npixels_y), wavelength=wavelength) X = wf1.get_mesh_x() Y = wf1.get_mesh_y() intensity = numpy.exp(-X**2 / (2 * sigma_x**2)) * numpy.exp(-Y**2 / (2 * sigma_y**2)) wf1.set_complex_amplitude(numpy.sqrt(intensity)) # plot plot_image(wf1.get_intensity(), 1e6 * wf1.get_coordinate_x(), 1e6 * wf1.get_coordinate_y(), xtitle="X um", ytitle="Y um", title="Gaussian source", show=1) wf2, x2, h2 = propagation_in_vacuum( wf1, propagation_distance=propagation_distance) plot_image(wf2.get_intensity(), 1e6 * wf2.get_coordinate_x(), 1e6 * wf2.get_coordinate_y(), xtitle="X um", ytitle="Y um", title="Before lens fft", show=1) focal_length = propagation_distance / 2 wf3 = apply_lens(wf2, focal_length) elif mode_wavefront_before_lens == 'Hermite with lens': # define wavefront at source point, propagate to the lens and apply lens wf1 = GenericWavefront2D.initialize_wavefront_from_range( x_min=-pixelsize_x * npixels_x / 2, x_max=pixelsize_x * npixels_x / 2, y_min=-pixelsize_y * npixels_y / 2, y_max=pixelsize_y * npixels_y / 2, number_of_points=(npixels_x, npixels_y), wavelength=wavelength) X = wf1.get_mesh_x() Y = wf1.get_mesh_y() efield = (hermite(hm)(numpy.sqrt(2)*X/sigma_x)*numpy.exp(-X**2/sigma_x**2))**2 \ * (hermite(hn)(numpy.sqrt(2)*Y/sigma_y)*numpy.exp(-Y**2/sigma_y**2))**2 wf1.set_complex_amplitude(efield) # plot plot_image(wf1.get_intensity(), 1e6 * wf1.get_coordinate_x(), 1e6 * wf1.get_coordinate_y(), xtitle="X um", ytitle="Y um", title="Hermite-Gauss source", show=1) wf2, x2, h2 = propagation_in_vacuum(wf1, propagation_distance=30.0, defocus_factor=1.0, propagation_steps=1) plot_image(wf2.get_intensity(), 1e6 * wf2.get_coordinate_x(), 1e6 * wf2.get_coordinate_y(), xtitle="X um", ytitle="Y um", title="Before lens %s" % USE_PROPAGATOR, show=1) wf3 = apply_lens(wf2, focal_length=propagation_distance / 2) elif mode_wavefront_before_lens == 'Undulator with lens': beamline = {} # beamline['name'] = "ESRF_NEW_OB" # beamline['ElectronBeamDivergenceH'] = 5.2e-6 # these values are not used (zero emittance) # beamline['ElectronBeamDivergenceV'] = 1.4e-6 # these values are not used (zero emittance) # beamline['ElectronBeamSizeH'] = 27.2e-6 # these values are not used (zero emittance) # beamline['ElectronBeamSizeV'] = 3.4e-6 # these values are not used (zero emittance) # beamline['ElectronEnergySpread'] = 0.001 # these values are not used (zero emittance) beamline['ElectronCurrent'] = 0.2 beamline['ElectronEnergy'] = 6.0 beamline['Kv'] = 1.68 # 1.87 beamline['NPeriods'] = 111 # 14 beamline['PeriodID'] = 0.018 # 0.035 beamline['distance'] = propagation_distance # beamline['gapH'] = pixelsize_x*npixels_x # beamline['gapV'] = pixelsize_x*npixels_x gamma = beamline['ElectronEnergy'] / (codata_mee * 1e-3) print("Gamma: %f \n" % (gamma)) resonance_wavelength = ( 1 + beamline['Kv']**2 / 2.0) / 2 / gamma**2 * beamline["PeriodID"] resonance_energy = m2ev / resonance_wavelength print("Resonance wavelength [A]: %g \n" % (1e10 * resonance_wavelength)) print("Resonance energy [eV]: %g \n" % (resonance_energy)) # red shift 100 eV resonance_energy = resonance_energy - 100 myBeam = ElectronBeam(Electron_energy=beamline['ElectronEnergy'], I_current=beamline['ElectronCurrent']) myUndulator = MagneticStructureUndulatorPlane( K=beamline['Kv'], period_length=beamline['PeriodID'], length=beamline['PeriodID'] * beamline['NPeriods']) wf2 = GenericWavefront2D.initialize_wavefront_from_range( x_min=-pixelsize_x * npixels_x / 2, x_max=pixelsize_x * npixels_x / 2, y_min=-pixelsize_y * npixels_y / 2, y_max=pixelsize_y * npixels_y / 2, number_of_points=(npixels_x, npixels_y), wavelength=wavelength) XX = wf2.get_mesh_x() YY = wf2.get_mesh_y() X = wf2.get_coordinate_x() Y = wf2.get_coordinate_y() source = SourceUndulatorPlane(undulator=myUndulator, electron_beam=myBeam, magnetic_field=None) omega = resonance_energy * codata.e / codata.hbar Nb_pts_trajectory = int( source.choose_nb_pts_trajectory(0.01, photon_frequency=omega)) print("Number of trajectory points: ", Nb_pts_trajectory) traj_fact = TrajectoryFactory(Nb_pts=Nb_pts_trajectory, method=TRAJECTORY_METHOD_ODE, initial_condition=None) print("Number of trajectory points: ", traj_fact.Nb_pts) if (traj_fact.initial_condition == None): traj_fact.initial_condition = source.choose_initial_contidion_automatic( ) print("Number of trajectory points: ", traj_fact.Nb_pts, traj_fact.initial_condition) rad_fact = RadiationFactory(method=RADIATION_METHOD_NEAR_FIELD, photon_frequency=omega) #print('step 3') trajectory = traj_fact.create_from_source(source=source) #print('step 4') radiation = rad_fact.create_for_one_relativistic_electron( trajectory=trajectory, source=source, XY_are_list=False, distance=beamline['distance'], X=X, Y=Y) efield = rad_fact.calculate_electrical_field( trajectory=trajectory, source=source, distance=beamline['distance'], X_array=XX, Y_array=YY) tmp = efield.electrical_field()[:, :, 0] wf2.set_photon_energy(resonance_energy) wf2.set_complex_amplitude(tmp) # plot plot_image(wf2.get_intensity(), 1e6 * wf2.get_coordinate_x(), 1e6 * wf2.get_coordinate_y(), xtitle="X um", ytitle="Y um", title="UND source at lens plane", show=1) # apply lens focal_length = propagation_distance / 2 wf3 = apply_lens(wf2, focal_length=focal_length) else: raise Exception("Unknown mode") plot_image(wf3.get_phase(), 1e6 * wf3.get_coordinate_x(), 1e6 * wf3.get_coordinate_y(), title="Phase just after the lens %s" % USE_PROPAGATOR, xtitle="X um", ytitle="Y um", show=1) wf4, x4, h4 = propagation_in_vacuum( wf3, propagation_distance=propagation_distance, defocus_factor=1.0, propagation_steps=1) plot_image(wf4.get_intensity(), 1e6 * wf4.get_coordinate_x(), 1e6 * wf4.get_coordinate_y(), title="Intensity at focal point %s" % USE_PROPAGATOR, xtitle="X um", ytitle="Y um", show=1) plot(1e4 * x4, h4, xtitle='x [um]', ytitle='intensity', title='horizontal profile', show=True)
if __name__ == "__main__": from json_tools import load_from_json_file from wofry.propagator.wavefront2D.generic_wavefront import GenericWavefront2D from srxraylib.plot.gol import plot_image from wofry.propagator.propagator import PropagationManager, PropagationElements, PropagationParameters from wofryimpl.propagator.propagators2D.fresnel_zoom_xy import FresnelZoomXY2D wfr = GenericWavefront2D.load_h5_file("source.h5", "wfr") plot_image(wfr.get_intensity(), 1e6 * wfr.get_coordinate_x(), 1e6 * wfr.get_coordinate_y(), title="Source", xtitle="X [um]", ytitle="Y [um]") bl = load_from_json_file("beamline.json") # # propagate elements using Fresnel Zoom propagator # magnification_x = [1, 1, 0.01, 440, 1, 1, 1, 0.00007] magnification_y = [1, 1, 1, 5, 1, 0.5, 1, 0.00009] # define propagator to be used propagator = PropagationManager.Instance() try: propagator.add_propagator(FresnelZoomXY2D()) except:
def test_spherical_wave(self, do_plot=do_plot): # # plane wave # print("# ") print("# Tests for a 2D spherical wave ") print("# ") wavelength = 1.24e-10 wavefront_length_x = 400e-6 wavefront_length_y = wavefront_length_x npixels_x = 1024 npixels_y = npixels_x x = numpy.linspace(-0.5 * wavefront_length_x, 0.5 * wavefront_length_x, npixels_x) y = numpy.linspace(-0.5 * wavefront_length_y, 0.5 * wavefront_length_y, npixels_y) wf1 = GenericWavefront2D.initialize_wavefront_from_steps( x_start=x[0], x_step=numpy.abs(x[1] - x[0]), y_start=y[0], y_step=numpy.abs(y[1] - y[0]), number_of_points=(npixels_x, npixels_y), wavelength=wavelength) numpy.testing.assert_almost_equal(x, wf1.get_coordinate_x(), 9) numpy.testing.assert_almost_equal(y, wf1.get_coordinate_y(), 9) wf2 = GenericWavefront2D.initialize_wavefront_from_steps( x_start=x[0], x_step=numpy.abs(x[1] - x[0]), y_start=y[0], y_step=numpy.abs(y[1] - y[0]), number_of_points=(npixels_x, npixels_y), wavelength=wavelength) numpy.testing.assert_almost_equal(x, wf2.get_coordinate_x(), 9) numpy.testing.assert_almost_equal(y, wf2.get_coordinate_y(), 9) # an spherical wavefront is obtained 1) by creation, 2) focusing a planewave wf1.set_spherical_wave(-5.0, 3 + 0j) wf1.clip_square(-50e-6, 10e-6, -20e-6, 40e-6) wf2.set_plane_wave_from_complex_amplitude(3 + 0j) ideal_lens = WOIdealLens("test", 5.0, 5.0) ideal_lens.applyOpticalElement(wf2) wf2.clip_square(-50e-6, 10e-6, -20e-6, 40e-6) if do_plot: from srxraylib.plot.gol import plot_image plot_image(wf1.get_phase(), wf2.get_coordinate_x(), wf2.get_coordinate_y(), title="Phase of spherical wavefront", show=0) plot_image(wf2.get_phase(), wf2.get_coordinate_x(), wf2.get_coordinate_y(), title="Phase of focused plane wavefront", show=0) plot_image( wf1.get_phase(from_minimum_intensity=0.1), wf2.get_coordinate_x(), wf2.get_coordinate_y(), title="Phase of spherical wavefront (for intensity > 0.1)", show=0) plot_image( wf2.get_phase(from_minimum_intensity=0.1), wf2.get_coordinate_x(), wf2.get_coordinate_y(), 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 write_file(self): self.setStatusMessage("") try: if not self.af is None: congruence.checkDir(self.file_name) if self.TYPE_OF_OUTPUT == 0: # ['COMSYL hdf5 with multi-mode','WOFRY hdf5 with multi-mode','WOFRY multiple files' if self.ALL_MODES: self.af.write_h5(self.file_name, maximum_number_of_modes=None) else: self.af.write_h5(self.file_name, maximum_number_of_modes=self.MODE_TO) path, file_name = os.path.split(self.file_name) self.setStatusMessage("File Out: " + file_name) else: # WOFRY if self.ALL_MODES == 0 and (self.MODE_TO < self.af.number_of_modes()): nmax = self.MODE_TO else: nmax = self.af.number_of_modes() for i in range(nmax + 1): eigenvalue = numpy.real(self.af.eigenvalue(i), ) eigenfunction = self.af.mode(i) w = GenericWavefront2D.initialize_wavefront_from_arrays( self.af.x_coordinates(), self.af.y_coordinates(), eigenfunction * numpy.sqrt(eigenvalue)) w.set_photon_energy(self.af.photon_energy()) if self.TYPE_OF_OUTPUT == 1: # file_name = self.file_name subgroupname = "mode" + self.index_format % (i) overwrite = False elif self.TYPE_OF_OUTPUT == 2: subgroupname = "mode" + self.index_format % (i) file_name = self.file_name.split(".")[0] + "_" + ( self.index_format % i) + ".h5" overwrite = True if i == 0: w.save_h5_file(file_name, subgroupname=subgroupname, intensity=True, phase=True, overwrite=True) else: w.save_h5_file(file_name, subgroupname=subgroupname, intensity=True, phase=True, overwrite=overwrite) path, file_name = os.path.split(file_name) self.setStatusMessage("File Out: " + file_name) # path, file_name = os.path.split(self.file_name) # self.setStatusMessage("File Out: " + file_name) else: QMessageBox.critical(self, "Error", "COMSYL modes not present", QMessageBox.Ok) except Exception as exception: QMessageBox.critical(self, "Error", str(exception), QMessageBox.Ok)
def propagate_wavefront(cls, wavefront1, propagation_distance, magnification_x=1.0, magnification_y=1.0, shift_half_pixel=False): wavefront = wavefront1.duplicate() wavelength = wavefront.get_wavelength() wavenumber = wavefront.get_wavenumber() shape = wavefront.size() delta = wavefront.delta() # frequency for axis 1 pixelsize = delta[0] npixels = shape[0] freq_nyquist = 0.5 / pixelsize freq_n = numpy.linspace(-1.0, 1.0, npixels) freq_x0 = freq_n * freq_nyquist freq_x1 = numpy.fft.fftfreq(npixels, pixelsize) freq_x1 = numpy.fft.ifftshift(freq_x1) # frequency for axis 2 pixelsize = delta[1] npixels = shape[1] freq_nyquist = 0.5 / pixelsize freq_n = numpy.linspace(-1.0, 1.0, npixels) freq_y0 = freq_n * freq_nyquist freq_y1 = numpy.fft.fftfreq(npixels, pixelsize) freq_y1 = numpy.fft.ifftshift(freq_y1) print(freq_x0[0:10], freq_x1[0:10]) # It happens that with method=0 (old) the propagation of a centro-symmetric beam # is not longer center but shifted. # This is due to "shifted" storage of the frequencies that is dependent on the # even or odd number of pixels. # It seems that with the new method (method=1) the beam is center. # Note: The new method ignores the shift_half_pixel keyword # See also doscussion with V. Favre-Nicolin email to srio on 2018-05-02 method = 1 # 0-old, 1-new if method == 0: freq_x = freq_x0 freq_y = freq_y0 if shift_half_pixel: freq_x = freq_x - 0.5 * numpy.abs(freq_x[1] - freq_x[0]) freq_y = freq_y - 0.5 * numpy.abs(freq_y[1] - freq_y[0]) else: freq_x = freq_x1 freq_y = freq_y1 f_x, f_y = numpy.meshgrid(freq_x, freq_y, indexing='ij') fsq = numpy.fft.fftshift(f_x**2 / magnification_x + f_y**2 / magnification_y) x = wavefront.get_mesh_x() y = wavefront.get_mesh_y() x_rescaling = wavefront.get_mesh_x() * magnification_x y_rescaling = wavefront.get_mesh_y() * magnification_y r1sq = x**2 * (1 - magnification_x) + y**2 * (1 - magnification_y) r2sq = x_rescaling**2 * ( (magnification_x - 1) / magnification_x) + y_rescaling**2 * ( (magnification_y - 1) / magnification_y) 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.fft2(wavefront.get_complex_amplitude()) ifft = numpy.fft.ifft2(fft * Q2) * Q3 / numpy.sqrt( magnification_x * magnification_y) wf_propagated = GenericWavefront2D.initialize_wavefront_from_arrays( x_array=wavefront.get_coordinate_x() * magnification_x, y_array=wavefront.get_coordinate_y() * magnification_y, z_array=ifft, wavelength=wavelength) return wf_propagated
def propagate_wavefront(cls,wavefront,propagation_distance,shuffle_interval=False,calculate_grid_only=True): # # Fresnel-Kirchhoff integral (neglecting inclination factor) # if not calculate_grid_only: # # calculation over the whole detector area # p_x = wavefront.get_coordinate_x() p_y = wavefront.get_coordinate_y() wavelength = wavefront.get_wavelength() amplitude = wavefront.get_complex_amplitude() det_x = p_x.copy() det_y = p_y.copy() p_X = wavefront.get_mesh_x() p_Y = wavefront.get_mesh_y() det_X = p_X det_Y = p_Y amplitude_propagated = numpy.zeros_like(amplitude,dtype='complex') wavenumber = 2 * numpy.pi / wavelength for i in range(det_x.size): for j in range(det_y.size): if not shuffle_interval: rd_x = 0.0 rd_y = 0.0 else: rd_x = (numpy.random.rand(p_x.size,p_y.size)-0.5)*shuffle_interval rd_y = (numpy.random.rand(p_x.size,p_y.size)-0.5)*shuffle_interval r = numpy.sqrt( numpy.power(p_X + rd_x - det_X[i,j],2) + numpy.power(p_Y + rd_y - det_Y[i,j],2) + numpy.power(propagation_distance,2) ) amplitude_propagated[i,j] = (amplitude / r * numpy.exp(1.j * wavenumber * r)).sum() output_wavefront = GenericWavefront2D.initialize_wavefront_from_arrays(det_x,det_y,amplitude_propagated) else: x = wavefront.get_coordinate_x() y = wavefront.get_coordinate_y() X = wavefront.get_mesh_x() Y = wavefront.get_mesh_y() wavenumber = 2 * numpy.pi / wavefront.get_wavelength() amplitude = wavefront.get_complex_amplitude() used_indices = wavefront.get_mask_grid(width_in_pixels=(1,1),number_of_lines=(1,1)) indices_x = wavefront.get_mesh_indices_x() indices_y = wavefront.get_mesh_indices_y() indices_x_flatten = indices_x[numpy.where(used_indices == 1)].flatten() indices_y_flatten = indices_y[numpy.where(used_indices == 1)].flatten() X_flatten = X[numpy.where(used_indices == 1)].flatten() Y_flatten = Y[numpy.where(used_indices == 1)].flatten() complex_amplitude_propagated = amplitude*0 print("propagate_2D_integral: Calculating %d points from a total of %d x %d = %d"%( X_flatten.size,amplitude.shape[0],amplitude.shape[1],amplitude.shape[0]*amplitude.shape[1])) for i in range(X_flatten.size): r = numpy.sqrt( numpy.power(wavefront.get_mesh_x() - X_flatten[i],2) + numpy.power(wavefront.get_mesh_y() - Y_flatten[i],2) + numpy.power(propagation_distance,2) ) complex_amplitude_propagated[int(indices_x_flatten[i]),int(indices_y_flatten[i])] = (amplitude / r * numpy.exp(1.j * wavenumber * r)).sum() output_wavefront = GenericWavefront2D.initialize_wavefront_from_arrays(x_array=x, y_array=y, z_array=complex_amplitude_propagated, wavelength=wavefront.get_wavelength()) # added [email protected] 2018-03-23 to conserve energy - TODO: review method! output_wavefront.rescale_amplitude( numpy.sqrt(wavefront.get_intensity().sum() / output_wavefront.get_intensity().sum())) return output_wavefront
def propagate_wavefront(cls, wavefront1, propagation_distance, magnification_x=1.0, magnification_y=1.0, shift_half_pixel=False): wavefront = wavefront1.duplicate() wavelength = wavefront.get_wavelength() wavenumber = wavefront.get_wavenumber() shape = wavefront.size() delta = wavefront.delta() pixelsize = delta[0] npixels = shape[0] freq_nyquist = 0.5 / pixelsize freq_n = numpy.linspace(-1.0, 1.0, npixels) freq_x = freq_n * freq_nyquist # frequency for axis 2 pixelsize = delta[1] npixels = shape[1] freq_nyquist = 0.5 / pixelsize freq_n = numpy.linspace(-1.0, 1.0, npixels) freq_y = freq_n * freq_nyquist if shift_half_pixel: freq_x = freq_x - 0.5 * numpy.abs(freq_x[1] - freq_x[0]) freq_y = freq_y - 0.5 * numpy.abs(freq_y[1] - freq_y[0]) f_x, f_y = numpy.meshgrid(freq_x, freq_y, indexing='ij') fsq = numpy.fft.fftshift(f_x**2 / magnification_x + f_y**2 / magnification_y) x = wavefront.get_mesh_x() y = wavefront.get_mesh_y() x_rescaling = wavefront.get_mesh_x() * magnification_x y_rescaling = wavefront.get_mesh_y() * magnification_y r1sq = x**2 * (1 - magnification_x) + y**2 * (1 - magnification_y) r2sq = x_rescaling**2 * ( (magnification_x - 1) / magnification_x) + y_rescaling**2 * ( (magnification_y - 1) / magnification_y) 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.fft2(wavefront.get_complex_amplitude()) ifft = numpy.fft.ifft2(fft * Q2) * Q3 / numpy.sqrt( magnification_x * magnification_y) wf_propagated = GenericWavefront2D.initialize_wavefront_from_arrays( x_array=wavefront.get_coordinate_x() * magnification_x, y_array=wavefront.get_coordinate_y() * magnification_y, z_array=ifft, wavelength=wavelength) return wf_propagated
def test_interpolator(self, do_plot=do_plot): # # interpolator # print("# ") print("# Tests for 2D interpolator ") print("# ") x = numpy.linspace(-10, 10, 100) y = numpy.linspace(-20, 20, 50) xy = numpy.meshgrid(x, y) X = xy[0].T Y = xy[1].T sigma = 3.0 Z = 3 * numpy.exp(-(X**2 + Y**2) / 2 / sigma**2) + 4j print("shape of Z", Z.shape) wf = GenericWavefront2D.initialize_wavefront_from_steps( x[0], x[1] - x[0], y[0], y[1] - y[0], number_of_points=(100, 50)) print("wf shape: ", wf.size()) print("wf polarized: ", wf.is_polarized()) wf.set_complex_amplitude(Z) x1 = 3.2 y1 = -2.5 z1 = 3 * numpy.exp(-(x1**2 + y1**2) / 2 / sigma**2) + 4j print("complex ampl at (%g,%g): %g+%gi (exact=%g+%gi)" % (x1, y1, wf.get_interpolated_complex_amplitude( x1, y1).real, wf.get_interpolated_complex_amplitude( x1, y1).imag, z1.real, z1.imag)) self.assertAlmostEqual( wf.get_interpolated_complex_amplitude(x1, y1).real, z1.real, 4) self.assertAlmostEqual( wf.get_interpolated_complex_amplitude(x1, y1).imag, z1.imag, 4) # print( "intensity at (%g,%g): %g (exact=%g)" % (x1, y1, wf.get_interpolated_intensity(x1, y1), numpy.abs(z1)**2)) self.assertAlmostEqual(wf.get_interpolated_intensity(x1, y1), numpy.abs(z1)**2, 3) # interpolate on same grid interpolated_complex_amplitude_on_same_grid = wf.get_interpolated_complex_amplitudes( X, Y) print("Shape interpolated at same grid: ", interpolated_complex_amplitude_on_same_grid.shape) numpy.testing.assert_array_almost_equal( wf.get_complex_amplitude(), interpolated_complex_amplitude_on_same_grid, 4) print( "Total intensity original wavefront: %g, interpolated on the same grid: %g" % (wf.get_intensity().sum(), (numpy.abs(interpolated_complex_amplitude_on_same_grid)** 2).sum())) if do_plot: from srxraylib.plot.gol import plot_image plot_image(wf.get_intensity(), wf.get_coordinate_x(), wf.get_coordinate_y(), title="Original", show=0) plot_image(wf.get_interpolated_intensity(X, Y), wf.get_coordinate_x(), wf.get_coordinate_y(), title="interpolated on same grid", show=1) # rebin wavefront # wf.set_plane_wave_from_complex_amplitude(3+4j) wf_rebin = wf.rebin(2.0, 5.0, 0.5, 0.8, keep_the_same_intensity=1, set_extrapolation_to_zero=1) print("Shape before rebinning: ", wf.size()) print("Shape after rebinning: ", wf_rebin.size()) print("Total intensity original wavefront: %g, rebinned: %g" % (wf.get_intensity().sum(), wf_rebin.get_intensity().sum())) if do_plot: from srxraylib.plot.gol import plot_image plot_image(wf.get_intensity(), wf.get_coordinate_x(), wf.get_coordinate_y(), title="BEFORE REBINNING", show=0) plot_image(wf_rebin.get_intensity(), wf_rebin.get_coordinate_x(), wf_rebin.get_coordinate_y(), title="REBINNED", show=1)