示例#1
0
    def undulator(self, method, npixels_x, npixels_y, pixelsize_x, pixelsize_y,
                  wavelength, sigma, m, m_x, m_y, propagation_distance, radius,
                  show, image_source, apply_lens):

        wavefront = 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)

        wavefront.set_spherical_wave(radius=radius)

        if image_source == False:

            X = wavefront.get_mesh_x()
            Y = wavefront.get_mesh_y()

            wavefront.rescale_amplitude(
                numpy.exp(-(X**2 + Y**2) / (2 * sigma**2))
            )  # applichiamo intensita' con profilo gaussiano

        print("Input intensity: ", wavefront.get_intensity().sum())

        if apply_lens == True:
            wavefront.apply_ideal_lens(focal_length_x=propagation_distance,
                                       focal_length_y=propagation_distance)

            print("Intensity after lens: ", wavefront.get_intensity().sum())

        if method == 'fft':
            output_wf = propagate_2D_fresnel(
                wavefront, propagation_distance=propagation_distance)
        elif method == 'rescaling':
            output_wf = propagator2d_fourier_rescaling(
                wavefront, propagation_distance=propagation_distance, m=m)
        elif method == 'rescaling_xy':
            output_wf = propagator2d_fourier_rescaling_xy(
                wavefront,
                propagation_distance=propagation_distance,
                m_x=m_x,
                m_y=m_y)

        plot_undulator(output_wf, method=method, show=show)

        horizontal_profile_wf = line_image(wavefront.get_intensity(),
                                           horizontal_or_vertical='H')

        vertical_profile_wf = line_image(wavefront.get_intensity(),
                                         horizontal_or_vertical='V')

        horizontal_phase_profile_wf = line_image(wavefront.get_phase(),
                                                 horizontal_or_vertical='H')

        if image_source == True:
            return wavefront.get_coordinate_x(
            ), horizontal_profile_wf, horizontal_phase_profile_wf
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
示例#3
0
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
示例#4
0
    # 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:
        raise Exception("Undefined method")


    plot_image(wf_prop.get_intensity(),1e6*wf_prop.get_coordinate_x(),1e6*wf_prop.get_coordinate_y(), show=0,
               title="in-python propagated intensity at 35 m",xtitle="X [um]",ytitle="Y [um]",)

    wavefront_intensity_fwhm(wf_prop,prefix="In-python propagated wavefront",units="urad")

    #
示例#5
0
    def propagate_2D_fresnel(self,
                             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,
                             m=1,
                             m_x=1,
                             m_y=1,
                             show=0):

        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)
        else:
            raise Exception("Not implemented! (accepted: circle, square)")

        if method == 'fft':
            wf1 = propagate_2D_fresnel(wf, propagation_distance)
        elif method == 'rescaling':
            wf1 = propagator2d_fourier_rescaling(wf, propagation_distance, m=m)
        elif method == 'rescaling_xy':
            wf1 = propagator2d_fourier_rescaling_xy(wf,
                                                    propagation_distance,
                                                    m_x=m_x,
                                                    m_y=m_y)
        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 = wf.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.60, 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)

        if method == 'rescaling_xy' and do_plot:
            angle_y = wf.get_coordinate_y() / propagation_distance
            intensity_calculated_v = wf1.get_intensity()[int(wf1.size()[1] /
                                                             2), :]
            intensity_calculated_v /= intensity_calculated_v.max()

            from srxraylib.plot.gol import plot
            plot(
                wf1.get_coordinate_y() * 1e6 / propagation_distance,
                intensity_calculated_v,
                angle_y * 1e6,
                intensity_theory,
                legend=[
                    "%s V profile" % method_label, "Theoretical (far field)"
                ],
                legend_position=(0.60, 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="Y (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 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
示例#8
0
    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
示例#9
0
          (method_label))
    print("#                                                             ")

    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))

    wf.apply_pinhole(aperture_diameter / 2, negative=True)

    wf1 = propagate_2D_fresnel(wf, propagation_distance)

    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]",
               show=0)

    plot_image(wf1.get_intensity(),
               1e6 * wf1.get_coordinate_x() / propagation_distance,
               1e6 * wf1.get_coordinate_y() / propagation_distance,
               title="Diffracted intensity by a circular stop %3.1f um" %
               (1e6 * aperture_diameter),
示例#10
0
    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:
        raise Exception("Undefined method")

    plot_image(
示例#11
0
def propagate_2D(calculation_parameters, input_parameters):
    shadow_oe = calculation_parameters.shadow_oe_end

    if calculation_parameters.do_ff_z and calculation_parameters.do_ff_x:
        global_phase_shift_profile = None

        if shadow_oe._oe.F_MOVE == 1 and shadow_oe._oe.X_ROT != 0.0:
            if input_parameters.ghy_calcType == 3 or input_parameters.ghy_calcType == 4:
                global_phase_shift_profile = calculation_parameters.w_mirr_2D_values
            elif input_parameters.ghy_calcType == 2:
                global_phase_shift_profile = ScaledMatrix.initialize_from_range(numpy.zeros((3, 3)),
                                                                                shadow_oe._oe.RWIDX2, shadow_oe._oe.RWIDX1,
                                                                                shadow_oe._oe.RLEN2,  shadow_oe._oe.RLEN1)

            for x_index in range(global_phase_shift_profile.size_x()):
                global_phase_shift_profile.z_values[x_index, :] += global_phase_shift_profile.get_y_values()*numpy.sin(numpy.radians(-shadow_oe._oe.X_ROT))
        elif input_parameters.ghy_calcType == 3 or input_parameters.ghy_calcType == 4:
            global_phase_shift_profile = calculation_parameters.w_mirr_2D_values

        # only tangential slopes
        if input_parameters.ghy_calcType == 3 or input_parameters.ghy_calcType == 4:
            rms_slope = hy_findrmsslopefromheight(ScaledArray(np_array=global_phase_shift_profile.z_values[int(global_phase_shift_profile.size_x()/2), :],
                                                              scale=global_phase_shift_profile.get_y_values()))

            print("Using RMS slope = " + str(rms_slope))

        # ------------------------------------------
        # far field calculation
        # ------------------------------------------
        focallength_ff = calculate_focal_length_ff_2D(calculation_parameters.ghy_x_min,
                                                      calculation_parameters.ghy_x_max,
                                                      calculation_parameters.ghy_z_min,
                                                      calculation_parameters.ghy_z_max,
                                                      input_parameters.ghy_npeak,
                                                      calculation_parameters.gwavelength)

        if (input_parameters.ghy_calcType == 3 or input_parameters.ghy_calcType == 4) and rms_slope != 0:
            focallength_ff = min(focallength_ff,(calculation_parameters.ghy_z_max-calculation_parameters.ghy_z_min) / 16 / rms_slope ) #xshi changed
        elif input_parameters.ghy_calcType == 2 and not global_phase_shift_profile is None:
            focallength_ff = min(focallength_ff, input_parameters.ghy_distance*4) #TODO: PATCH to be found with a formula

        print("FF: calculated focal length: " + str(focallength_ff))

        fftsize_x = int(calculate_fft_size(calculation_parameters.ghy_x_min,
                                           calculation_parameters.ghy_x_max,
                                           calculation_parameters.gwavelength,
                                           focallength_ff,
                                           input_parameters.ghy_fftnpts,
                                           factor=20))

        fftsize_z = int(calculate_fft_size(calculation_parameters.ghy_z_min,
                                        calculation_parameters.ghy_z_max,
                                        calculation_parameters.gwavelength,
                                        focallength_ff,
                                        input_parameters.ghy_fftnpts,
                                        factor=20))

        print("FF: creating plane wave begin, fftsize_x = " +  str(fftsize_x) + ", fftsize_z = " +  str(fftsize_z))

        wavefront = Wavefront2D.initialize_wavefront_from_range(wavelength=calculation_parameters.gwavelength,
                                                                number_of_points=(fftsize_x, fftsize_z),
                                                                x_min=calculation_parameters.ghy_x_min,
                                                                x_max=calculation_parameters.ghy_x_max,
                                                                y_min=calculation_parameters.ghy_z_min,
                                                                y_max=calculation_parameters.ghy_z_max)

        try:
            for i in range(0, len(wavefront.electric_field_array.x_coord)):
                for j in range(0, len(wavefront.electric_field_array.y_coord)):
                    interpolated = calculation_parameters.wIray_2d.interpolate_value(wavefront.electric_field_array.x_coord[i],
                                                                                     wavefront.electric_field_array.y_coord[j])
                    wavefront.electric_field_array.set_z_value(i, j, numpy.sqrt(0.0 if interpolated < 0 else interpolated))
        except IndexError:
            raise Exception("Unexpected Error during interpolation: try reduce Number of bins for I(Tangential) histogram")

        wavefront.apply_ideal_lens(focallength_ff, focallength_ff)

        shadow_oe = calculation_parameters.shadow_oe_end

        if input_parameters.ghy_calcType == 3 or \
                (input_parameters.ghy_calcType == 2 and not global_phase_shift_profile is None):
            print("FF: calculating phase shift due to Height Error Profile")

            phase_shifts = numpy.zeros(wavefront.size())

            for index in range(0, phase_shifts.shape[0]):
                np_array = numpy.zeros(global_phase_shift_profile.shape()[1])
                for j in range(0, len(np_array)):
                    np_array[j] = global_phase_shift_profile.interpolate_value(wavefront.get_coordinate_x()[index], calculation_parameters.w_mirr_2D_values.get_y_value(j))

                global_phase_shift_profile_z = ScaledArray.initialize_from_steps(np_array,
                                                                                 global_phase_shift_profile.y_coord[0],
                                                                                 global_phase_shift_profile.y_coord[1] - global_phase_shift_profile.y_coord[0])

                phase_shifts[index, :] = get_mirror_phase_shift(wavefront.get_coordinate_y(),
                                                                calculation_parameters.gwavelength,
                                                                calculation_parameters.wangle_z,
                                                                calculation_parameters.wl_z,
                                                                global_phase_shift_profile_z)
            wavefront.add_phase_shifts(phase_shifts)
        elif input_parameters.ghy_calcType == 4:
            print("FF: calculating phase shift due to Height Error Profile")

            phase_shifts = numpy.zeros(wavefront.size())

            for index in range(0, phase_shifts.shape[0]):
                global_phase_shift_profile_z = ScaledArray.initialize_from_steps(global_phase_shift_profile.z_values[index, :],
                                                                                 global_phase_shift_profile.y_coord[0],
                                                                                 global_phase_shift_profile.y_coord[1] - global_phase_shift_profile.y_coord[0])

                phase_shifts[index, :] = get_grating_phase_shift(wavefront.get_coordinate_y(),
                                                                 calculation_parameters.gwavelength,
                                                                 calculation_parameters.wangle_z,
                                                                 calculation_parameters.wangle_ref_z,
                                                                 calculation_parameters.wl_z,
                                                                 global_phase_shift_profile_z)
            wavefront.add_phase_shifts(phase_shifts)
        elif input_parameters.ghy_calcType == 6:
            for w_mirr_2D_values in calculation_parameters.w_mirr_2D_values:
                phase_shift = get_crl_phase_shift(w_mirr_2D_values,
                                                  input_parameters,
                                                  calculation_parameters,
                                                  [wavefront.get_coordinate_x(), wavefront.get_coordinate_y()])

                wavefront.add_phase_shift(phase_shift)

        print("calculated plane wave: begin FF propagation (distance = " +  str(focallength_ff) + ")")

        propagated_wavefront = propagator2D.propagate_2D_fresnel(wavefront, focallength_ff)

        print("dif_zp: begin calculation")

        imagesize_x = min(abs(calculation_parameters.ghy_x_max), abs(calculation_parameters.ghy_x_min)) * 2
        imagesize_x = min(imagesize_x,
                          input_parameters.ghy_npeak*2*0.88*calculation_parameters.gwavelength*focallength_ff/abs(calculation_parameters.ghy_x_max-calculation_parameters.ghy_x_min))

        # TODO: this is a patch: to be rewritten
        if shadow_oe._oe.F_MOVE==1 and not shadow_oe._oe.Y_ROT==0:
            imagesize_x = max(imagesize_x, 8*(focallength_ff*numpy.tan(numpy.radians(numpy.abs(shadow_oe._oe.Y_ROT))) + numpy.abs(shadow_oe._oe.OFFX)))

        delta_x = propagated_wavefront.delta()[0]
        imagenpts_x = int(round(imagesize_x/delta_x/2) * 2 + 1)

        imagesize_z = min(abs(calculation_parameters.ghy_z_max), abs(calculation_parameters.ghy_z_min)) * 2
        imagesize_z = min(imagesize_z,
                          input_parameters.ghy_npeak*2*0.88*calculation_parameters.gwavelength*focallength_ff/abs(calculation_parameters.ghy_z_max-calculation_parameters.ghy_z_min))

        # TODO: this is a patch: to be rewritten
        if shadow_oe._oe.F_MOVE==1 and not shadow_oe._oe.X_ROT==0:
            imagesize_z = max(imagesize_z, 8*(focallength_ff*numpy.tan(numpy.radians(numpy.abs(shadow_oe._oe.X_ROT))) + numpy.abs(shadow_oe._oe.OFFZ)))

        delta_z = propagated_wavefront.delta()[1]
        imagenpts_z = int(round(imagesize_z/delta_z/2) * 2 + 1)

        dif_xpzp = ScaledMatrix.initialize_from_range(numpy.ones((imagenpts_x, imagenpts_z)),
                                                      min_scale_value_x = -(imagenpts_x - 1) / 2 * delta_x,
                                                      max_scale_value_x =(imagenpts_x - 1) / 2 * delta_x,
                                                      min_scale_value_y = -(imagenpts_z - 1) / 2 * delta_z,
                                                      max_scale_value_y =(imagenpts_z - 1) / 2 * delta_z)

        for i in range(0, dif_xpzp.shape()[0]):
            for j in range(0, dif_xpzp.shape()[1]):
                dif_xpzp.set_z_value(i, j, numpy.absolute(propagated_wavefront.get_interpolated_complex_amplitude(
                                                               dif_xpzp.x_coord[i],
                                                               dif_xpzp.y_coord[j]))**2
                                                           )

        dif_xpzp.set_scale_from_range(0,
                                      -(imagenpts_x - 1) / 2 * delta_x / focallength_ff,
                                      (imagenpts_x - 1) / 2 * delta_x / focallength_ff)

        dif_xpzp.set_scale_from_range(1,
                                      -(imagenpts_z - 1) / 2 * delta_z / focallength_ff,
                                      (imagenpts_z - 1) / 2 * delta_z / focallength_ff)

        calculation_parameters.dif_xpzp = dif_xpzp