def test_1d_gaussian_slope_error(self): mirror_length=200.0 step=1.0 rms_slopes=1.3e-7 rms_heights = 1e-7 correlation_length = 10.0 x, f = simulate_profile_1D_gaussian(step=step, \ mirror_length=mirror_length, \ rms_heights=rms_heights, \ correlation_length=correlation_length,\ renormalize_to_slopes_sd=None) slopes = numpy.gradient(f, x[1]-x[0]) print("test_1d_gaussian: test function: %s, Stdev (not normalized): HEIGHTS=%g.SLOPES=%g"%("test_1d_gaussian_slope_error",f.std(),slopes.std())) x, f = simulate_profile_1D_gaussian(step=step, \ mirror_length=mirror_length, \ rms_heights=rms_heights, \ correlation_length=correlation_length,\ renormalize_to_slopes_sd=rms_slopes) slopes = numpy.gradient(f, x[1]-x[0]) print("test_1d_gaussian: test function: %s, SLOPES Stdev (normalized to %g)=%g"%("test_1d_gaussian_slope_error",rms_slopes,slopes.std())) assert numpy.abs( rms_slopes - slopes.std() ) < 0.01 * numpy.abs(rms_slopes) if do_plot: from srxraylib.plot.gol import plot plot(x,slopes,title="test_1d_gaussian_slope_error",xtitle="Y",ytitle="slopes Z'")
def propagate_1D(self,do_plot=do_plot,method='fft', wavelength=1.24e-10,aperture_type='square',aperture_diameter=40e-6, wavefront_length=100e-6,npoints=500, propagation_distance = 30.0,show=1): print("\n# ") print("# far field 1D (fraunhofer) diffraction from a %s aperture "%aperture_type) print("# ") wf = Wavefront1D.initialize_wavefront_from_range(x_min=-wavefront_length/2, x_max=wavefront_length/2, number_of_points=npoints,wavelength=wavelength) wf.set_plane_wave_from_complex_amplitude((2.0+1.0j)) # an arbitraty value if aperture_type == 'square': wf.apply_slit(-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 method == 'fft': wf1 = propagate_1D_fresnel(wf, propagation_distance) elif method == 'convolution': wf1 = propagate_1D_fresnel_convolution(wf, propagation_distance) elif method == 'integral': wf1 = propagate_1D_integral(wf, propagation_distance) elif method == 'fraunhofer': wf1 = propagate_1D_fraunhofer(wf, propagation_distance) else: raise Exception("Not implemented method: %s"%method) # get the theoretical value angle_x = wf1.get_abscissas() / 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() intensity_calculated /= intensity_calculated.max() if do_plot: from srxraylib.plot.gol import plot plot(wf1.get_abscissas()*1e6/propagation_distance,intensity_calculated, angle_x*1e6,intensity_theory, legend=["%s "%method,"Theoretical (far field)"], legend_position=(0.95, 0.95), title="1D (%s) diffraction from a %s aperture of %3.1f um at wavelength of %3.1f A"% (method,aperture_type,aperture_diameter*1e6,wavelength*1e10), xtitle="X (urad)", ytitle="Intensity",xrange=[-20,20], show=show) return wf1.get_abscissas()/propagation_distance,intensity_calculated,intensity_theory
def showModeDistribution(self): try: from srxraylib.plot.gol import plot y = (self.modeDistribution()).real x = np.arange(y.shape[0]) plot(x, y, title = "Mode distribution", xtitle = "Mode index", ytitle = "Occupancy") except: pass
def propagation_to_image(wf,do_plot=do_plot,plot_title="Before lens",method='fft', 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 print("Incident intensity: ",wf.get_intensity().sum()) # propagation downstream the lens to image plane for i in range(propagation_steps): if propagation_steps > 1: print(">>> Propagating step %d of %d; propagation_distance=%g m"%(i+1,propagation_steps, propagation_distance*defocus_factor/propagation_steps)) if method == 'fft': wf = propagate_2D_fresnel(wf, propagation_distance*defocus_factor/propagation_steps) elif method == 'convolution': wf = propagate_2D_fresnel_convolution(wf, propagation_distance*defocus_factor/propagation_steps) elif method == 'srw': wf = propagate_2D_fresnel_srw(wf, propagation_distance*defocus_factor/propagation_steps) elif method == 'fraunhofer': wf = propagate_2D_fraunhofer(wf, propagation_distance*defocus_factor/propagation_steps) else: raise Exception("Not implemented method: %s"%method) horizontal_profile = wf.get_intensity()[:,wf.size()[1]/2] horizontal_profile /= horizontal_profile.max() print("FWHM of the horizontal profile: %g um"%(1e6*line_fwhm(horizontal_profile)*wf.delta()[0])) vertical_profile = wf.get_intensity()[wf.size()[0]/2,:] vertical_profile /= vertical_profile.max() print("FWHM of the vertical profile: %g um"%(1e6*line_fwhm(vertical_profile)*wf.delta()[1])) if do_plot: from srxraylib.plot.gol import plot,plot_image plot_image(wf.get_intensity(),1e6*wf.get_coordinate_x(),1e6*wf.get_coordinate_y(), xtitle="X um",ytitle="Y um",title='intensity (%s)'%method,show=0) # plot_image(wf.get_amplitude(),wf.get_coordinate_x(),wf.get_coordinate_y(),title='amplitude (%s)'%method,show=0) plot_image(wf.get_phase(),1e6*wf.get_coordinate_x(),1e6*wf.get_coordinate_y(), xtitle="X um",ytitle="Y um",title='phase (%s)'%method,show=0) plot(wf.get_coordinate_x(),horizontal_profile, wf.get_coordinate_y(),vertical_profile, legend=['Horizontal profile','Vertical profile'],title="%s %s"%(plot_title,method),show=show) print("Output intensity: ",wf.get_intensity().sum()) return wf,wf.get_coordinate_x(),horizontal_profile
def test_plane_wave(self,do_plot=do_plot): # # plane wave # print("# ") print("# Tests for a 1D plane wave ") print("# ") wavelength = 1.24e-10 wavefront_length_x = 400e-6 npixels_x = 1024 wavefront_x = numpy.linspace(-0.5*wavefront_length_x,0.5*wavefront_length_x,npixels_x) wavefront = Wavefront1D.initialize_wavefront_from_steps( x_start=wavefront_x[0],x_step=numpy.abs(wavefront_x[1]-wavefront_x[0]), number_of_points=npixels_x,wavelength=wavelength) numpy.testing.assert_almost_equal(wavefront_x,wavefront.get_abscissas(),9) # possible modifications wavefront.set_plane_wave_from_amplitude_and_phase(5.0,numpy.pi/2) numpy.testing.assert_almost_equal(wavefront.get_intensity(),25,5) wavefront.set_plane_wave_from_complex_amplitude(2.0+3j) numpy.testing.assert_almost_equal(wavefront.get_intensity(),13,5) phase_before = wavefront.get_phase() wavefront.add_phase_shift(numpy.pi/2) phase_after = wavefront.get_phase() numpy.testing.assert_almost_equal(phase_before+numpy.pi/2,phase_after,5) intensity_before = wavefront.get_intensity() wavefront.rescale_amplitude(10.0) intensity_after = wavefront.get_intensity() numpy.testing.assert_almost_equal(intensity_before*100,intensity_after,5) # interpolation wavefront.set_plane_wave_from_complex_amplitude(2.0+3j) test_value1 = wavefront.get_interpolated_complex_amplitude(0.01) self.assertAlmostEqual( (2.0+3j).real, test_value1.real, 5) self.assertAlmostEqual( (2.0+3j).imag, test_value1.imag, 5) if do_plot: from srxraylib.plot.gol import plot plot(wavefront.get_abscissas(),wavefront.get_intensity(),title="Intensity (plane wave)",show=0) plot(wavefront.get_abscissas(),wavefront.get_phase(),title="Phase (plane wave)",show=1)
def test_1d_fractal_slope_error(self): mirror_length=200.0 step=1.0 rms=3e-6 x, f = simulate_profile_1D_fractal(step=step,mirror_length=mirror_length, renormalize_to_slopes_sd=rms) slopes = numpy.gradient(f, x[1]-x[0]) print("%s, SLOPES Stdev: input=%g, obtained=%g"%("test_1d_fractal_slope_error",rms,slopes.std())) assert numpy.abs( rms - slopes.std() ) < 0.01 * numpy.abs(rms) if do_plot: from srxraylib.plot.gol import plot plot(x,slopes,title="test_1d_fractal_slope_error",xtitle="Y",ytitle="slopes Z'")
def test_1d_fractal_figure_error(self): mirror_length=200.0 step=1.0 rms=1.25e-7 x, f = simulate_profile_1D_fractal(step=step,mirror_length=mirror_length, renormalize_to_heights_sd=rms) print("%s, HEIGHTS Stdev: input=%g, obtained=%g"%("test_1d_fractal_figure_error",rms,f.std())) assert numpy.abs( rms - f.std() ) < 0.01 * numpy.abs(rms) if do_plot: from srxraylib.plot.gol import plot plot(x,f,title="test_1d_fractal_figure_error",xtitle="Y",ytitle="heights profile Z")
def test_1d_aps_figure_error(self): mirror_length=200.0 step=1.0 random_seed=898882 rms=1e-7 # units mm wName_x,wName = create_simulated_1D_file_APS(mirror_length=mirror_length,step=step, random_seed=random_seed, error_type=FIGURE_ERROR, rms=rms) print("%s, HEIGHTS Stdev: input=%g, obtained=%g"%("test_1d_aps_figure_error",rms,wName.std())) assert numpy.abs( rms - wName.std() ) < 0.01 * numpy.abs(rms) if do_plot: from srxraylib.plot.gol import plot plot(wName_x,wName,title="test_1d_aps_figure_error",xtitle="Y",ytitle="heights profile Z")
def test_1d_aps_slope_error(self): mirror_length=200.0 step=1.0 random_seed=898882 rms=1e-7 # units mm wName_x,wName = create_simulated_1D_file_APS(mirror_length=mirror_length,step=step, random_seed=random_seed, error_type=SLOPE_ERROR, rms=rms) slopes = numpy.gradient(wName, wName_x[1]-wName_x[0]) print("test_1d: test function: %s, SLOPES Stdev: input=%g, obtained=%g"%("test_1d_aps_figure_error",rms,slopes.std())) assert numpy.abs( rms - slopes.std() ) < 0.01 * numpy.abs(rms) if do_plot: from srxraylib.plot.gol import plot plot(wName_x,slopes,title="test_1d_aps_slope_error",xtitle="Y",ytitle="slopes Z'")
def test_initializers(self,do_plot=do_plot): print("# ") print("# Tests for initializars (1D) ") print("# ") x = numpy.linspace(-100,100,50) y = numpy.abs(x)**1.5 + 1j*numpy.abs(x)**1.8 wf0 = Wavefront1D.initialize_wavefront_from_steps(x[0],numpy.abs(x[1]-x[0]),y.size) wf0.set_complex_amplitude(y) wf1 = Wavefront1D.initialize_wavefront_from_range(x[0],x[-1],y.size) wf1.set_complex_amplitude(y) wf2 = Wavefront1D.initialize_wavefront_from_arrays(x,y) print("wavefront sizes: ",wf1.size(),wf1.size(),wf2.size()) if do_plot: from srxraylib.plot.gol import plot plot(wf0.get_abscissas(),wf0.get_intensity(), title="initialize_wavefront_from_steps",show=0) plot(wf1.get_abscissas(),wf1.get_intensity(), title="initialize_wavefront_from_range",show=0) plot(wf2.get_abscissas(),wf2.get_intensity(), title="initialize_wavefront_from_arrays",show=1) numpy.testing.assert_almost_equal(wf0.get_intensity(),numpy.abs(y)**2,5) numpy.testing.assert_almost_equal(wf1.get_intensity(),numpy.abs(y)**2,5) numpy.testing.assert_almost_equal(x,wf1.get_abscissas(),11) numpy.testing.assert_almost_equal(x,wf2.get_abscissas(),11)
def test_interpolator(self,do_plot=do_plot): # # interpolator # print("# ") print("# Tests for 1D interpolator ") print("# ") x = numpy.linspace(-10,10,100) sigma = 3.0 Z = numpy.exp(-1.0*x**2/2/sigma**2) print("shape of Z",Z.shape) wf = Wavefront1D.initialize_wavefront_from_steps(x[0],numpy.abs(x[1]-x[0]),number_of_points=100) print("wf shape: ",wf.size()) wf.set_complex_amplitude( Z ) x1 = 3.2 z1 = numpy.exp(x1**2/-2/sigma**2) print("complex ampl at (%g): %g+%gi (exact=%g)"%(x1, wf.get_interpolated_complex_amplitude(x1).real, wf.get_interpolated_complex_amplitude(x1).imag, z1)) self.assertAlmostEqual(wf.get_interpolated_complex_amplitude(x1).real,z1,4) print("intensity at (%g): %g (exact=%g)"%(x1,wf.get_interpolated_intensity(x1),z1**2)) self.assertAlmostEqual(wf.get_interpolated_intensity(x1),z1**2,4) if do_plot: from srxraylib.plot.gol import plot plot(wf.get_abscissas(),wf.get_intensity(),title="Original",show=1) xx = wf.get_abscissas() yy = wf.get_interpolated_intensities(wf.get_abscissas()-1e-5) plot(xx,yy,title="interpolated on same grid",show=1)
def test_spherical_wave(self,do_plot=do_plot): # # plane wave # print("# ") print("# Tests for a 1D spherical wave ") print("# ") wavelength = 1.24e-10 wavefront_length_x = 400e-6 npixels_x = 1024 wavefront_x = numpy.linspace(-0.5*wavefront_length_x,0.5*wavefront_length_x,npixels_x) wf1 = Wavefront1D.initialize_wavefront_from_steps( x_start=wavefront_x[0],x_step=numpy.abs(wavefront_x[1]-wavefront_x[0]), number_of_points=npixels_x,wavelength=wavelength) wf2 = Wavefront1D.initialize_wavefront_from_steps( x_start=wavefront_x[0],x_step=numpy.abs(wavefront_x[1]-wavefront_x[0]), number_of_points=npixels_x,wavelength=wavelength) # an spherical wavefront is obtained 1) by creation, 2) focusing a planewave wf1.set_spherical_wave(-5.0, 3+0j) wf1.apply_slit(-50e-6,10e-6) wf2.set_plane_wave_from_complex_amplitude(3+0j) wf2.apply_ideal_lens(5.0) wf2.apply_slit(-50e-6,10e-6) if do_plot: from srxraylib.plot.gol import plot plot(wf1.get_abscissas(),wf1.get_phase(),title="Phase of spherical wavefront",show=0) plot(wf2.get_abscissas(),wf2.get_phase(),title="Phase of focused plane wavefront",show=0) plot(wf1.get_abscissas(),wf1.get_phase(from_minimum_intensity=0.1),title="Phase of spherical wavefront (for intensity > 0.1)",show=0) plot(wf2.get_abscissas(),wf2.get_phase(from_minimum_intensity=0.1),title="Phase of focused plane wavefront (for intensity > 0.1)",show=1) numpy.testing.assert_almost_equal(wf1.get_phase(),wf2.get_phase(),5)
def test_plane_wave(do_plot=0): import copy # # plane wave # value_amplitude = 5.0 value_phase = numpy.pi wavefront = Wavefront1D.initialize_wavefront_from_range( wavelength=1e-2, number_of_points=1000000, x_min=-1, x_max=1 ) wavefront.set_plane_wave_from_amplitude_and_phase(value_amplitude, value_phase) wavefront.apply_slit(-0.4, 0.4) wavefront_focused = copy.deepcopy(wavefront) wavefront_focused.apply_ideal_lens(100) # # some tests # test_value1 = wavefront.get_interpolated_amplitude(0.01) - value_amplitude assert numpy.abs(test_value1) < 1e-6 test_value2 = wavefront.get_interpolated_amplitudes(-4) assert numpy.abs(test_value2) < 1e-6 if do_plot: from srxraylib.plot.gol import plot plot( wavefront.get_abscissas(), wavefront.get_intensity(), show=0, title="Plane wave defined in [-1,1] and clipped by a [-.4,.4] slit", xtitle="X (m)", ytitle="Intensity", ) plot( wavefront.get_abscissas(), wavefront.get_amplitude(), show=0, title="Plane wave defined in [-1,1] and clipped by a [-.4,.4] slit", xtitle="X (m)", ytitle="Amplitude", ) plot( wavefront.get_abscissas(), wavefront.get_phase(), show=0, title="Plane wave defined in [-1,1] and clipped by a [-.4,.4] slit", xtitle="X (m)", ytitle="Phase [rad]", ) plot( wavefront.get_abscissas(), wavefront_focused.get_phase(), show=1, title="Plane wave after ideal lens", xtitle="X (m)", ytitle="Phase [rad]", )
# # plot profiles # horizontal_intensity_profile = wf_prop.get_intensity()[:,wf_prop.size()[1]/2] horizontal_intensity_profile /= horizontal_intensity_profile.max() vertical_intensity_profile = wf_prop.get_intensity()[wf_prop.size()[0]/2,:] vertical_intensity_profile /= vertical_intensity_profile.max() horizontal_intensity_profile_srw = wf_prop_srw.get_intensity()[:,wf_prop_srw.size()[1]/2] horizontal_intensity_profile_srw /= horizontal_intensity_profile_srw.max() vertical_intensity_profile_srw = wf_prop_srw.get_intensity()[wf_prop_srw.size()[0]/2,:] vertical_intensity_profile_srw /= vertical_intensity_profile_srw.max() plot( 1e6*wf_prop.get_coordinate_x(), horizontal_intensity_profile, 1e6*wf_prop_srw.get_coordinate_x(), horizontal_intensity_profile_srw, show=0, legend=["in-python","SRW"],color=["red","black"], title="Horizontal profile of diffracted intensity",xtitle='X [um]',ytitle='Diffracted intensity [a.u.]') plot( 1e6*wf_prop.get_coordinate_y(), vertical_intensity_profile, 1e6*wf_prop_srw.get_coordinate_y(), vertical_intensity_profile_srw, show=0, legend=["in-python","SRW"],color=["red","black"], title="Vertical profile of diffracted intensity",xtitle='X [um]',ytitle='Diffracted intensity [a.u.]') plot_show() # # sample rays fro SHADOW
def test_ScaledArray(self,do_plot=do_plot): # # ScaledArray.initialize + set_scale_from_steps # test_array = numpy.arange(15.0, 18.8, 0.2) print("\nTesting ScaledArray.initialize + set_scale_from_steps...") scaled_array = ScaledArray.initialize(test_array) scaled_array.set_scale_from_steps(test_array[0],0.2) print("Using array: ",test_array) print("Stored array: ",scaled_array.get_values()) print("Using array: ",test_array) print("Stored abscissas: ",scaled_array.get_abscissas()) numpy.testing.assert_almost_equal(test_array,scaled_array.get_values(),11) numpy.testing.assert_almost_equal(test_array,scaled_array.get_abscissas(),11) self.assertAlmostEqual(0.2,scaled_array.delta(),11) self.assertAlmostEqual(15.0,scaled_array.offset(),11) x_in = (18.80,16.22,22.35) x_good = (18.80,16.22,18.8) for i,x in enumerate(x_in): print("interpolated at %3.2f is: %3.2f (must give %3.2f)"%( x,scaled_array.interpolate_value(x), x_good[i] )) self.assertAlmostEqual(scaled_array.interpolate_value(x), x_good[i], 2) # # ScaledArray.initialize + set_scale_from_range ; interpolate vectorized # print("\nTesting ScaledArray.initialize + set_scale_from_range ; interpolate vectorized...") scaled_array = ScaledArray.initialize(test_array) scaled_array.set_scale_from_range(test_array[0],test_array[-1]) x_in = (18.80,16.22,22.35) x_good = (18.80,16.22,18.8) for i,x in enumerate(x_in): print("interpolated at %3.2f is: %3.2f (must give %3.2f)"%( x,scaled_array.interpolate_value(x), x_good[i] )) self.assertAlmostEqual(scaled_array.interpolate_value(x), x_good[i], 2) # # ScaledArray.initialize_from_steps # print("\nTesting ScaledArray.initialize_from_steps...") scaled_array = ScaledArray.initialize_from_steps(test_array, test_array[0], 0.2) x_in = (18.80,16.22,22.35) x_good = (18.80,16.22,18.8) for i,x in enumerate(x_in): print("interpolated at %3.2f is: %3.2f (must give %3.2f)"%( x,scaled_array.interpolate_value(x), x_good[i] )) self.assertAlmostEqual(scaled_array.interpolate_value(x), x_good[i], 2) # # ScaledArray.initialize_from_steps # print("\nTesting ScaledArray.initialize_from_range...") scaled_array = ScaledArray.initialize_from_range(test_array,test_array[0], test_array[-1]) x_in = (18.80,16.22,22.35) x_good = (18.80,16.22,18.8) for i,x in enumerate(x_in): print("interpolated at %3.2f is: %3.2f (must give %3.2f)"%( x,scaled_array.interpolate_value(x), x_good[i] )) self.assertAlmostEqual(scaled_array.interpolate_value(x), x_good[i], 2) # # interpolator # print("\nTesting interpolator...") x = numpy.arange(-5.0, 18.8, 3) y = x**2 scaled_array = ScaledArray.initialize_from_range(y,x[0],x[-1]) print("for interpolation; x=",x) print("for interpolation; offset, delta:=",scaled_array.offset(),scaled_array.delta()) print("for interpolation; abscissas:=",scaled_array.get_abscissas()) x1 = numpy.concatenate( ( numpy.arange(-6, -4, 0.1) , [0], numpy.arange(11, 20.0, 0.1) ) ) y1 = scaled_array.interpolate_values(x1) if do_plot: from srxraylib.plot.gol import plot plot(x,y,x1,y1,legend=["Data",'Interpolated'],legend_position=[0.4,0.8], marker=['','o'],linestyle=['-',''],xrange=[-6,21],yrange=[-5,375]) for i in range(len(x1)): y2 = x1[i]**2 if x1[i] <= x[0]: y2 = y[0] if x1[i] >= x[-1]: y2 = y[-1] print(" interpolated at x=%g is: %g (expected: %g)"%(x1[i],y1[i],y2)) self.assertAlmostEqual(1e-3*y1[i], 1e-3*y2, 2) # interpolate on same grid print("\nTesting interpolation on the same grid...") y1 = scaled_array.interpolate_values(scaled_array.get_abscissas()) if do_plot: from srxraylib.plot.gol import plot plot(scaled_array.get_abscissas(),scaled_array.get_values(), scaled_array.get_abscissas(),y1,legend=["Data",'Interpolated on same grid'],legend_position=[0.4,0.8], marker=['','o'],linestyle=['-','']) numpy.testing.assert_almost_equal(scaled_array.get_values(),y1,5)
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): 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 = Wavefront2D.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)) if aperture_type == 'circle': wf.apply_pinhole(aperture_diameter/2) elif aperture_type == 'square': wf.apply_slit(-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 method == 'fft': wf1 = propagate_2D_fresnel(wf, propagation_distance) elif method == 'convolution': wf1 = propagate_2D_fresnel_convolution(wf, propagation_distance) elif method == 'srw': wf1 = propagate_2D_fresnel_srw(wf, propagation_distance) elif method == 'integral': wf1 = propagate_2D_integral(wf, propagation_distance) 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()[:,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 = Wavefront2D.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) spherical_or_plane_and_lens = 0 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) 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 wf.apply_ideal_lens(focal_length,focal_length) print("Incident intensity: ",wf.get_intensity().sum()) # propagation downstream the lens to image plane for i in range(propagation_steps): if propagation_steps > 1: print(">>> Propagating step %d of %d; propagation_distance=%g m"%(i+1,propagation_steps, propagation_distance*defocus_factor/propagation_steps)) if method == 'fft': wf = propagate_2D_fresnel(wf, propagation_distance*defocus_factor/propagation_steps) elif method == 'convolution': wf = propagate_2D_fresnel_convolution(wf, propagation_distance*defocus_factor/propagation_steps) elif method == 'srw': wf = propagate_2D_fresnel_srw(wf, propagation_distance*defocus_factor/propagation_steps) elif method == 'fraunhofer': wf = propagate_2D_fraunhofer(wf, propagation_distance*defocus_factor/propagation_steps) else: raise Exception("Not implemented method: %s"%method) horizontal_profile = wf.get_intensity()[:,wf.size()[1]/2] horizontal_profile /= horizontal_profile.max() print("FWHM of the horizontal profile: %g um"%(1e6*line_fwhm(horizontal_profile)*wf.delta()[0])) vertical_profile = wf.get_intensity()[wf.size()[0]/2,:] vertical_profile /= vertical_profile.max() print("FWHM of the vertical profile: %g um"%(1e6*line_fwhm(vertical_profile)*wf.delta()[1])) if do_plot: from srxraylib.plot.gol import plot,plot_image plot_image(wf.get_intensity(),wf.get_coordinate_x(),wf.get_coordinate_y(),title='intensity (%s)'%method,show=0) # plot_image(wf.get_amplitude(),wf.get_coordinate_x(),wf.get_coordinate_y(),title='amplitude (%s)'%method,show=0) plot_image(wf.get_phase(),wf.get_coordinate_x(),wf.get_coordinate_y(),title='phase (%s)'%method,show=0) plot(wf.get_coordinate_x(),horizontal_profile, wf.get_coordinate_y(),vertical_profile, legend=['Horizontal profile','Vertical profile'],title="%s"%method,show=show) print("Output intensity: ",wf.get_intensity().sum()) return wf.get_coordinate_x(),horizontal_profile
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 = 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 = Wavefront2D.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)) if aperture_type == 'circle': wf.apply_pinhole(aperture_diameter/2) elif aperture_type == 'square': wf.apply_slit(-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)") wf1 = propagate_2D_fraunhofer(wf, propagation_distance=1.0) # propagating at 1 m means the result is like in angles 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()[:,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)
h5w = H5SimpleWriter.initialize_file(h5_file,creator="xoppy_undulators.py") else: h5w = H5SimpleWriter(h5_file,None) h5w.create_entry(h5_entry_name,nx_default=None) h5w.add_stack(e,h,v,p,stack_name="Radiation",entry_name=h5_entry_name, title_0="Photon energy [eV]", title_1="X gap [mm]", title_2="Y gap [mm]") h5w.create_entry("parameters",root_entry=h5_entry_name,nx_default=None) for key in h5_parameters.keys(): h5w.add_key(key,h5_parameters[key], entry_name=h5_entry_name+"/parameters") print("File written to disk: %s"%h5_file) except: print("ERROR initializing h5 file") return e, h, v, p, code if __name__ == "__main__": from srxraylib.plot.gol import plot,plot_image e, f, spectral_power, cumulated_power = xoppy_calc_undulator_spectrum() plot(e,f) h, v, p, code = xoppy_calc_undulator_power_density(h5_file="test.h5",h5_initialize=True) plot_image(p,h,v) e, h, v, p, code = xoppy_calc_undulator_radiation(ELECTRONENERGY=6.0, h5_file="test.h5",h5_entry_name="first_entry",h5_initialize=True) e, h, v, p, code = xoppy_calc_undulator_radiation(ELECTRONENERGY=7.0, h5_file="test.h5",h5_entry_name="second_entry",h5_initialize=False)