예제 #1
0
    def schmidt(self, pixelsize, npixels, wavelength, m, propagation_distance):
        wavefront = Wavefront1D.initialize_wavefront_from_range(
            x_min=-pixelsize * npixels / 2,
            x_max=pixelsize * npixels / 2,
            number_of_points=npixels,
            wavelength=wavelength)

        # wavefront.set_spherical_wave(radius=radius)
        wavefront.set_plane_wave_from_amplitude_and_phase()

        wavefront.apply_slit(-1e-3, 1e-3)

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

        wavefront_propagated = propagator1d_fourier_rescaling(
            wavefront, propagation_distance=propagation_distance, m=m)

        print('Intensity after propagation: ',
              wavefront_propagated.get_intensity().sum())

        intensity_theory = fresnel_prop_square_aperture_analitical(
            x2=wavefront_propagated.get_abscissas(),
            y2=0,
            aperture_diameter=2e-3,
            wavelength=wavelength,
            propagation_distance=propagation_distance)

        return wavefront_propagated, intensity_theory
예제 #2
0
    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
예제 #3
0
    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
예제 #4
0
    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)
예제 #5
0
    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)
예제 #6
0
def propagate_1D_x_direction(calculation_parameters, input_parameters):

    scale_factor = 1.0

    shadow_oe = calculation_parameters.shadow_oe_end

    global_phase_shift_profile = None

    if shadow_oe._oe.F_MOVE == 1 and shadow_oe._oe.Y_ROT != 0.0:
        if input_parameters.ghy_calcType == 3 or input_parameters.ghy_calcType == 4:
            global_phase_shift_profile = calculation_parameters.w_mirror_lx
        elif input_parameters.ghy_calcType == 2:
            global_phase_shift_profile = ScaledArray.initialize_from_range(numpy.zeros(3), shadow_oe._oe.RWIDX2, shadow_oe._oe.RWIDX1)

        global_phase_shift_profile.set_values(global_phase_shift_profile.get_values() +
                                              global_phase_shift_profile.get_abscissas()*numpy.sin(numpy.radians(-shadow_oe._oe.Y_ROT)))
    elif input_parameters.ghy_calcType == 3 or input_parameters.ghy_calcType == 4:
        global_phase_shift_profile = calculation_parameters.w_mirror_lx

    if input_parameters.ghy_calcType == 3 or input_parameters.ghy_calcType == 4:
        rms_slope = hy_findrmsslopefromheight(global_phase_shift_profile)

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

        average_incident_angle = numpy.radians(90-calculation_parameters.shadow_oe_end._oe.T_INCIDENCE)*1e3
        average_reflection_angle = numpy.radians(90-calculation_parameters.shadow_oe_end._oe.T_REFLECTION)*1e3

        if calculation_parameters.beam_not_cut_in_x:
            dp_image = numpy.std(calculation_parameters.xx_focal_ray)/input_parameters.ghy_focallength
            dp_se = 2 * rms_slope * numpy.sin(average_incident_angle/1e3)	# different in x and z
            dp_error = calculation_parameters.gwavelength/2/(calculation_parameters.ghy_x_max-calculation_parameters.ghy_x_min)

            scale_factor = max(1, 5*min(dp_error/dp_image, dp_error/dp_se))

    # ------------------------------------------
    # far field calculation
    # ------------------------------------------
    if calculation_parameters.do_ff_x:
        focallength_ff = calculate_focal_length_ff(calculation_parameters.ghy_x_min,
                                                   calculation_parameters.ghy_x_max,
                                                   input_parameters.ghy_npeak,
                                                   calculation_parameters.gwavelength)

        if input_parameters.ghy_calcType == 3:
            if not (rms_slope == 0.0 or average_incident_angle == 0.0):
                focallength_ff = min(focallength_ff,(calculation_parameters.ghy_x_max-calculation_parameters.ghy_x_min) / 16 / rms_slope / numpy.sin(average_incident_angle / 1e3))#xshi changed
        elif input_parameters.ghy_calcType == 4:
            if not (rms_slope == 0.0 or average_incident_angle == 0.0):
                focallength_ff = min(focallength_ff,(calculation_parameters.ghy_x_max-calculation_parameters.ghy_x_min) / 8 / rms_slope / (numpy.sin(average_incident_angle / 1e3) + numpy.sin(average_reflection_angle / 1e3)))#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

        fftsize = int(scale_factor * calculate_fft_size(calculation_parameters.ghy_x_min,
                                                        calculation_parameters.ghy_x_max,
                                                        calculation_parameters.gwavelength,
                                                        focallength_ff,
                                                        input_parameters.ghy_fftnpts))
        
        print("FF: creating plane wave begin, fftsize = " +  str(fftsize))

        wavefront = Wavefront1D.initialize_wavefront_from_range(wavelength=calculation_parameters.gwavelength,
                                                                number_of_points=fftsize,
                                                                x_min=scale_factor * calculation_parameters.ghy_x_min,
                                                                x_max=scale_factor * calculation_parameters.ghy_x_max)

        if scale_factor == 1.0:
            try:
                wavefront.set_plane_wave_from_complex_amplitude(numpy.sqrt(calculation_parameters.wIray_x.interpolate_values(wavefront.get_abscissas())))
            except IndexError:
                raise Exception("Unexpected Error during interpolation: try reduce Number of bins for I(Sagittal) histogram")

        wavefront.apply_ideal_lens(focallength_ff)

        if input_parameters.ghy_calcType == 3 or \
                (input_parameters.ghy_calcType == 2 and not global_phase_shift_profile is None):
           wavefront.add_phase_shifts(get_mirror_phase_shift(wavefront.get_abscissas(),
                                                             calculation_parameters.gwavelength,
                                                             calculation_parameters.wangle_x,
                                                             calculation_parameters.wl_x,
                                                             global_phase_shift_profile))
        elif input_parameters.ghy_calcType == 4:
           wavefront.add_phase_shifts(get_grating_phase_shift(wavefront.get_abscissas(),
                                                              calculation_parameters.gwavelength,
                                                              calculation_parameters.wangle_x,
                                                              calculation_parameters.wangle_ref_x,
                                                              calculation_parameters.wl_x,
                                                              global_phase_shift_profile))

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

        propagated_wavefront = propagator.propagate_1D_fresnel(wavefront, focallength_ff)

        print("dif_xp: begin calculation")

        shadow_oe = calculation_parameters.shadow_oe_end

        imagesize = min(abs(calculation_parameters.ghy_x_max), abs(calculation_parameters.ghy_x_min)) * 2
        # 2017-01 Luca Rebuffi
        imagesize = min(imagesize,
                        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 = max(imagesize, 8*(focallength_ff*numpy.tan(numpy.radians(numpy.abs(shadow_oe._oe.Y_ROT))) + numpy.abs(shadow_oe._oe.OFFX)))

        imagenpts = int(round(imagesize / propagated_wavefront.delta() / 2) * 2 + 1)

        dif_xp = ScaledArray.initialize_from_range(numpy.ones(propagated_wavefront.size()),
                                                   -(imagenpts - 1) / 2 * propagated_wavefront.delta(),
                                                   (imagenpts - 1) / 2 * propagated_wavefront.delta())


        dif_xp.np_array = numpy.absolute(propagated_wavefront.get_interpolated_complex_amplitudes(dif_xp.scale))**2

        dif_xp.set_scale_from_range(-(imagenpts - 1) / 2 * propagated_wavefront.delta() / focallength_ff,
                                    (imagenpts - 1) / 2 * propagated_wavefront.delta() / focallength_ff)

        calculation_parameters.dif_xp = dif_xp

    # ------------------------------------------
    # near field calculation
    # ------------------------------------------
    if input_parameters.ghy_nf >= 1 and input_parameters.ghy_calcType > 1:  # near field calculation
        focallength_nf = input_parameters.ghy_focallength

        fftsize = int(scale_factor * calculate_fft_size(calculation_parameters.ghy_x_min,
                                                        calculation_parameters.ghy_x_max,
                                                        calculation_parameters.gwavelength,
                                                        numpy.abs(focallength_nf),
                                                        input_parameters.ghy_fftnpts))

        print("NF: creating plane wave begin, fftsize = " +  str(fftsize))

        wavefront = Wavefront1D.initialize_wavefront_from_range(wavelength=calculation_parameters.gwavelength,
                                                                number_of_points=fftsize,
                                                                x_min=scale_factor*calculation_parameters.ghy_x_min,
                                                                x_max=scale_factor*calculation_parameters.ghy_x_max)

        if scale_factor == 1.0:
            try:
                wavefront.set_plane_wave_from_complex_amplitude(numpy.sqrt(calculation_parameters.wIray_x.interpolate_values(wavefront.get_abscissas())))
            except IndexError:
                raise Exception("Unexpected Error during interpolation: try reduce Number of bins for I(Sagittal) histogram")

        wavefront.apply_ideal_lens(focallength_nf)

        if input_parameters.ghy_calcType == 3 or \
                (input_parameters.ghy_calcType == 2 and not global_phase_shift_profile is None):
           wavefront.add_phase_shifts(get_mirror_phase_shift(wavefront.get_abscissas(),
                                                             calculation_parameters.gwavelength,
                                                             calculation_parameters.wangle_x,
                                                             calculation_parameters.wl_x,
                                                             global_phase_shift_profile))
        elif input_parameters.ghy_calcType == 4:
           wavefront.add_phase_shifts(get_grating_phase_shift(wavefront.get_abscissas(),
                                                              calculation_parameters.gwavelength,
                                                              calculation_parameters.wangle_x,
                                                              calculation_parameters.wangle_ref_x,
                                                              calculation_parameters.wl_x,
                                                              global_phase_shift_profile))

        print("calculated plane wave: begin NF propagation (distance = " + str(input_parameters.ghy_distance) + ")")

        propagated_wavefront = propagator.propagate_1D_fresnel(wavefront, input_parameters.ghy_distance)

        # ghy_npeak in the wavefront propagation image
        imagesize = (input_parameters.ghy_npeak * 2 * 0.88 * calculation_parameters.gwavelength * numpy.abs(focallength_nf) / abs(calculation_parameters.ghy_x_max - calculation_parameters.ghy_x_min))
        imagesize = max(imagesize,
                        2 * abs((calculation_parameters.ghy_x_max - calculation_parameters.ghy_x_min) * (input_parameters.ghy_distance - numpy.abs(focallength_nf))) / numpy.abs(focallength_nf))

        if input_parameters.ghy_calcType == 3:
            imagesize = max(imagesize,
                            16 * rms_slope * numpy.abs(focallength_nf) * numpy.sin(average_incident_angle / 1e3))
        elif input_parameters.ghy_calcType == 4:
            imagesize = max(imagesize,
                            8 * rms_slope * numpy.abs(focallength_nf) * (numpy.sin(average_incident_angle / 1e3) + numpy.sin(average_reflection_angle / 1e3)))

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

        imagenpts = int(round(imagesize / propagated_wavefront.delta() / 2) * 2 + 1)

        print("dif_x: begin calculation")

        dif_x = ScaledArray.initialize_from_range(numpy.ones(imagenpts),
                                                  -(imagenpts - 1) / 2 * propagated_wavefront.delta(),
                                                  (imagenpts - 1) / 2 * propagated_wavefront.delta())

        dif_x.np_array *= numpy.absolute(propagated_wavefront.get_interpolated_complex_amplitudes(dif_x.scale))**2

        calculation_parameters.dif_x = dif_x