Exemple #1
0
def wake_t_beam_to_parray(wake_t_beam, gamma_ref=None, z_ref=None):
    """
    Converts a Wake-T particle beam to an Ocelot ParticleArray.

    Parameters:
    -----------
    wake_t_beam : ParticleBunch (Wake-T class)
        The original particle distribution from Wake-T.

    gamma_ref : float (Optional)
        Reference energy of the particle beam used for tracking in Ocelot. If
        not specified, the reference energy will be taken as the average
        energy of the input distribution.

    z_ref : float (Optional)
        Reference longitudinal position of the particle beam used for tracking
        in Ocelot. If not specified, the reference value will be taken as the
        average longitudinal position of the input distribution.

    Returns:
    --------
    An Ocelot ParticleArray.

    """
    # Extract particle coordinates.
    x = wake_t_beam.x  # [m]
    y = wake_t_beam.y  # [m]
    z = wake_t_beam.xi + wake_t_beam.prop_distance  # [m]
    px = wake_t_beam.px  # [m_e * c]
    py = wake_t_beam.py  # [m_e * c]
    pz = wake_t_beam.pz  # [m_e * c]
    q = wake_t_beam.q  # [C]

    # Calculate gamma.
    gamma = np.sqrt(1 + px**2 + py**2 + pz**2)

    # Determine reference energy and longitudinal position.
    if gamma_ref is None:
        gamma_ref = np.average(gamma, weights=q)
    if z_ref is None:
        z_ref = wake_t_beam.prop_distance

    # Calculate momentum deviation (dp) and kinetic momentum (p_kin).
    b_ref = np.sqrt(1 - gamma_ref**(-2))
    dp = (gamma-gamma_ref)/(gamma_ref*b_ref)
    p_kin = np.sqrt(gamma_ref**2 - 1)

    # Create particle array
    p_array = ParticleArray(len(q))
    p_array.rparticles[0] = x
    p_array.rparticles[2] = y
    p_array.rparticles[4] = -(z - z_ref)
    p_array.rparticles[1] = px/p_kin
    p_array.rparticles[3] = py/p_kin
    p_array.rparticles[5] = dp
    p_array.q_array[:] = q
    p_array.s = z_ref
    p_array.E = gamma_ref * m_e_GeV

    return p_array
Exemple #2
0
def slicing_p_array(p_array, SIZE):
    """
    Divide ParticleArray into chuncks

    :param p_array: ParticleArray
    :param SIZE: number of threads
    :return: list of ParticleArray
    """

    if SIZE == 0:
        raise ValueError("SIZE must be not zero")
    if SIZE > p_array.n:
        raise ValueError("SIZE must be less or equal number of paricles")
    p_array_list = []
    nchunk = int(p_array.n / SIZE)
    #print(p_array.n, nchunk, SIZE)
    nparticles_list = np.ones(SIZE, dtype=int)*nchunk
    nparticles_last = p_array.n - nchunk * (SIZE - 1)
    if nparticles_last > nchunk:
        nchunk += 1
        nextra = nparticles_last - nchunk
        nparticles_list[:nextra] += 1
        nparticles_list[-1] = nparticles_last - nextra
    #nparticles = nchunk
    ncontrol = 0

    for i, nparticles in enumerate(nparticles_list):
        p_array_part = ParticleArray(n=nparticles)
        p_array_part.rparticles[:, :] = p_array.rparticles[:, ncontrol:ncontrol+nparticles]
        p_array_part.q_array[:] = p_array.q_array[ncontrol:ncontrol+nparticles]
        ncontrol += nparticles
        p_array_part.s = p_array.s
        p_array_part.E = p_array.E
        p_array_list.append(p_array_part)
    return p_array_list
Exemple #3
0
def csrtrackBeam2particleArray(filename, orient="H"):
    """
    Function to read CSRtrack beam files ".fmt1"
    H: z x y pz px py -> x y z px py pz
    V: z y x pz py px -> x y -z px py -pz

    :param filename: filename
    :param orient: str, "H" or "V" horizontal or vertical orientation
    :return: ParticleArray
    """
    pd = np.loadtxt(filename)
    n = np.shape(pd)[0] - 1
    pd1 = np.zeros((n, 6))

    if orient == 'H':
        pd1[:, 0] = pd[1:, 1]
        pd1[:, 1] = pd[1:, 2]
        pd1[:, 2] = pd[1:, 0]
        pd1[:, 3] = pd[1:, 4]
        pd1[:, 4] = pd[1:, 5]
        pd1[:, 5] = pd[1:, 3]
    else:
        pd1[:, 0] = -pd[1:, 2]
        pd1[:, 1] = pd[1:, 1]
        pd1[:, 2] = pd[1:, 0]
        pd1[:, 3] = -pd[1:, 5]
        pd1[:, 4] = pd[1:, 4]
        pd1[:, 5] = pd[1:, 3]

    for i in range(6):
        pd1[1:n, i] = pd1[1:n, i] + pd1[0, i]

    p_ref = np.sqrt(pd1[0, 3]**2 + pd1[0, 4]**2 + pd1[0, 5]**2)

    px = pd1[:, 3] / p_ref
    py = pd1[:, 4] / p_ref
    Eref = np.sqrt(m_e_eV**2 + p_ref**2)
    pe = (np.sqrt(m_e_eV**2 +
                  (pd1[:, 3]**2 + pd1[:, 4]**2 + pd1[:, 5]**2)) - Eref) / p_ref

    p_array = ParticleArray(n)
    p_array.rparticles[0] = pd1[:, 0]
    p_array.rparticles[2] = pd1[:, 1]
    p_array.rparticles[4] = -(pd1[:, 2] - pd1[0, 2])
    p_array.rparticles[1] = px[:]
    p_array.rparticles[3] = py[:]
    p_array.rparticles[5] = pe[:]

    p_array.q_array[:] = pd[1:, 6]
    p_array.s = pd1[0, 2]
    p_array.E = Eref * 1e-9
    return p_array
Exemple #4
0
def csrtrackBeam2particleArray(filename, orient="H"):
    #H z x y pz px py -> x y z px py pz
    #V z y x pz py px -> x y -z px py -pz
    PD = np.loadtxt(filename)
    #PD = load(infile)
    n = np.shape(PD)[0] - 1  #length(PD(:,1))- 1
    #print(n)
    PD1 = np.zeros((n, 6))
    Q = np.sum(PD[1:, 6]) * 1e9
    t0 = PD[0, 0]
    if orient == 'H':
        PD1[:, 1 - 1] = PD[1:, 2 - 1]
        PD1[:, 2 - 1] = PD[1:, 3 - 1]
        PD1[:, 3 - 1] = PD[1:, 1 - 1]
        PD1[:, 4 - 1] = PD[1:, 5 - 1]
        PD1[:, 5 - 1] = PD[1:, 6 - 1]
        PD1[:, 6 - 1] = PD[1:, 4 - 1]
    else:
        PD1[:, 1 - 1] = -PD[1:, 3 - 1]
        PD1[:, 2 - 1] = PD[1:, 2 - 1]
        PD1[:, 3 - 1] = PD[1:, 1 - 1]
        PD1[:, 4 - 1] = -PD[1:, 6 - 1]
        PD1[:, 5 - 1] = PD[1:, 5 - 1]
        PD1[:, 6 - 1] = PD[1:, 4 - 1]
    #print("CSR", PD1[0, :])
    for i in range(6):
        PD1[1:n, i] = PD1[1:n, i] + PD1[0, i]

    p_ref = np.sqrt(PD1[0, 3]**2 + PD1[0, 4]**2 + PD1[0, 5]**2)
    px = PD1[:, 3] / p_ref
    py = PD1[:, 4] / p_ref
    Eref = np.sqrt(m_e_eV**2 + p_ref**2)
    pe = (np.sqrt(m_e_eV**2 +
                  (PD1[:, 3]**2 + PD1[:, 4]**2 + PD1[:, 5]**2)) - Eref) / p_ref

    p_array = ParticleArray(n)
    p_array.rparticles[0] = PD1[:, 0] - 0 * PD1[0, 0]
    p_array.rparticles[2] = PD1[:, 1] - 0 * PD1[0, 1]
    p_array.rparticles[4] = -(PD1[:, 2] - PD1[0, 2])
    p_array.rparticles[1] = px[:]
    p_array.rparticles[3] = py[:]
    p_array.rparticles[5] = pe[:]

    p_array.q_array[:] = PD[1:, 6]
    p_array.s = PD1[0, 2]
    p_array.E = Eref * 1e-9
    return p_array
Exemple #5
0
    def apply(self, prcl_series):
        """
        :param prcl_series: can be list of Particles [Particle_1, Particle_2, ... ] or ParticleArray
        :return: None
        """
        if prcl_series.__class__ == ParticleArray:
            self.map(prcl_series.rparticles, energy=prcl_series.E)
            prcl_series.E += self.delta_e
            prcl_series.s += self.length

        elif prcl_series.__class__ == Particle:
            p = prcl_series
            p.x, p.px, p.y, p.py, p.tau, p.p = self.map(
                array([[p.x], [p.px], [p.y], [p.py], [p.tau], [p.p]]), p.E)[:,
                                                                            0]
            p.s += self.length
            p.E += self.delta_e

        elif prcl_series.__class__ == list and prcl_series[
                0].__class__ == Particle:
            # If the energy is not the same (p.E) for all Particles in the list of Particles
            # in that case cycle is applied. For particles with the same energy p.E
            list_e = array([p.E for p in prcl_series])
            if False in (list_e[:] == list_e[0]):
                for p in prcl_series:
                    self.map(array([[p.x], [p.px], [p.y], [p.py], [p.tau],
                                    [p.p]]),
                             energy=p.E)
                    p.E += self.delta_e
                    p.s += self.length
            else:
                pa = ParticleArray()
                pa.list2array(prcl_series)
                pa.E = prcl_series[0].E
                self.map(pa.rparticles, energy=pa.E)
                pa.E += self.delta_e
                pa.s += self.length
                pa.array2ex_list(prcl_series)

        else:
            print(prcl_series)
            exit("Unknown type of Particle_series. class TransferMap.apply()")