def test_simple_gauusina_propagation(): # TODO: fix propagation for coerrect results import sys sys.path.insert(0, "..") import os import wpg from wpg.generators import build_gauss_wavefront from wpg.beamline import Beamline from wpg.optical_elements import Drift, Use_PP from wpg.srwlib import srwl import numpy as np d2waist = 270.0 # beam parameters: qnC = 0.1 # [nC] e-bunch charge thetaOM = 3.6e-3 ekev = 5.0 # calculate angular divergence: theta_fwhm = (17.2 - 6.4 * np.sqrt(qnC)) * 1e-6 / ekev**0.85 theta_rms = theta_fwhm / 2.35 sigX = 12.4e-10 / (ekev * 4 * np.pi * theta_rms) # define limits xmax = theta_rms * d2waist * 3.5 xmin = -xmax ymin = xmin ymax = xmax nx = 300 ny = nx nz = 3 tau = 0.12e-15 srw_wf = build_gauss_wavefront(nx, ny, nz, ekev, xmin, xmax, ymin, ymax, tau, sigX, sigX, d2waist) wf = wpg.Wavefront(srw_wf) b = Beamline() b.append(Drift(5), Use_PP()) srwl.SetRepresElecField(wf._srwl_wf, "f") b.propagate(wf) srwl.SetRepresElecField(wf._srwl_wf, "c") srwl.ResizeElecField(srw_wf, "c", [0, 0.25, 1, 0.25, 1]) ti = wf.get_intensity() out_folder = os.path.join(os.path.dirname(__file__), "tests_data") if not os.path.exists(out_folder): os.mkdir(out_folder) wf_hdf5_out_file_path = os.path.join(out_folder, "my_gauss.h5") wf.store_hdf5(wf_hdf5_out_file_path) wf_out = wpg.Wavefront() wf_out.load_hdf5(wf_hdf5_out_file_path) return wf
def get_beamline(): """ Setup and return the WPG.Beamline object representing the SPB/SFX nanofocus beamline (KB mirrors). :return: beamline :rtype beamline: wpg.Beamline """ ### Geometry ### src_to_hom1 = 257.8 # Distance source to HOM 1 [m] src_to_hom2 = 267.8 # Distance source to HOM 2 [m] src_to_crl = 887.8 # Distance source to CRL [m] src_to_exp = 920.42 # Distance source to experiment [m] #Incidence angle at HOM theta_om = 3.6e-3 # [rad] om_mirror_length = 0.8 # [m] om_clear_ap = om_mirror_length * theta_om #define the beamline: beamline = Beamline() zoom = 1 # Define HOM1 = Aperture + Wavefront distortion. aperture_x_to_y_ratio = 1 hom1_aperture = Aperture(shape='r', ap_or_ob='a', Dx=om_clear_ap, Dy=om_clear_ap / aperture_x_to_y_ratio) # Append to beamline. beamline.append( hom1_aperture, Use_PP(semi_analytical_treatment=0, zoom=zoom, sampling=zoom)) # Free space propagation from hom1 to hom2 hom1_to_hom2_drift = Drift(src_to_hom2 - src_to_hom1) beamline.append(hom1_to_hom2_drift, Use_PP(semi_analytical_treatment=0)) # Define HOM2. zoom = 1.0 hom2_aperture = Aperture('r', 'a', om_clear_ap, om_clear_ap / aperture_x_to_y_ratio) beamline.append( hom2_aperture, Use_PP(semi_analytical_treatment=0, zoom=zoom, sampling=zoom)) #drift to CRL aperture hom2_to_crl_drift = Drift(src_to_crl - src_to_hom2) beamline.append(hom2_to_crl_drift, Use_PP(semi_analytical_treatment=1)) # Circular Aperture before CRL. crl_front_aperture_diameter = 2.8e-3 crl_front_aperture = Aperture('c', 'a', crl_front_aperture_diameter, crl_front_aperture_diameter) ### Define CRL crl_focussing_plane = 3 # Both horizontal and vertical. crl_delta = 4.8308e-06 # Refractive index decrement (n = 1- delta - i*beta) @ 8.4 keV crl_attenuation_length = 6.053e-3 # Attenuation length [m], Henke data. crl_shape = 1 # Parabolic lenses crl_aperture = 3.0e-3 # [m] crl_curvature_radius = 5.8e-3 # [m] crl_number_of_lenses = 19 crl_wall_thickness = 8.0e-5 # Thickness crl_center_horizontal_coordinate = 0.0 crl_center_vertical_coordinate = 0.0 crl_initial_photon_energy = 8.48e3 # [eV] crl_final_photon_energy = 8.52e3 # [eV] crl = CRL( _foc_plane=crl_focussing_plane, _delta=crl_delta, _atten_len=crl_attenuation_length, _shape=crl_shape, _apert_h=crl_aperture, _apert_v=crl_aperture, _r_min=crl_curvature_radius, _n=crl_number_of_lenses, _wall_thick=crl_wall_thickness, _xc=crl_center_horizontal_coordinate, _yc=crl_center_vertical_coordinate, _void_cen_rad=None, _e_start=crl_initial_photon_energy, _e_fin=crl_final_photon_energy, ) zoom = 0.6 beamline.append( crl_front_aperture, Use_PP(semi_analytical_treatment=0, zoom=zoom, sampling=zoom / 0.1)) beamline.append(crl, Use_PP(semi_analytical_treatment=0, zoom=1, sampling=1)) # Drift to focus aperture crl_to_exp_drift = Drift(src_to_exp - src_to_crl) beamline.append(crl_to_exp_drift, Use_PP(semi_analytical_treatment=1, zoom=1, sampling=1)) return beamline
def get_beamline(): import os import wpg from wpg import Beamline from wpg.optical_elements import Aperture, Drift, CRL, Empty, Use_PP, WF_dist, calculateOPD wpg_path = os.path.abspath(os.path.dirname(wpg.__file__)) # S1 beamline layout # Geometry ### src_to_hom1 = 257.8 # Distance source to HOM 1 [m] src_to_hom2 = 267.8 # Distance source to HOM 2 [m] src_to_crl = 887.8 # Distance source to CRL [m] # src_to_exp = 920.42 # Distance source to experiment [m] # Drift to focus aperture # crl_to_exp_drift = Drift( src_to_exp - src_to_crl ) z = 34.0 # define distances, angles, etc # ... # Incidence angle at HOM # should be checked for other beams !!! theta_om = 3.6e-3 # [rad] om_mirror_length = 0.8 # [m] om_clear_ap = om_mirror_length * theta_om # define the beamline: bl0 = Beamline() zoom = 1 # Define HOM1. aperture_x_to_y_ratio = 1 hom1 = Aperture(shape='r', ap_or_ob='a', Dx=om_clear_ap, Dy=om_clear_ap / aperture_x_to_y_ratio) bl0.append(hom1, Use_PP(semi_analytical_treatment=0, zoom=zoom, sampling=zoom)) # Define mirror profile hom1_wavefront_distortion = WF_dist(nx=1500, ny=100, Dx=om_clear_ap, Dy=om_clear_ap / aperture_x_to_y_ratio) # Apply distortion. mirrors_path = os.path.join(wpg_path, '..', 'samples', 'data_common') hom1_wavefront_distortion = calculateOPD(wf_dist=hom1_wavefront_distortion, mdatafile=os.path.join( mirrors_path, 'mirror1.dat'), ncol=2, delim=' ', Orient='x', theta=theta_om, scale=1., stretching=1.) bl0.append(hom1_wavefront_distortion, Use_PP(semi_analytical_treatment=0, zoom=zoom, sampling=zoom)) # Free space propagation from hom1 to hom2 hom1_to_hom2_drift = Drift(src_to_hom2 - src_to_hom1) bl0.append(hom1_to_hom2_drift, Use_PP(semi_analytical_treatment=0)) # Define HOM2. zoom = 1.0 hom2 = Aperture('r', 'a', om_clear_ap, om_clear_ap / aperture_x_to_y_ratio) bl0.append( hom2, Use_PP(semi_analytical_treatment=0, zoom=zoom, sampling=zoom / 0.75)) # define mirror 2 # nx, ny from tutorial #3 (new). hom2_wavefront_distortion = WF_dist(nx=1500, ny=100, Dx=om_clear_ap, Dy=om_clear_ap / aperture_x_to_y_ratio) # Apply distortion. hom2_wavefront_distortion = calculateOPD(wf_dist=hom2_wavefront_distortion, mdatafile=os.path.join( mirrors_path, 'mirror2.dat'), ncol=2, delim=' ', Orient='x', theta=theta_om, scale=1., stretching=1.) bl0.append(hom2_wavefront_distortion, Use_PP(semi_analytical_treatment=0, zoom=zoom, sampling=zoom)) # drift to CRL aperture hom2_to_crl_drift = Drift(src_to_crl - src_to_hom2) bl0.append(hom2_to_crl_drift, Use_PP(semi_analytical_treatment=1)) # Define CRL crl_focussing_plane = 3 # Both horizontal and vertical. # Refractive index decrement (n = 1- delta - i*beta) crl_delta = 4.7177e-06 crl_attenuation_length = 6.3e-3 # Attenuation length [m], Henke data. crl_shape = 1 # Parabolic lenses crl_aperture = 5.0e-3 # [m] crl_curvature_radius = 5.8e-3 # [m] crl_number_of_lenses = 19 crl_wall_thickness = 8.0e-5 # Thickness crl_center_horizontal_coordinate = 0.0 crl_center_vertical_coordinate = 0.0 crl_initial_photon_energy = 8.48e3 # [eV] ### OK ??? crl_final_photon_energy = 8.52e3 # [eV] ### OK ??? crl = CRL( _foc_plane=crl_focussing_plane, _delta=crl_delta, _atten_len=crl_attenuation_length, _shape=crl_shape, _apert_h=crl_aperture, _apert_v=crl_aperture, _r_min=crl_curvature_radius, _n=crl_number_of_lenses, _wall_thick=crl_wall_thickness, _xc=crl_center_horizontal_coordinate, _yc=crl_center_vertical_coordinate, _void_cen_rad=None, _e_start=crl_initial_photon_energy, _e_fin=crl_final_photon_energy, ) zoom = 0.6 bl0.append( crl, Use_PP(semi_analytical_treatment=1, zoom=zoom, sampling=zoom / 0.1)) crl_to_exp_drift = Drift(z) bl0.append(crl_to_exp_drift, Use_PP(semi_analytical_treatment=1, zoom=1, sampling=1)) # bl0.append(Empty(),Use_PP(zoom=0.25, sampling=0.25)) return bl0
def testGaussianReference(self, debug=False): """ Check that propagation of a Gaussian pulse (in t,x,y) through vacuum reproduces reference data. """ # Central photon energy. ekev = 8.4 # Energy [keV] # Pulse parameters. qnC = 0.5 # e-bunch charge, [nC] pulse_duration = 9.0e-15 # [s] pulseEnergy = 1.5e-3 # total pulse energy, J # Coherence time coh_time = 0.25e-15 # [s] # Distance in free space. z0 = 10. # (m), position where to build the wavefront. z1 = 10. # (m), distance to travel in free space. # Beam divergence. theta_fwhm = 2.5e-6 # rad wlambda = 12.4*1e-10/ekev # wavelength, m w0 = wlambda/(numpy.pi*theta_fwhm) # beam waist, m zR = (math.pi*w0**2)/wlambda #Rayleigh range, m fwhm_at_zR = theta_fwhm*zR #FWHM at Rayleigh range, m sigmaAmp = w0/(2.0*math.sqrt(math.log(2.0))) #sigma of amplitude, m if debug: print (" *** Pulse properties ***") print (" lambda = %4.3e m" % (wlambda) ) print (" w0 = %4.3e m" % (w0) ) print (" zR = %4.3e m" % (zR) ) print (" fwhm at zR = %4.3e m" % (fwhm_at_zR) ) print (" sigma = %4.3e m" % (sigmaAmp) ) # expected beam radius after free space drift. expected_beam_radius = w0*math.sqrt(1.0+(z0/zR)**2) # Number of points in each x and y dimension. np=400 # Sampling window = 6 sigma of initial beam. range_xy = 6.*expected_beam_radius dx = range_xy / (np-1) nslices = 20 if debug: print (" Expected beam waist at z=%4.3f m : %4.3e m." % (z0, expected_beam_radius) ) print ("Setting up mesh of %d points per dimension on a %4.3e x %4.3e m^2 grid with grid spacing %4.3e m." % (np, range_xy, range_xy, dx) ) # Construct srw wavefront. srwl_wf = build_gauss_wavefront(np, np, nslices, ekev, -range_xy/2., range_xy/2., -range_xy/2., range_xy/2., coh_time/math.sqrt(2.), sigmaAmp, sigmaAmp, z0, pulseEn=pulseEnergy, pulseRange=8.) # Convert to wpg. wf = Wavefront(srwl_wf) if debug: print('*** z=%4.3e m ***' % (z0)) fwhm = calculate_fwhm(wf) print('fwhm_x = %4.3e\nfwhm_y = %4.3e' % (fwhm['fwhm_x'], fwhm['fwhm_y']) ) plot_t_wf(wf) look_at_q_space(wf) # Construct the beamline. beamline = Beamline() # Add free space drift. drift = Drift(z1) beamline.append( drift, Use_PP(semi_analytical_treatment=1)) # Propagate srwl.SetRepresElecField(wf._srwl_wf, 'f') # <---- switch to frequency domain beamline.propagate(wf) srwl.SetRepresElecField(wf._srwl_wf, 't') if debug: print('*** z=%4.3e m ***' % (z0+z1)) fwhm = calculate_fwhm(wf) print('fwhm_x = %4.3e\nfwhm_y = %4.3e' % (fwhm['fwhm_x'], fwhm['fwhm_y']) ) plot_t_wf(wf) look_at_q_space(wf) # Get propagated wavefront data. wf_intensity = wf.get_intensity() # Project on t axis. wf_onaxis = wf_intensity.sum(axis=(0,1)) # Get hash of the data. wf_hash = hash( wf_intensity.tostring() ) # Load reference hash. with open(TestUtilities.generateTestFilePath("reference_wf_gauss_10m.hash.txt"), 'r') as hashfile: ref_hash = hashfile.readline() hashfile.close() ref_onaxis = numpy.loadtxt(TestUtilities.generateTestFilePath("reference_wf_gauss_onaxis_10m.txt")) # Weak test. for x,y in zip(wf_onaxis, ref_onaxis): self.assertAlmostEqual( x, y, 14 ) # Strong test. self.assertEqual( str(wf_hash), ref_hash)
def testGaussianVsAnalytic(self, debug=False): """ Check that propagation of a Gaussian pulse (in t,x,y) through vacuum gives the correct result, compare to analytic solution. """ # Central photon energy. ekev = 8.4 # Energy [keV] # Pulse parameters. qnC = 0.5 # e-bunch charge, [nC] pulse_duration = 9.0e-15 # [s] pulseEnergy = 1.5e-3 # total pulse energy, J # Coherence time coh_time = 0.25e-15 # [s] # Distance in free space. z0 = 10. # (m), position where to build the wavefront. z1 = 20. # (m), distance to travel in free space. z2 = z0 + z1 # distance where to build the reference wavefront. # Beam divergence. theta_fwhm = 2.5e-6 # rad wlambda = 12.4*1e-10/ekev # wavelength, m w0 = wlambda/(numpy.pi*theta_fwhm) # beam waist, m zR = (math.pi*w0**2)/wlambda #Rayleigh range, m fwhm_at_zR = theta_fwhm*zR #FWHM at Rayleigh range, m sigmaAmp = w0/(2.0*math.sqrt(math.log(2.0))) #sigma of amplitude, m if debug: print (" *** Pulse properties ***") print (" lambda = %4.3e m" % (wlambda) ) print (" w0 = %4.3e m" % (w0) ) print (" zR = %4.3e m" % (zR) ) print (" fwhm at zR = %4.3e m" % (fwhm_at_zR) ) print (" sigma = %4.3e m" % (sigmaAmp) ) # expected beam radius after free space drift. expected_beam_radius = w0*math.sqrt(1.0+(z0/zR)**2) # Number of points in each x and y dimension. np=600 # Sampling window = 6 sigma of initial beam. range_xy = 6.*expected_beam_radius dx = range_xy / (np-1) nslices = 20 #if debug: #print (" Expected beam waist at z=%4.3f m : %4.3e m." % (z0, expected_beam_radius) ) #print ("Setting up mesh of %d points per dimension on a %4.3e x %4.3e m^2 grid with grid spacing %4.3e m." % (np, range_xy, range_xy, dx) ) # Construct srw wavefront. srwl_wf = build_gauss_wavefront(np, np, nslices, ekev, -range_xy/2., range_xy/2., -range_xy/2., range_xy/2., coh_time/math.sqrt(2.), sigmaAmp, sigmaAmp, z0, pulseEn=pulseEnergy, pulseRange=8.) # Convert to wpg. wf = Wavefront(srwl_wf) # Construct reference srw wavefront. reference_srwl_wf = build_gauss_wavefront(np, np, nslices, ekev, -1.5*range_xy/2., 1.5*range_xy/2., -1.5*range_xy/2., 1.5*range_xy/2., coh_time/math.sqrt(2.), sigmaAmp, sigmaAmp, z2, pulseEn=pulseEnergy, pulseRange=8.) reference_wf = Wavefront(reference_srwl_wf) if debug: print('*** z=%4.3e m ***' % (z0)) fwhm = calculate_fwhm(wf) print('wf:\nfwhm_x = %4.3e\nfwhm_y = %4.3e' % (fwhm['fwhm_x'], fwhm['fwhm_y']) ) plot_t_wf(wf) #look_at_q_space(wf) # Construct the beamline. beamline = Beamline() # Add free space drift. drift = Drift(z1) beamline.append( drift, Use_PP(semi_analytical_treatment=0, zoom=2.0, sampling=0.5)) # Propagate srwl.SetRepresElecField(wf._srwl_wf, 'f') beamline.propagate(wf) srwl.SetRepresElecField(wf._srwl_wf, 't') fwhm = calculate_fwhm(wf) reference_fwhm = calculate_fwhm(reference_wf) if debug: print('*** z=%4.3e m ***' % (z0+z1)) print('wf :\nfwhm_x = %4.3e\nfwhm_y = %4.3e' % (fwhm['fwhm_x'], fwhm['fwhm_y']) ) plot_t_wf(wf) print('ref:\nfwhm_x = %4.3e\nfwhm_y = %4.3e' % (reference_fwhm['fwhm_x'], reference_fwhm['fwhm_y']) ) plot_t_wf(reference_wf) #look_at_q_space(wf) # Calculate difference reference_norm = numpy.linalg.norm(numpy.array([reference_fwhm['fwhm_x'], reference_fwhm['fwhm_y']])) difference_norm = numpy.linalg.norm(numpy.array([fwhm['fwhm_x'], fwhm['fwhm_y']]) - numpy.array([reference_fwhm['fwhm_x'], reference_fwhm['fwhm_y']])) if debug: print ("|ref_fwhm_xy| = %4.3e" % (reference_norm) ) print ("|ref_fwhm_xy - fhwm_xy| = %4.3e" % (difference_norm) ) self.assertLess(difference_norm / reference_norm, 0.01)
def get_beamline(): from wpg import Beamline from wpg.optical_elements import Aperture, Drift, CRL, Empty, Use_PP # S1 beamline layout ### Geometry ### src_to_hom1 = 257.8 # Distance source to HOM 1 [m] src_to_hom2 = 267.8 # Distance source to HOM 2 [m] src_to_crl = 887.8 # Distance source to CRL [m] # src_to_exp = 920.42 # Distance source to experiment [m] z0 = src_to_hom1 # Drift to focus aperture # crl_to_exp_drift = Drift( src_to_exp - src_to_crl ) z = 34.0 # define distances, angles, etc # ... # Incidence angle at HOM theta_om = 3.6e-3 # [rad] om_mirror_length = 0.8 # [m] om_clear_ap = om_mirror_length * theta_om # define the beamline: bl0 = Beamline() zoom = 1 # Define HOM1. aperture_x_to_y_ratio = 1 hom1 = Aperture(shape="r", ap_or_ob="a", Dx=om_clear_ap, Dy=om_clear_ap / aperture_x_to_y_ratio) bl0.append(hom1, Use_PP(semi_analytical_treatment=0, zoom=zoom, sampling=zoom)) # Free space propagation from hom1 to hom2 hom1_to_hom2_drift = Drift(src_to_hom2 - src_to_hom1) z0 = z0 + (src_to_hom2 - src_to_hom1) bl0.append(hom1_to_hom2_drift, Use_PP(semi_analytical_treatment=0)) # Define HOM2. zoom = 1.0 hom2 = Aperture("r", "a", om_clear_ap, om_clear_ap / aperture_x_to_y_ratio) bl0.append( hom2, Use_PP(semi_analytical_treatment=0, zoom=zoom, sampling=zoom / 0.75)) # drift to CRL aperture hom2_to_crl_drift = Drift(src_to_crl - src_to_hom2) z0 = z0 + (src_to_crl - src_to_hom2) # bl0.append( hom2_to_crl_drift, Use_PP(semi_analytical_treatment=0)) bl0.append(hom2_to_crl_drift, Use_PP(semi_analytical_treatment=1)) # Define CRL crl_focussing_plane = 3 # Both horizontal and vertical. crl_delta = 4.7177e-06 # Refractive index decrement (n = 1- delta - i*beta) crl_attenuation_length = 6.3e-3 # Attenuation length [m], Henke data. crl_shape = 1 # Parabolic lenses crl_aperture = 5.0e-3 # [m] crl_curvature_radius = 5.8e-3 # [m] crl_number_of_lenses = 19 crl_wall_thickness = 8.0e-5 # Thickness crl_center_horizontal_coordinate = 0.0 crl_center_vertical_coordinate = 0.0 crl_initial_photon_energy = 8.48e3 # [eV] ### OK ??? crl_final_photon_energy = 8.52e3 # [eV] ### OK ??? crl = CRL( _foc_plane=crl_focussing_plane, _delta=crl_delta, _atten_len=crl_attenuation_length, _shape=crl_shape, _apert_h=crl_aperture, _apert_v=crl_aperture, _r_min=crl_curvature_radius, _n=crl_number_of_lenses, _wall_thick=crl_wall_thickness, _xc=crl_center_horizontal_coordinate, _yc=crl_center_vertical_coordinate, _void_cen_rad=None, _e_start=crl_initial_photon_energy, _e_fin=crl_final_photon_energy, ) zoom = 0.6 bl0.append( crl, Use_PP(semi_analytical_treatment=1, zoom=zoom, sampling=zoom / 0.1)) crl_to_exp_drift = Drift(z) z0 = z0 + z bl0.append(crl_to_exp_drift, Use_PP(semi_analytical_treatment=1, zoom=1, sampling=1)) # bl0.append(Empty(),Use_PP(zoom=0.25, sampling=0.25)) return bl0
def get_beamline(): import os import wpg from wpg import Beamline from wpg.optical_elements import Aperture, Drift, CRL, Empty, Use_PP, WF_dist, calculateOPD wpg_path = os.path.abspath(os.path.dirname(wpg.__file__)) # S1 beamline layout # Geometry ### src_to_hom1 = 257.8 # Distance source to HOM 1 [m] src_to_hom2 = 267.8 # Distance source to HOM 2 [m] src_to_crl = 887.8 # Distance source to CRL [m] # src_to_exp = 920.42 # Distance source to experiment [m] # Drift to focus aperture # crl_to_exp_drift = Drift( src_to_exp - src_to_crl ) z = 34.0 # define distances, angles, etc # ... # Incidence angle at HOM # should be checked for other beams !!! theta_om = 3.6e-3 # [rad] om_mirror_length = 0.8 # [m] om_clear_ap = om_mirror_length * theta_om # define the beamline: bl0 = Beamline() zoom = 1 # Define HOM1. aperture_x_to_y_ratio = 1 hom1 = Aperture( shape='r', ap_or_ob='a', Dx=om_clear_ap, Dy=om_clear_ap / aperture_x_to_y_ratio) bl0.append( hom1, Use_PP(semi_analytical_treatment=0, zoom=zoom, sampling=zoom)) # Define mirror profile hom1_wavefront_distortion = WF_dist(nx=1500, ny=100, Dx=om_clear_ap, Dy=om_clear_ap / aperture_x_to_y_ratio) # Apply distortion. mirrors_path = os.path.join(wpg_path, '..', 'samples', 'data_common') hom1_wavefront_distortion = calculateOPD(wf_dist=hom1_wavefront_distortion, mdatafile=os.path.join( mirrors_path, 'mirror1.dat'), ncol=2, delim=' ', Orient='x', theta=theta_om, scale=1., stretching=1.) bl0.append(hom1_wavefront_distortion, Use_PP(semi_analytical_treatment=0, zoom=zoom, sampling=zoom)) # Free space propagation from hom1 to hom2 hom1_to_hom2_drift = Drift(src_to_hom2 - src_to_hom1) bl0.append(hom1_to_hom2_drift, Use_PP(semi_analytical_treatment=0)) # Define HOM2. zoom = 1.0 hom2 = Aperture('r', 'a', om_clear_ap, om_clear_ap / aperture_x_to_y_ratio) bl0.append(hom2, Use_PP(semi_analytical_treatment=0, zoom=zoom, sampling=zoom / 0.75)) # define mirror 2 # nx, ny from tutorial #3 (new). hom2_wavefront_distortion = WF_dist(nx=1500, ny=100, Dx=om_clear_ap, Dy=om_clear_ap / aperture_x_to_y_ratio) # Apply distortion. hom2_wavefront_distortion = calculateOPD(wf_dist=hom2_wavefront_distortion, mdatafile=os.path.join( mirrors_path, 'mirror2.dat'), ncol=2, delim=' ', Orient='x', theta=theta_om, scale=1., stretching=1.) bl0.append(hom2_wavefront_distortion, Use_PP( semi_analytical_treatment=0, zoom=zoom, sampling=zoom)) # drift to CRL aperture hom2_to_crl_drift = Drift(src_to_crl - src_to_hom2) bl0.append(hom2_to_crl_drift, Use_PP(semi_analytical_treatment=1)) # Define CRL crl_focussing_plane = 3 # Both horizontal and vertical. # Refractive index decrement (n = 1- delta - i*beta) crl_delta = 4.7177e-06 crl_attenuation_length = 6.3e-3 # Attenuation length [m], Henke data. crl_shape = 1 # Parabolic lenses crl_aperture = 5.0e-3 # [m] crl_curvature_radius = 5.8e-3 # [m] crl_number_of_lenses = 19 crl_wall_thickness = 8.0e-5 # Thickness crl_center_horizontal_coordinate = 0.0 crl_center_vertical_coordinate = 0.0 crl_initial_photon_energy = 8.48e3 # [eV] ### OK ??? crl_final_photon_energy = 8.52e3 # [eV] ### OK ??? crl = CRL(_foc_plane=crl_focussing_plane, _delta=crl_delta, _atten_len=crl_attenuation_length, _shape=crl_shape, _apert_h=crl_aperture, _apert_v=crl_aperture, _r_min=crl_curvature_radius, _n=crl_number_of_lenses, _wall_thick=crl_wall_thickness, _xc=crl_center_horizontal_coordinate, _yc=crl_center_vertical_coordinate, _void_cen_rad=None, _e_start=crl_initial_photon_energy, _e_fin=crl_final_photon_energy, ) zoom = 0.6 bl0.append( crl, Use_PP(semi_analytical_treatment=1, zoom=zoom, sampling=zoom/0.1)) crl_to_exp_drift = Drift(z) bl0.append(crl_to_exp_drift, Use_PP( semi_analytical_treatment=1, zoom=1, sampling=1)) # bl0.append(Empty(),Use_PP(zoom=0.25, sampling=0.25)) return bl0
def stepwise(in_fname, get_beamline): """ Propagate wavefront stepwise, dumping the wavefront at every step. :param in_file: input wavefront file :param get_beamline: function to build beamline """ print("#" * 80) print("Setup initial wavefront.") wf = Wavefront() # Load wavefront data. print("Load " + in_fname) wf.load_hdf5(in_fname) # Get beamline. bl0 = get_beamline() beamline = bl0.propagation_options if len(beamline) > 1: raise RuntimeError("Beamline configuration not supported.") beamline = beamline[0] elements = beamline["optical_elements"] options = beamline["propagation_parameters"] if len(elements) != len(options): raise RuntimeError("Beamline configuration not supported.") i = 0 for element, option in zip(elements, options): print("\n") print("#" * 80) print("Propagation step %d." % (i)) print("Setting up incremental beamline.") beamline_step = Beamline() beamline_step.append(element, option) ### <== CHECKME # Switch to frequency domain. wpg.srwlib.srwl.SetRepresElecField(wf._srwl_wf, "f") # Save spectrum for later reference. sz0 = get_intensity_on_axis(wf) wf.custom_fields["/misc/spectrum0"] = sz0 # Propagate. beamline_step.propagate(wf) # Save spectrum after propagation for later reference. sz1 = get_intensity_on_axis(wf) wf.custom_fields["/misc/spectrum1"] = sz1 # Switch back to time domain. wpg.srwlib.srwl.SetRepresElecField(wf._srwl_wf, "t") incremental_filename = "%04d.h5" % (i) print("Saving propagated wavefront to " + incremental_filename) mkdir_p(os.path.dirname(incremental_filename)) wf.store_hdf5(incremental_filename) print("Done with propagation step %d." % (i)) print("#" * 80) # Increment running index. i += 1
def get_beamline(): from wpg import Beamline from wpg.optical_elements import Aperture, Drift, CRL, Empty, Use_PP #S1 beamline layout ### Geometry ### src_to_hom1 = 257.8 # Distance source to HOM 1 [m] src_to_hom2 = 267.8 # Distance source to HOM 2 [m] src_to_crl = 887.8 # Distance source to CRL [m] # src_to_exp = 920.42 # Distance source to experiment [m] z0 = src_to_hom1 # Drift to focus aperture #crl_to_exp_drift = Drift( src_to_exp - src_to_crl ) z = 34.0 #define distances, angles, etc #... #Incidence angle at HOM theta_om = 3.6e-3 # [rad] om_mirror_length = 0.8 # [m] om_clear_ap = om_mirror_length*theta_om #define the beamline: bl0 = Beamline() zoom=1 # Define HOM1. aperture_x_to_y_ratio = 1 hom1 = Aperture(shape='r',ap_or_ob='a',Dx=om_clear_ap,Dy=om_clear_ap/aperture_x_to_y_ratio) bl0.append( hom1, Use_PP(semi_analytical_treatment=0, zoom=zoom, sampling=zoom) ) # Free space propagation from hom1 to hom2 hom1_to_hom2_drift = Drift(src_to_hom2 - src_to_hom1); z0 = z0+(src_to_hom2 - src_to_hom1) bl0.append( hom1_to_hom2_drift, Use_PP(semi_analytical_treatment=0)) # Define HOM2. zoom = 1.0 hom2 = Aperture('r','a', om_clear_ap, om_clear_ap/aperture_x_to_y_ratio) bl0.append( hom2, Use_PP(semi_analytical_treatment=0, zoom=zoom, sampling=zoom/0.75)) #drift to CRL aperture hom2_to_crl_drift = Drift( src_to_crl - src_to_hom2 );z0 = z0+( src_to_crl - src_to_hom2 ) #bl0.append( hom2_to_crl_drift, Use_PP(semi_analytical_treatment=0)) bl0.append( hom2_to_crl_drift, Use_PP(semi_analytical_treatment=1)) # Define CRL crl_focussing_plane = 3 # Both horizontal and vertical. crl_delta = 4.7177e-06 # Refractive index decrement (n = 1- delta - i*beta) crl_attenuation_length = 6.3e-3 # Attenuation length [m], Henke data. crl_shape = 1 # Parabolic lenses crl_aperture = 5.0e-3 # [m] crl_curvature_radius = 5.8e-3 # [m] crl_number_of_lenses = 19 crl_wall_thickness = 8.0e-5 # Thickness crl_center_horizontal_coordinate = 0.0 crl_center_vertical_coordinate = 0.0 crl_initial_photon_energy = 8.48e3 # [eV] ### OK ??? crl_final_photon_energy = 8.52e3 # [eV] ### OK ??? crl = CRL( _foc_plane=crl_focussing_plane, _delta=crl_delta, _atten_len=crl_attenuation_length, _shape=crl_shape, _apert_h=crl_aperture, _apert_v=crl_aperture, _r_min=crl_curvature_radius, _n=crl_number_of_lenses, _wall_thick=crl_wall_thickness, _xc=crl_center_horizontal_coordinate, _yc=crl_center_vertical_coordinate, _void_cen_rad=None, _e_start=crl_initial_photon_energy, _e_fin=crl_final_photon_energy, ) zoom=0.6 bl0.append( crl, Use_PP(semi_analytical_treatment=1, zoom=zoom, sampling=zoom/0.1) ) crl_to_exp_drift = Drift( z ); z0 = z0+z bl0.append( crl_to_exp_drift, Use_PP(semi_analytical_treatment=1, zoom=1, sampling=1)) # bl0.append(Empty(),Use_PP(zoom=0.25, sampling=0.25)) return bl0
def get_beamline(): """ Setup and return the WPG.Beamline object representing the SPB/SFX nanofocus beamline (KB mirrors). :return: beamline :rtype: wpg.Beamline """ # Distances distance0 = 246.5 distance1 = 683.5 distance = distance0 + distance1 # Focal lengths. f_hfm = 3.0 # nominal focal length for HFM KB f_vfm = 1.9 # nominal focal length for VFM KB distance_hfm_vfm = f_hfm - f_vfm distance_foc = 1. / (1. / f_vfm + 1. / (distance + distance_hfm_vfm)) # Mirror incidence angles theta_om = 3.5e-3 # offset mirrors incidence angle theta_kb = 3.5e-3 # KB mirrors incidence angle # Mirror lengths om_mirror_length = 0.8 om_clear_ap = om_mirror_length * theta_om kb_mirror_length = 0.9 kb_clear_ap = kb_mirror_length * theta_kb # Drifts. drift0 = optical_elements.Drift(distance0) drift1 = optical_elements.Drift(distance1) drift_in_kb = optical_elements.Drift(distance_hfm_vfm) drift_to_foc = optical_elements.Drift(distance_foc) # Mirror apertures. ap0 = optical_elements.Aperture('r', 'a', 5.0e-4, 5.0e-4) ap1 = optical_elements.Aperture('r', 'a', om_clear_ap, 2 * om_clear_ap) ap_kb = optical_elements.Aperture('r', 'a', kb_clear_ap, kb_clear_ap) # Mirror definitions. hfm = optical_elements.Mirror_elliptical(orient='x', p=distance, q=(distance_hfm_vfm + distance_foc), thetaE=theta_kb, theta0=theta_kb, length=0.9) vfm = optical_elements.Mirror_elliptical(orient='y', p=(distance + distance_hfm_vfm), q=distance_foc, thetaE=theta_kb, theta0=theta_kb, length=0.9) # Mirror profiles. wf_dist_om = optical_elements.Mirror_plane(orient='x', theta=theta_om, length=om_mirror_length, range_xy=2 * om_clear_ap, filename=os.path.join( mirror_data_dir, 'mirror2.dat'), scale=2., bPlot=False) wf_dist_hfm = optical_elements.Mirror_plane(orient='x', theta=theta_kb, length=kb_mirror_length, range_xy=kb_clear_ap, filename=os.path.join( mirror_data_dir, 'mirror1.dat'), scale=2., bPlot=False) wf_dist_vfm = optical_elements.Mirror_plane(orient='y', theta=theta_kb, length=kb_mirror_length, range_xy=kb_clear_ap, filename=os.path.join( mirror_data_dir, 'mirror2.dat'), scale=2., bPlot=False) # Assemble the beamline with PP parameters. bl0 = Beamline() ### Aperture to resample. Increase sampling frequency to get Fresnel zone between 7 and 10 px. bl0.append( ap0, Use_PP(semi_analytical_treatment=0, zoom=1.0, sampling=1. / 0.4)) #### Increase sampling again, reduce ROI => ROI ~10 fwhm, 700x700 sampling. bl0.append( drift0, Use_PP(semi_analytical_treatment=1, zoom=0.5, sampling=1.5 / 0.28)) #### bl0.append(ap1, Use_PP(zoom=1.0, sampling=1.0)) bl0.append(wf_dist_om, Use_PP()) ### bl0.append(drift1, Use_PP(semi_analytical_treatment=1, zoom=1.0, sampling=2.0)) ### bl0.append(ap_kb, Use_PP()) bl0.append(hfm, Use_PP()) bl0.append(wf_dist_hfm, Use_PP()) ### bl0.append(drift_in_kb, Use_PP(semi_analytical_treatment=1)) bl0.append(vfm, Use_PP()) bl0.append(wf_dist_vfm, Use_PP()) ### bl0.append( drift_to_foc, Use_PP(semi_analytical_treatment=1, zoom_h=0.1, sampling_h=1.2, zoom_v=0.05, sampling_v=1.2)) ###bl0.append(ap0, Use_PP(semi_analytical_treatment=0, ## #zoom=14.4, ## #sampling=1/1.6)) ###bl0.append(drift0,Use_PP(semi_analytical_treatment=0)) ###bl0.append(ap1, Use_PP(zoom=0.8)) ###bl0.append(wf_dist_om, Use_PP()) ###bl0.append(drift1, Use_PP(semi_analytical_treatment=1)) ###bl0.append(ap_kb, Use_PP(zoom = 6.4, sampling = 1/16.)) ###bl0.append(hfm, Use_PP()) ###bl0.append(wf_dist_hfm, Use_PP()) ###bl0.append(drift_in_kb, Use_PP(semi_analytical_treatment=1)) ###bl0.append(vfm, Use_PP()) ###bl0.append(wf_dist_vfm, Use_PP()) ###bl0.append(drift_to_foc, Use_PP(semi_analytical_treatment=1)) # All done, return. return bl0
def get_beamline(): """ Setup and return the WPG.Beamline object representing the SPB/SFX nanofocus beamline (KB mirrors). :return: beamline :rtype: wpg.Beamline """ # Distances distance0 = 300.0 distance1 = 630.0 distance = distance0 + distance1 # Focal lengths. f_hfm = 3.0 # nominal focal length for HFM KB f_vfm = 1.9 # nominal focal length for VFM KB distance_hfm_vfm = f_hfm - f_vfm distance_foc = 1. /(1./f_vfm + 1. / (distance + distance_hfm_vfm)) # Mirror incidence angles theta_om = 3.5e-3 # offset mirrors incidence angle theta_kb = 3.5e-3 # KB mirrors incidence angle # Mirror lengths om_mirror_length = 0.8; om_clear_ap = om_mirror_length*theta_om kb_mirror_length = 0.9; kb_clear_ap = kb_mirror_length*theta_kb # Drifts. drift0 = optical_elements.Drift(distance0) drift1 = optical_elements.Drift(distance1) drift_in_kb = optical_elements.Drift(distance_hfm_vfm) drift_to_foc = optical_elements.Drift(distance_foc) # Mirror apertures. ap0 = optical_elements.Aperture('r','a', 120.e-6, 120.e-6) ap1 = optical_elements.Aperture('r','a', om_clear_ap, 2*om_clear_ap) ap_kb = optical_elements.Aperture('r','a', kb_clear_ap, kb_clear_ap) # Mirror definitions. hfm = optical_elements.Mirror_elliptical( orient='x', p=distance, q=(distance_hfm_vfm+distance_foc), thetaE=theta_kb, theta0=theta_kb, length=kb_mirror_length, ) vfm = optical_elements.Mirror_elliptical( orient='y', p=(distance+distance_hfm_vfm), q=distance_foc, thetaE=theta_kb, theta0=theta_kb, length=kb_mirror_length, ) # Mirror profiles. wf_dist_om = optical_elements.Mirror_plane(orient='x', theta=theta_om, length=om_mirror_length, range_xy=2*om_clear_ap, filename=os.path.join(mirror_data_dir, 'mirror2.dat'), scale=2., bPlot=False) wf_dist_hfm = optical_elements.Mirror_plane(orient='x', theta=theta_kb, length=kb_mirror_length, range_xy=kb_clear_ap, filename=os.path.join(mirror_data_dir, 'mirror1.dat'), scale=2., bPlot=False) wf_dist_vfm = optical_elements.Mirror_plane(orient='y', theta=theta_kb, length=kb_mirror_length, range_xy=kb_clear_ap, filename=os.path.join(mirror_data_dir, 'mirror2.dat'), scale=2., bPlot=False) # Assemble the beamline with PP parameters. bl0 = Beamline() bl0.append(ap0, Use_PP(semi_analytical_treatment=0, zoom=14.4, sampling=1/1.6)) bl0.append(drift0,Use_PP(semi_analytical_treatment=0)) bl0.append(ap1, Use_PP(zoom=0.8)) bl0.append(wf_dist_om, Use_PP()) bl0.append(drift1, Use_PP(semi_analytical_treatment=1)) bl0.append(ap_kb, Use_PP(zoom = 6.4, sampling = 1/16.)) bl0.append(hfm, Use_PP()) bl0.append(wf_dist_hfm, Use_PP()) bl0.append(drift_in_kb, Use_PP(semi_analytical_treatment=1)) bl0.append(vfm, Use_PP()) bl0.append(wf_dist_vfm, Use_PP()) bl0.append(drift_to_foc, Use_PP(semi_analytical_treatment=1)) # All done, return. return bl0