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 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 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 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 get_wavefront(self): # # If making changes here, don't forget to do changes in to_python_code() as well... # if self._initialize_from == 0: if self._dimension == 1: wf = GenericWavefront1D.initialize_wavefront_from_range( x_min=self._range_from_h, x_max=self._range_to_h, number_of_points=self._number_of_points_h) elif self._dimension == 2: wf = GenericWavefront2D.initialize_wavefront_from_range( x_min=self._range_from_h, x_max=self._range_to_h, y_min=self._range_from_v, y_max=self._range_to_v, number_of_points=(self._number_of_points_h, self._number_of_points_v)) else: if self._dimension == 1: wf = GenericWavefront1D.initialize_wavefront_from_steps( x_start=self._steps_start_h, x_step=self._steps_step_h, number_of_points=self._number_of_points_h) elif self._dimension == 2: wf = GenericWavefront2D.initialize_wavefront_from_steps( x_start=self._steps_start_h, x_step=self._steps_step_h, y_start=self._steps_start_v, y_step=self._steps_step_v, number_of_points=(self._number_of_points_h, self._number_of_points_v)) if self._units == 0: wf.set_photon_energy(self._energy) else: wf.set_wavelength(self._wavelength) if self._kind_of_wave == 0: # plane if self._dimension == 1: if self._initialize_amplitude == 0: wf.set_plane_wave_from_complex_amplitude( complex_amplitude=complex(self._complex_amplitude_re, self._complex_amplitude_im), inclination=self._inclination) else: wf.set_plane_wave_from_amplitude_and_phase( amplitude=self._amplitude, phase=self._phase, inclination=self._inclination) elif self._dimension == 2: if self._initialize_amplitude == 0: wf.set_plane_wave_from_complex_amplitude( complex_amplitude=complex(self._complex_amplitude_re, self._complex_amplitude_im)) else: wf.set_plane_wave_from_amplitude_and_phase( amplitude=self._amplitude, phase=self._phase) elif self._kind_of_wave == 1: # spheric if self._dimension == 1: wf.set_spherical_wave(radius=self._radius, center=self._center, complex_amplitude=complex( self._complex_amplitude_re, self._complex_amplitude_im)) elif self._dimension == 2: wf.set_spherical_wave(radius=self._radius, complex_amplitude=complex( self._complex_amplitude_re, self._complex_amplitude_im)) elif self._kind_of_wave == 2: # gaussian if self._dimension == 1: wf.set_gaussian(sigma_x=self._sigma_h, amplitude=self._amplitude, shift=self._gaussian_shift) elif self._dimension == 2: wf.set_gaussian(sigma_x=self._sigma_h, sigma_y=self._sigma_v, amplitude=self._amplitude) elif self._kind_of_wave == 3: # g.s.m. if self._dimension == 1: wf.set_gaussian_hermite_mode( sigma_x=self._sigma_h, mode_x=self._n_h, amplitude=self._amplitude, beta=self._beta_h, shift=self._gaussian_shift, ) elif self._dimension == 2: wf.set_gaussian_hermite_mode( sigma_x=self._sigma_h, sigma_y=self._sigma_v, amplitude=self._amplitude, nx=self._n_h, ny=self._n_v, betax=self._beta_h, betay=self._beta_v, ) if self._add_random_phase: wf.add_phase_shifts(2 * numpy.pi * numpy.random.random(wf.size())) return wf
(-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(
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 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 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 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
intensity_total = I.sum() * (x[1] - x[0]) * (y[1] - y[0]) intensity_peak = I.max() return fwhm_x, fwhm_y, intensity_total, intensity_at_center, intensity_peak, I, x, y if __name__ == "__main__": from wofry.propagator.wavefront2D.generic_wavefront import GenericWavefront2D sc = Tally2D(scan_variable_name='mode index', additional_stored_variable_names=['a', 'b'], do_store_wavefronts=False) for xmode in range(5): output_wavefront = GenericWavefront2D.initialize_wavefront_from_range( x_min=-0.00012, x_max=0.00012, y_min=-5e-05, y_max=5e-05, number_of_points=(400, 200)) output_wavefront.set_photon_energy(7000) output_wavefront.set_gaussian_hermite_mode(sigma_x=3.00818e-05, sigma_y=6.99408e-06, amplitude=1, nx=xmode, ny=0, betax=0.129748, betay=1.01172) sc.append(output_wavefront, scan_variable_value=xmode, additional_stored_values=[1, 2.1])
pixelsize_y = 1e-7 npixels_x = 2024 npixels_y = 2024 propagation_distance = 1.0 show = 1 method_label = "fresnel (fft)" print("\n# ") print("# 2D near field fresnel (%s) diffraction from a a circular stop " % (method_label)) print("# ") 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)) wf.clip_circle(aperture_diameter / 2, negative=True) plot_image(wf.get_intensity(), 1e6 * wf.get_coordinate_x(), 1e6 * wf.get_coordinate_y(), title="intensity at screen/aperture plane, Diameter=%5.1f um" % (1e6 * aperture_diameter), xtitle="X [um]", ytitle="Y [um]",
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_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)