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