Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
    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)
Ejemplo n.º 5
0
    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)
Ejemplo n.º 6
0
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
Ejemplo n.º 7
0
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
Ejemplo n.º 8
0
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
Ejemplo n.º 9
0
    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)
Ejemplo n.º 10
0
    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)
Ejemplo n.º 11
0
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
Ejemplo n.º 12
0
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
Ejemplo n.º 13
0
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