def initialize_wavefront_from_range(cls, x_min=0.0, x_max=0.0, y_min=0.0, y_max=0.0, number_of_points=(100, 100), wavelength=1e-10, polarization=Polarization.SIGMA): sM = ScaledMatrix.initialize_from_range(numpy.full(number_of_points, (1.0 + 0.0j), dtype=complex), x_min, x_max, y_min, y_max, interpolator=False) if ((polarization == Polarization.PI) or (polarization == Polarization.SIGMA)): sMpi = ScaledMatrix.initialize_from_range(numpy.full( number_of_points, (1.0 + 0.0j), dtype=complex), x_min, x_max, y_min, y_max, interpolator=False) else: sMpi = None return Wavefront2D(wavelength, sM, sMpi)
def test_ScaledMatrix(self,do_plot=do_plot): # # Matrix # x = numpy.arange(10,20,2.0) y = numpy.arange(20,25,1.0) xy = numpy.meshgrid(x,y) X = xy[0].T Y = xy[1].T Z = Y print("x,y,X,Y,Z shapes: ",x.shape,y.shape,X.shape,Y.shape,Z.shape) print("x,y,X,Y,Z shapes: ",x.shape,y.shape,X.shape,Y.shape,Z.shape) # # scaledMatrix.initialize + set_scale_from_steps # print("\nTesting ScaledMatrix.initialize + set_scale_from_steps...") scaled_matrix = ScaledMatrix.initialize(Z) print(" Matrix shape", scaled_matrix.shape()) scaled_matrix.set_scale_from_steps(0,x[0],numpy.abs(x[1]-x[0])) scaled_matrix.set_scale_from_steps(1,y[0],numpy.abs(y[1]-y[0])) print("Original x: ",x) print("Stored x: ",scaled_matrix.get_x_values()) print("Original y: ",y) print("Stored y: ",scaled_matrix.get_y_values()) numpy.testing.assert_equal(x,scaled_matrix.get_x_values()) numpy.testing.assert_equal(y,scaled_matrix.get_y_values()) print(" Matrix X value x=0 : ", scaled_matrix.get_x_value(0.0)) print(" Matrix Y value x_index=3 is %g (to compare with %g) "%(scaled_matrix.get_x_value(2.0),x[0]+2*(x[1]-x[0]))) print(" Matrix Y value y_index=3 is %g (to compare with %g) "%(scaled_matrix.get_y_value(2.0),y[0]+2*(y[1]-y[0]))) self.assertAlmostEqual(scaled_matrix.get_x_value(2.0),x[0]+2*(x[1]-x[0]),10) self.assertAlmostEqual(scaled_matrix.get_y_value(2.0),y[0]+2*(y[1]-y[0]),10) # # scaledMatrix.initialize + set_scale_from_range # x = numpy.linspace(-10,10,10) y = numpy.linspace(-25,25,20) xy = numpy.meshgrid(x,y) X = xy[0].T Y = xy[1].T Z = Y print("\nTesting ScaledMatrix.initialize + set_scale_from_range...") scaled_matrix = ScaledMatrix.initialize(Z) # Z[0] contains Y print(" Matrix shape", scaled_matrix.shape()) scaled_matrix.set_scale_from_range(0,x[0],x[-1]) scaled_matrix.set_scale_from_range(1,y[0],y[-1]) print("Original x: ",x) print("Stored x: ",scaled_matrix.get_x_values()) print("Original y: ",y) print("Stored y: ",scaled_matrix.get_y_values()) numpy.testing.assert_almost_equal(x,scaled_matrix.get_x_values(),11) numpy.testing.assert_almost_equal(y,scaled_matrix.get_y_values(),11) print(" Matrix X value x=0 : ", scaled_matrix.get_x_value(0.0)) print(" Matrix Y value x_index=5 is %g (to compare with %g) "%(scaled_matrix.get_x_value(5.0),x[0]+5*(x[1]-x[0]))) print(" Matrix Y value y_index=5 is %g (to compare with %g) "%(scaled_matrix.get_y_value(5.0),y[0]+5*(y[1]-y[0]))) self.assertAlmostEqual(scaled_matrix.get_x_value(5.0),x[0]+5*(x[1]-x[0]),10) self.assertAlmostEqual(scaled_matrix.get_y_value(5.0),y[0]+5*(y[1]-y[0]),10) # # scaledMatrix.initialize_from_steps # x = numpy.arange(10,20,0.2) y = numpy.arange(20,25,0.1) xy = numpy.meshgrid(x,y) X = xy[0].T Y = xy[1].T Z = Y print("\nTesting ScaledMatrix.initialize_from_steps...") scaled_matrix2 = ScaledMatrix.initialize_from_steps(Z,x[0],numpy.abs(x[1]-x[0]),y[0],numpy.abs(y[1]-y[0])) print(" Matrix 2 shape", scaled_matrix2.shape()) print(" Matrix 2 value x=0 : ", scaled_matrix2.get_x_value(0.0)) print(" Matrix 2 value x=5 is %g (to compare with %g) "%(scaled_matrix2.get_x_value(5.0),x[0]+5*(x[1]-x[0]))) self.assertAlmostEqual(scaled_matrix2.get_x_value(5.0),x[0]+5*(x[1]-x[0])) print(" Matrix 2 value y=5 is %g (to compare with %g) "%(scaled_matrix2.get_y_value(5.0),y[0]+5*(y[1]-y[0]))) self.assertAlmostEqual(scaled_matrix2.get_y_value(5.0),y[0]+5*(y[1]-y[0])) # # scaledMatrix.initialize_from_range # print("\nTesting ScaledMatrix.initialize_from_range...") x = numpy.linspace(-10,10,20) y = numpy.linspace(-25,25,30) xy = numpy.meshgrid(x,y) X = xy[0].T Y = xy[1].T Z = X*0+(3+2j) # scaled_matrix3 = ScaledMatrix.initialize_from_range(Z,x[0],x[-1],y[0],y[-1]) print("Matrix 3 shape", scaled_matrix3.shape()) print("Matrix 3 value x=0 : ", scaled_matrix3.get_x_value(0.0)) print("Matrix 3 value x=15 is %g (to compare with %g) "%(scaled_matrix3.get_x_value(15.0),x[0]+15*(x[1]-x[0]))) self.assertAlmostEqual(scaled_matrix3.get_x_value(15.0),x[0]+15*(x[1]-x[0])) print("Matrix 3 value y=15 is %g (to compare with %g) "%(scaled_matrix3.get_y_value(15.0),y[0]+15*(y[1]-y[0]))) self.assertAlmostEqual(scaled_matrix3.get_y_value(15.0),y[0]+15*(y[1]-y[0])) # print("Matrix 3 X : ", scaled_matrix3.get_x_values()) # print("Matrix 3 Y : ", scaled_matrix3.get_y_values()) # print("Matrix 3 Z : ", scaled_matrix3.get_z_values()) # # interpolator # print("\nTesting interpolator on the same grid...") # constant Z = X * Y scaled_matrix4 = ScaledMatrix.initialize_from_range(Z,x[0],x[-1],y[0],y[-1]) scaled_matrix4.compute_interpolator() print("Matrix 4 interpolation x=110,y=210 is ",scaled_matrix4.interpolate_value(110,210)) # interpolate in the same grid s4int = scaled_matrix4.interpolate_value(X,Y) print("Matrix 4 interpolation same grid (shape)",s4int.shape," before: ",scaled_matrix4.shape()) numpy.testing.assert_almost_equal(scaled_matrix4.get_z_values(),s4int,3) print("\nTesting interpolator on a grid with less points...") # interpolate in a grid with much less points xrebin = numpy.linspace(x[0],x[-1],x.size/10) yrebin = numpy.linspace(y[0],y[-1],y.size/10) xyrebin =numpy.meshgrid( xrebin, yrebin) Xrebin = xyrebin[0].T Yrebin = xyrebin[1].T s4rebin = scaled_matrix4.interpolate_value(Xrebin,Yrebin) if do_plot == 1: from srxraylib.plot.gol import plot_image plot_image(scaled_matrix4.get_z_values(),scaled_matrix4.get_x_values(),scaled_matrix4.get_y_values(), title="Original",show=0) plot_image(numpy.real(s4int),scaled_matrix4.get_x_values(),scaled_matrix4.get_y_values(), title="Interpolated on same grid",show=0) plot_image(numpy.real(s4rebin),xrebin,yrebin, title="Interpolated on a grid with 10 times less points") for xi in xrebin: for yi in yrebin: yint = scaled_matrix4.interpolate_value(xi,yi) print(" Interpolated at (%g,%g) is %g+%gi (expected %g)"%(xi,yi,yint.real,yint.imag,xi*yi)) self.assertAlmostEqual(scaled_matrix4.interpolate_value(xi,yi),xi*yi)
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
def initialize_wavefront_from_range(cls, x_min=0.0, x_max=0.0, y_min=0.0, y_max=0.0, number_of_points=(100,100), wavelength=1e-10 ): return Wavefront2D(wavelength, ScaledMatrix.initialize_from_range( \ numpy.full(number_of_points, (1.0 + 0.0j), dtype=complex), x_min,x_max,y_min,y_max,interpolator=False))