Exemplo n.º 1
0
    def generateEigenmodes(self, nx, ny, ekev, xMin, xMax, yMin, yMax, sigX,
                           sigY, d2Waist):
        """
        Generates eigenmodes of the partially coherent GSM beam
        
        :param nx: wfr horizontal dimensions in pixels (int)
        :param ny: wfr vertical dimensions in pixels (int)
        :param ekev: wfr energy in keV (float)
        :param xMin: wfr horizontal spatial minimum (float)
        :param xMax: wfr horizontal spatial maximum (float)
        :param yMin: wfr vertical spatial minimum (float)
        :param yMax: wfr vertical spatial maximum (float)
        :param sigX: fundamental gaussian horizontal FWHM (1st dev.) (float)
        :param sigY: fundamental gaussian vertical FWHM (1st dev.) (float)
        :param d2Waist: distance to waist - defines beam curvature (float)
        """

        for mx, my in self.eigenModes:

            if mx == 0 and my == 0:

                self.wfr = Wavefront(
                    build_gauss_wavefront_xy(nx,
                                             ny,
                                             ekev,
                                             xMin,
                                             xMax,
                                             yMin,
                                             yMax,
                                             sigX,
                                             sigY,
                                             d2Waist,
                                             _mx=mx,
                                             _my=my))

                self.wfr.params.type = 'Gaussian Schell Model Type Beam'
            else:

                tmp_gsn = Wavefront(
                    build_gauss_wavefront_xy(nx,
                                             ny,
                                             ekev,
                                             xMin,
                                             xMax,
                                             yMin,
                                             yMax,
                                             sigX,
                                             sigY,
                                             d2Waist,
                                             _mx=mx,
                                             _my=my))

                addSlice(self.wfr, tmp_gsn)

                del tmp_gsn
Exemplo n.º 2
0
    def do_wpg_calculation(self):

        theta_fwhm = self.calculate_theta_fwhm_cdr(self.ekev, self.qnC)
        k = 2*numpy.sqrt(2*numpy.log(2))
        sigX = 12.4e-10*k/(self.ekev*4*numpy.pi*theta_fwhm)

        print('sigX, waist_fwhm [um], far field theta_fwhms [urad]: {}, {},{}'.format(
                                    sigX*1e6, sigX*k*1e6, theta_fwhm*1e6)
              )

        #define limits
        range_xy = theta_fwhm/k*self.distance*7. # sigma*7 beam size

        self.range_xy = range_xy

        npoints=180


        wfr0 = build_gauss_wavefront_xy(npoints,
                                        npoints,
                                        self.ekev,
                                        -range_xy/2,
                                        range_xy/2,
                                        -range_xy/2,
                                        range_xy/2,
                                        sigX,
                                        sigX,
                                        self.distance,
                                        pulseEn=self.pulseEnergy,
                                        pulseTau=self.coh_time/numpy.sqrt(2),
                                        repRate=1/(numpy.sqrt(2)*self.pulse_duration))


        return Wavefront(wfr0)
Exemplo n.º 3
0
def gsmSource(wfr, mx, my, sigX=None, sigY=None, d2waist=None):
    """
    takes an existing wavefield structure and uses it to generate a gsm source
    w/ a coherence function defined by starikov and wolf
    """

    if sigX == None:
        sigX = (wfr.params.Mesh.xMax - wfr.params.Mesh.xMin) / 10

    if sigY == None:
        sigY = (wfr.params.Mesh.yMax - wfr.params.Mesh.yMin) / 10

    wfr.params.type = 'Gaussian Schell Model Type Beam'

    #### GENERATE TRANSVERSE ELECTRIC MODE PAIRS
    wfr.params.eigenmodes = ordered_pairs(mx, my)

    #xMin, xMax, yMin, yMax = wfr.get_limits()
    for mx, my in wfr.params.eigenmodes:
        tmp_gsn = Wavefront(
            build_gauss_wavefront_xy(wfr.params.Mesh.nx,
                                     wfr.params.Mesh.ny,
                                     wfr.params.photonEnergy / 1000,
                                     *wfr.get_limits(),
                                     sigX,
                                     sigY,
                                     wfr.params.Mesh.zCoord,
                                     _mx=mx,
                                     _my=my))
        addSlice(wfr, tmp_gsn)

    return wfr
Exemplo n.º 4
0
        %%%%def generate_mode(self, mode_no, eigenfn, outPath = None):
        
        gauss_0 = primary_gaussian() # properties of gaussian

        gauss_0.d2waist = 0
        print("Generating Mode {}".format(mode_no))
        mx = self.modeIndices[n][0]
        my = self.modeIndices[n][1]
        
        xw = self.rho_I *
        yw = self.rho_I * 
        
        M2x = (2*mx)+1
        M2y = (2*my)+1
        
        wfr = Wavefront(build_gauss_wavefront_xy(gauss_0.nx ,gauss_0.ny,
                                                      self.EkeV,
                                                      self.xMin, self.xMax,
                                                      self.yMin, self.yMax,
                                                      gauss_0.sigX*(M2x**-0.5),
                                                      gauss_0.sigY*(M2y**-0.5),
                                                      gauss_0.d2waist,
                                                      tiltX = 0,
                                                      tiltY = 0,
                                                      _mx = mx,
                                                      _my = my))
        
        if outPath is not None:
            wfr.store_hdf5(outdir + "wfr_mode_{}.hdf5".format(mode_no))
        
        return wfr
Exemplo n.º 5
0
    ax1 = fig.add_subplot(111)
    ax1.plot(ax_x, Ix, color="blue", label="Horizontal Profile")
    ax1.set_ylabel("Intensity (W/$mm^2$)", fontsize=22)

    ax1.plot(ax_y, Iy, color="red", label="Vertical Profile")
    ax1.set_xlabel("Position ($\mu m$)", fontsize=22)

    plt.legend(fontsize=22)

    if show == True:
        plt.show()


def plotWavefront(wfr):

    fig = plt.figure(figsize=[12, 8])

    ii = wfr.get_intensity()[:, :, 0]
    ph = wfr.get_phase()[:, :, 0]

    plt.imshow(ph * ii)


if __name__ == '__main__':

    ### CONSTRUCT ARB. WFR
    wfr = Wavefront(
        build_gauss_wavefront_xy(256, 256, 9.2, -5e-07, 5e-07, -5e-07, 5e-07,
                                 1e-07, 1e-07, 1e-09))
    plotWavefront(wfr)
Exemplo n.º 6
0
    def test_gsm(self, beta = 1, nx = 10, ny = 1, pos = "end", export = False, outdir = ""):
        """
        Initialise GSM beam as a container of multiple coherent modes

        Modes dictionary is setup by order {wfr, eigenvalue/weight}

        :param p_mu: rms width of the degree of coherence
        :param p_I: rms width of the intensity profile
        :param n: number of values for eigenvalue calculation (almost arb.)
        """
        print("Initialising Gaussian-Schell Model Beam")
        self.log.info("Initialising Gaussian-Schell Model Beam")

        gauss_0 = primary_gaussian() # properties of gaussian
        N = nx*ny
        

        results = []

        if export == True:
            os.mkdir(outdir)
        else:
            pass

        for itr in range(N):
            self.wfr.eigenval.append(eigenvaluePartCoh(1, beta,itr))

        self.wfr.eigenval = self.wfr.eigenval[0:N]
        self.wfr.eigenfn = gen_modes(nx, ny)

        if pos == "start":
            gauss_0.d2waist = 0
        elif pos == "end":
            gauss_0.d2waist = 2.012
        else:
            assert("wavefront posn' should be 'start' or 'end'")

        print("Generating {} Coherent Modes".format(N))
        self.log.info("Generating {} Coherent Modes".format(N))
        
        eField = np.zeros((2048, 2048, 1))

        if pos == "start":
            gauss_0.d2waist = 0
        elif pos == "end":
            gauss_0.d2waist = 2.012
        else:
            assert("wavefront posn' should be 'start' or 'end'")
        
        print(self.wfr.eigenfn)
        print("Generating {} Coherent Modes".format(N))
        self.log.info("Generating {} Coherent Modes".format(N))
        for itr in range(N):
            
            res = []
            res.append(self.wfr.eigenfn[itr])
            res.append(self.wfr.eigenval[itr])

            if itr % 5 == 0:
                print("Generating Mode {}/{}".format(itr+1, N))
                self.log.info("Generating Mode {}/{}".format(itr+1, N))
                
            _mx = self.wfr.eigenfn[itr][0]
            _my = self.wfr.eigenfn[itr][1]

            M2x = (2*_mx)+1
            M2y = (2*_my)+1
            self.wfr.modes.append(Wavefront(build_gauss_wavefront_xy(gauss_0.nx ,gauss_0.ny,
                                           self.global_E*1e-03,
                                           gauss_0.xMin, gauss_0.xMax,
                                           gauss_0.yMin,gauss_0.yMax,
                                           gauss_0.sigX*M2x**-0.25,
                                           gauss_0.sigY*M2y**-0.25,
                                           gauss_0.d2waist,
                                           tiltX = 0,
                                           tiltY = 0,
                                           _mx = - _mx, ## NOTE NEGATIVE 
                                           _my = _my,
                                           pulseEn = 2.51516e-2)))


            self.wfr.type = 'gsm'

        print("Coherent Modes Generated")
        self.log.info("Coherent Modes Generated")
        
        print("Testing Coherent Modes")
        self.log.info("Testing Coherent Modes")
        
        axis_x = np.linspace(-0.002, 0.002, 2048)
        axis_y = np.linspace(-0.002, 0.002, 2048)
        
        eField = np.zeros((2048,2048,1))
        
        for itr in range(len(self.wfr.modes)):
            eField += self.wfr.modes[itr].data.arrEhor[:,:,:,0] * self.wfr.eigenval[itr]
            [cohx, cohy] = coherence_log(eField, axis_x, axis_y)
            
            
            self.log.info("**************************************************")
            self.log.info("Addition of Mode {}".format(itr))
            self.log.info("Mode Weighting {}".format(self.wfr.eigenval[itr]))
            self.log.info("Mode Weighting {}".format(self.wfr.eigenfn[itr]))
            self.log.info("\n")
            self.log.info("Ix: {} m\nJx: {} m".format(cohx[2], cohx[3]))
            self.log.info("Iy: {} m\nJy: {} m".format(cohy[2], cohy[3]))
            self.log.info("x-beta: {} \n y-beta: {}".format(cohx[4], cohy[4]))

            res.append(cohx[2])
            res.append(cohy[2])
            res.append(cohx[3])
            res.append(cohy[3])
            res.append(cohx[4])
            res.append(cohy[4])

            results.append(res)
        
        return results
Exemplo n.º 7
0
def constructTestWaveField(npoints=256,ekeV=0.6,z1=5, show=False):  
    # Simple function for generating  simple Gaussian wavefield for testing purposes


    from wpg.srwlib import srwl_uti_ph_en_conv
    from extensions.gvrutils import calculate_theta_fwhm_cdr
    from wpg.generators import build_gauss_wavefront_xy


    # set wavefield parameters
    qnC        = 0.01
    wlambda    = srwl_uti_ph_en_conv(ekeV, _in_u='keV', _out_u='nm')
    theta_fwhm = calculate_theta_fwhm_cdr(ekeV,qnC)
    k          = 2*np.sqrt(2*np.log(2))
    range_xy   = (theta_fwhm/k*z1*5.)*2.0
    sigX       = 12.4e-10*k/(ekeV*4*np.pi*theta_fwhm)

    # construct wavefield
    wf0=build_gauss_wavefront_xy(nx=npoints, ny=npoints, ekev=ekeV,
                                              xMin=-range_xy/2 ,xMax=range_xy/2,
                                              yMin=-range_xy/2, yMax=range_xy/2,
                                              sigX=sigX, sigY=sigX,
                                              d2waist=z1,
                                              _mx=0, _my=0 )
    wfr = Wavefront(srwl_wavefront=wf0)    
    print('Wavelength=%f, theta FWWM=%f, range XY = %f, sig X = %f' % (wlambda, theta_fwhm, range_xy, sigX))

    wfr._srwl_wf.unitElFld = 1#'sqrt(Phot/s/0.1%bw/mm^2)'

    if show==True: #display the wavefield
        plotWavefront(wfr, 'Wavefield at source')

    return wfr



    
    def generate_mode_test(self, mode_no, eigenfn, outdir, gwaist = None):
        gauss_0 = primary_gaussian() # properties of gaussian
        gauss_0.d2waist = -9.0000
        if gwaist is not None:
            gauss_0.d2waist = gwaist
        print("Generating Mode {}".format(mode_no))
        _mx = eigenfn[mode_no][0]
        _my = eigenfn[mode_no][1]
        
        M2x = (2*_mx)+1
        M2y = (2*_my)+1
        
        GsnBm = SRWLGsnBm(_x = 0, _y = 0, _z = 0,
                          _sigX = 100e-06,#gauss_0.sigX*(M2x**-0.25),
                          _sigY = 100e-06,#gauss_0.sigY*(M2y**-0.25),
                          _xp = 0, #gauss_0.xp,
                          _yp = 0,#gauss_0.yp,
                          _mx = _mx,
                          _my = _my,
                          _avgPhotEn = gauss_0.E)
        
        wfr = Wavefront(build_gaussian(GsnBm,
                                       gauss_0.nx*2, gauss_0.ny*2,
                                       gauss_0.xMin*2, gauss_0.xMax*2,
                                       gauss_0.yMin*2, gauss_0.yMax*2))

        wfr.store_hdf5(outdir + "wfr_mode_{}.hdf5".format(mode_no))
        return wfr
Exemplo n.º 8
0
def constructWavefield(
    ekeV,
    qnC,
    z1,
    range_xy,
    strOutputDataFolder=None,
    dimension=2,
    beta=0.7,  # 'tunable' parameter — sets global degree of coherence
    threshold=0.8,  # ignore modes with eigenvalue < this value
    npoints=512,
    nslices=10,
    display=True,
):
    """
    Define Transverse Optical Modes
    """
    k = 2 * np.sqrt(2 * np.log(2))
    wlambda = 12.4 * 1e-10 / ekeV  # wavelength
    theta_fwhm = calculate_theta_fwhm_cdr(ekeV, qnC)
    sigX = 12.4e-10 * k / (ekeV * 4 * np.pi * theta_fwhm)

    # coherence width:
    widthCoherence = beta * sigX

    # get first n eigenvalues for transverse modes
    n = 99
    e0 = eigenvaluePartCoh(sigX, widthCoherence, range(0, n))

    # keep only modes for which eigenvalue > threshold
    e = e0[e0 > threshold]

    if display:
        plotEigenValues(e0, threshold)

    # generate mode indices
    modes = modes2D(9, N=len(e))

    dimension = 2  # value should be 3 for 3D wavefront, 2 for 2D wavefront
    wf = []
    for mx, my in modes:

        # define unique filename for storing results
        ip = np.floor(ekeV)
        frac = np.floor((ekeV - ip) * 1e3)

        # build initial gaussian wavefront
        if dimension == 2:
            wfr0 = build_gauss_wavefront_xy(
                nx=npoints,
                ny=npoints,
                ekev=ekeV,
                xMin=-range_xy / 2,
                xMax=range_xy / 2,
                yMin=-range_xy / 2,
                yMax=range_xy / 2,
                sigX=sigX,
                sigY=sigX,
                d2waist=z1,
                _mx=mx,
                _my=my,
            )

        else:
            # build initial 3d gaussian beam
            tau = 1
            # not sure if this parameter is even used - check meaning.
            wfr0 = build_gauss_wavefront(
                nx=npoints,
                ny=npoints,
                nz=nslices,
                ekev=ekev,
                xMin=-range_xy / 2,
                xMax=range_xy / 2,
                yMin=-range_xy / 2,
                yMax=range_xy / 2,
                tau=tau,
                sigX=sigX,
                sigY=sigX,
                d2waist=z1,
                _mx=mx,
                _my=my,
            )
            if display == True:
                print(
                    "dy {:.1f} um".format(
                        (mwf.params.Mesh.yMax - mwf.params.Mesh.yMin)
                        * 1e6
                        / (mwf.params.Mesh.ny - 1.0)
                    )
                )
                print(
                    "dx {:.1f} um".format(
                        (mwf.params.Mesh.xMax - mwf.params.Mesh.xMin)
                        * 1e6
                        / (mwf.params.Mesh.nx - 1.0)
                    )
                )
                plot_t_wf(mwf)
                look_at_q_space(mwf)

        # init WPG Wavefront helper class
        mwf = Wavefront(wfr0)

        # store wavefront to HDF5 file
        if strOutputDataFolder:
            fname0 = (
                "g"
                + str(int(ip))
                + "_"
                + str(int(frac))
                + "kev"
                + "_tm"
                + str(mx)
                + str(my)
            )
            ifname = os.path.join(strOutputDataFolder, fname0 + ".h5")
            mwf.store_hdf5(ifname)
            print("Saved wavefront to HDF5 file: {}".format(ifname))
        else:
            ifname = None

        wf.append([mx, my, ifname, mwf])

        # plotWavefront(mwf, 'at '+str(z1)+' m')
        # look_at_q_space(mwf)

        fwhm_x = calculate_fwhm_x(mwf)
        print(
            "FWHMx [mm], theta_fwhm [urad]: {}, {}".format(
                fwhm_x * 1e3, fwhm_x / z1 * 1e6
            )
        )

        # show_slices_hsv(mwf, slice_numbers=None, pretitle='SLICETYSLICE')

        return wf, modes, e