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 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("# ") # \ | / # * /users/pirro/Documents/workspace/syned | | | * # / | \ # <------- 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()[:,int(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()[int(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 (%d pixels)"%(wf.size()[0]),ytitle="Y um (%d pixels)",title='intensity (%s)'%method,show=False) plot_image(wf.get_phase(),1e6*wf.get_coordinate_x(),1e6*wf.get_coordinate_y(), xtitle="X um (%d pixels)"%(wf.size()[0]),ytitle="Y um (%d pixels)"%(wf.size[1]),title='phase (%s)'%method,show=False) 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
fwhm_h_source,fwhm_v_source = wavefront_intensity_fwhm(wf,prefix="Source wavefront ") # plot plot_image (wf.get_phase()**2,1e6*wf.get_coordinate_x(),1e6*reader.y_coordinates(),title="Phases for mode %i"%mymode_index, show=0) # # propagation # # method = "fraunhofer" # method = "srw" method = "fft" if method == "fraunhofer": wf_rebinned = wf.rebin(4,10,4,15,keep_the_same_intensity=1,set_extrapolation_to_zero=1) wf_prop = propagate_2D_fraunhofer(wf_rebinned,propagation_distance=propagation_distance,shift_half_pixel=1) elif method == "srw": wf_prop = propagate_2D_fresnel_srw(wf,propagation_distance=propagation_distance,srw_autosetting=1) elif method == "fft": wf_rebinned = wf.rebin(4,10,4,15,keep_the_same_intensity=1,set_extrapolation_to_zero=1) plot_image(wf_rebinned.get_phase(), 1e6*wf_rebinned.get_coordinate_x(), 1e6*wf_rebinned.get_coordinate_y(), title="Rebinned phases",show=0) number_of_steps = 1 if number_of_steps == 1: wf_prop = propagate_2D_fresnel(wf_rebinned,propagation_distance=propagation_distance,shift_half_pixel=1) else: wf_prop = wf_rebinned for i in range(number_of_steps): print(">>> Propagating step %d or %d..."%(i+1,number_of_steps)) wf_prop = propagate_2D_fresnel(wf_prop,propagation_distance=propagation_distance/number_of_steps,shift_half_pixel=1) else:
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)
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()[:, 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 = 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()[:, int(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()[int(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
# propagation # # method = "fraunhofer" # method = "srw" method = "fft" if method == "fraunhofer": wf_rebinned = wf.rebin(4, 10, 4, 15, keep_the_same_intensity=1, set_extrapolation_to_zero=1) wf_prop = propagate_2D_fraunhofer( wf_rebinned, propagation_distance=propagation_distance, shift_half_pixel=1) elif method == "srw": wf_prop = propagate_2D_fresnel_srw( wf, propagation_distance=propagation_distance, srw_autosetting=1) elif method == "fft": wf_rebinned = wf.rebin(4, 10, 4, 15, keep_the_same_intensity=1, set_extrapolation_to_zero=1) plot_image(wf_rebinned.get_phase(), 1e6 * wf_rebinned.get_coordinate_x(), 1e6 * wf_rebinned.get_coordinate_y(), title="Rebinned phases",