Пример #1
0
def get_traces(accelerator=None, m66=None, closed_orbit=None):
    """Return traces of 6D one-turn transfer matrix"""
    if m66 is None:
        m66 = _tracking.findm66(accelerator,
                                indices = 'm66', closed_orbit = closed_orbit)
    trace_x = m66[0,0] + m66[1,1]
    trace_y = m66[2,2] + m66[3,3]
    trace_z = m66[4,4] + m66[5,5]
    return trace_x, trace_y, trace_z, m66, closed_orbit
Пример #2
0
def old_calc_twiss(accelerator=None, init_twiss=None, fixed_point=None, indices = 'open'):
    """Return Twiss parameters of uncoupled dynamics.

    Keyword arguments:
    accelerator -- Accelerator object
    init_twiss  -- Twiss parameters at the start of first element
    fixed_point -- 6D position at the start of first element
    indices     -- Open or closed

    Returns:
    tw -- list of Twiss objects
    m66
    transfer_matrices
    closed_orbit
    """

    if indices == 'open':
        length = len(accelerator)
    elif indices == 'closed':
        length = len(accelerator)+1
    else:
        raise OpticsException("invalid value for 'indices' in calc_twiss")

    if init_twiss is not None:
        ''' as a transport line: uses init_twiss '''
        if fixed_point is None:
            fixed_point = init_twiss.fixed_point
        else:
            raise OpticsException('arguments init_twiss and fixed_orbit are mutually exclusive')

        closed_orbit, *_ = _tracking.linepass(accelerator, particles=list(fixed_point), indices='open')
        m66, cumul_trans_matrices = _tracking.findm66(accelerator, closed_orbit=closed_orbit)

        if indices == 'closed':
            orb, *_ = _tracking.linepass(accelerator[-1:], particles=closed_orbit[:,-1])
            closed_orbit = _np.append(closed_orbit,orb.transpose(),axis=1)

        mx, my = m66[0:2, 0:2], m66[2:4, 2:4]
        t = init_twiss
        t.etax = _np.array([[t.etax], [t.etapx]])
        t.etay = _np.array([[t.etay], [t.etapy]])
    else:
        ''' as a periodic system: try to find periodic solution '''

        if accelerator.harmonic_number == 0:
            raise OpticsException('Either harmonic number was not set or calc_twiss was'
                'invoked for transport line without initial twiss')

        if fixed_point is None:
            if not accelerator.cavity_on and not accelerator.radiation_on:
                closed_orbit = _np.zeros((6,length))
                closed_orbit[:4,:] = _tracking.findorbit4(accelerator, indices=indices)
            elif not accelerator.cavity_on and accelerator.radiation_on:
                raise OpticsException('The radiation is on but the cavity is off')
            else:

                closed_orbit = _tracking.findorbit6(accelerator, indices=indices)
        else:
            closed_orbit, *_ = _tracking.linepass(accelerator, particles=list(fixed_point), indices=indices)

        ''' calcs twiss at first element '''
        orbit = closed_orbit[:,:-1] if indices == 'closed' else closed_orbit
        m66, cumul_trans_matrices, *_ = _tracking.findm66(accelerator, closed_orbit=orbit)
        mx, my = m66[0:2,0:2], m66[2:4,2:4] # decoupled transfer matrices
        trace_x, trace_y, *_ = get_traces(accelerator, m66 = m66, closed_orbit=closed_orbit)
        if not (-2.0 < trace_x < 2.0):
            raise OpticsException('horizontal dynamics is unstable')
        if not (-2.0 < trace_y < 2.0):
            raise OpticsException('vertical dynamics is unstable')
        sin_nux = _math.copysign(1,mx[0,1]) * _math.sqrt(-mx[0,1] * mx[1,0] - ((mx[0,0] - mx[1,1])**2)/4);
        sin_nuy = _math.copysign(1,my[0,1]) * _math.sqrt(-my[0,1] * my[1,0] - ((my[0,0] - my[1,1])**2)/4);
        fp = closed_orbit[:,0]
        t = Twiss()
        t.spos = 0
        t.rx, t.px = fixed_point[0], fixed_point[1]
        t.ry, t.py = fixed_point[2], fixed_point[3]
        t.de, t.dl = fixed_point[4], fixed_point[5]
        t.alphax = (mx[0,0] - mx[1,1]) / 2 / sin_nux
        t.betax  = mx[0,1] / sin_nux
        t.alphay = (my[0,0] - my[1,1]) / 2 / sin_nuy
        t.betay  = my[0,1] / sin_nuy
        ''' dispersion function based on eta = (1 - M)^(-1) D '''
        Dx = _np.array([[m66[0,4]],[m66[1,4]]])
        Dy = _np.array([[m66[2,4]],[m66[3,4]]])
        t.etax = _np.linalg.solve(_np.eye(2,2) - mx, Dx)
        t.etay = _np.linalg.solve(_np.eye(2,2) - my, Dy)

    ''' get transfer matrices from cumulative transfer matrices '''
    transfer_matrices = []
    m66_prev = _np.eye(6,6)
    cumul_trans_matrices.append(m66)
    for m66_this in cumul_trans_matrices[1:]: # Matrices at start of elements
        inv_m66_prev = _np.linalg.inv(m66_prev)
        tm = _np.dot(m66_this, inv_m66_prev)
        #tm = _np.linalg.solve(m66_prev.T, m66_this.T).T  # Fernando, you may uncomment this line when running YOUR code! aushuashuahs
        m66_prev = m66_this
        transfer_matrices.append(tm)

    ''' propagates twiss through line '''
    tw = [t]
    m_previous = _np.eye(6,6)
    for i in range(1, length):
        m = transfer_matrices[i-1]
        mx, my = m[0:2,0:2], m[2:4,2:4] # decoupled transfer matrices
        Dx = _np.array([[m[0,4]],[m[1,4]]])
        Dy = _np.array([[m[2,4]],[m[3,4]]])
        n = Twiss()
        n.spos   = t.spos + accelerator[i-1].length
        fp = closed_orbit[:,i]
        n.rx, n.px = fixed_point[0], fixed_point[1]
        n.ry, n.py = fixed_point[2], fixed_point[3]
        n.de, n.dl = fixed_point[4], fixed_point[5]
        n.betax  =  ((mx[0,0] * t.betax - mx[0,1] * t.alphax)**2 + mx[0,1]**2) / t.betax
        n.alphax = -((mx[0,0] * t.betax - mx[0,1] * t.alphax) * (mx[1,0] * t.betax - mx[1,1] * t.alphax) + mx[0,1] * mx[1,1]) / t.betax
        n.betay  =  ((my[0,0] * t.betay - my[0,1] * t.alphay)**2 + my[0,1]**2) / t.betay
        n.alphay = -((my[0,0] * t.betay - my[0,1] * t.alphay) * (my[1,0] * t.betay - my[1,1] * t.alphay) + my[0,1] * my[1,1]) / t.betay

        ''' calcs phase advance based on R(mu) = U(2) M(2|1) U^-1(1) '''
        sint = mx[0,1]/_math.sqrt(n.betax * t.betax)
        cost = (mx[0,0] * t.betax - mx[0,1] * t.alphax)/_math.sqrt(n.betax * t.betax)
        dmux = _math.atan2(sint, cost)
        n.mux = t.mux + dmux
        sint = my[0,1]/_math.sqrt(n.betay * t.betay)
        cost = (my[0,0] * t.betay - my[0,1] * t.alphay)/_math.sqrt(n.betay * t.betay)
        dmuy = _math.atan2(sint, cost)
        n.muy = t.muy + dmuy

        ''' when phase advance in an element is over PI atan2 returns a
            negative value that has to be corrected by adding 2*PI'''
        if dmux < 0 and dmux < -10*_sys.float_info.epsilon:
            n.mux += 2*_math.pi
        if dmuy < 0 and dmuy < -10*_sys.float_info.epsilon:
            n.muy += 2*_math.pi

        ''' dispersion function'''
        n.etax = Dx + _np.dot(mx, t.etax)
        n.etay = Dy + _np.dot(my, t.etay)

        tw.append(n)

        t = n.make_copy()

    ''' converts eta format '''
    for t in tw:
        t.etapx, t.etapy = (t.etax[1,0], t.etay[1,0])
        t.etax,  t.etay  = (t.etax[0,0], t.etay[0,0])

    return tw, m66, transfer_matrices, closed_orbit
Пример #3
0
def calctwiss(
        accelerator=None,
        indices=None,
        transfer_matrices=None,
        closed_orbit=None,
        twiss_in=None):
    """Return uncoupled Twiss parameters."""

    ''' process arguments '''
    if indices is None:
        indices = range(len(accelerator))

    try:
        indices[0]
    except:
        indices = [indices]

    if transfer_matrices is None:
        transfer_matrices = _tracking.findm66(accelerator = accelerator, closed_orbit = closed_orbit)
    if twiss_in is None:
        twiss_in = Twiss()
        twiss_in.closed_orbit = closed_orbit
        twiss_in.mux, twiss_in.muy = 0, 0

    m66 = transfer_matrices[-1]

    ''' calcs twiss at first element '''
    mx, my = m66[0:2,0:2], m66[2:4,2:4] # decoupled transfer matrices
    sin_nux = _math.copysign(1,mx[0,1]) * _math.sqrt(-mx[0,1] * mx[1,0] - ((mx[0,0] - mx[1,1])**2)/4);
    sin_nuy = _math.copysign(1,my[0,1]) * _math.sqrt(-my[0,1] * my[1,0] - ((my[0,0] - my[1,1])**2)/4);
    t = Twiss()
    t.alphax  = (mx[0,0] - mx[1,1]) / 2 / sin_nux
    t.betax   = mx[0,1] / sin_nux
    t.alphay  = (my[0,0] - my[1,1]) / 2 / sin_nuy
    t.betay   = my[0,1] / sin_nuy
    ''' dispersion function based on eta = (1 - M)^(-1) D'''
    Dx = _np.array([[m66[0,4]],[m66[1,4]]])
    Dy = _np.array([[m66[2,4]],[m66[3,4]]])
    t.etax = _np.linalg.solve(_np.eye(2,2) - mx, Dx)
    t.etay = _np.linalg.solve(_np.eye(2,2) - my, Dy)

    if 0 in indices:
        tw = [t]
    else:
        tw = []

    ''' propagates twiss through line '''
    m_previous = _np.eye(6,6)
    for i in range(len(accelerator)):
        m_current = transfer_matrices[i-1]
        m = _np.dot(m_current, _np.linalg.inv(m_previous))
        m_previous = m_current
        mx, my = m[0:2,0:2], m[2:4,2:4] # decoupled transfer matrices
        Dx = _np.array([[m[0,4]],[m[1,4]]])
        Dy = _np.array([[m[2,4]],[m[3,4]]])
        n = Twiss()
        n.betax  =  ((mx[0,0] * t.betax - mx[0,1] * t.alphax)**2 + mx[0,1]**2) / t.betax
        n.alphax = -((mx[0,0] * t.betax - mx[0,1] * t.alphax) * (mx[1,0] * t.betax - mx[1,1] * t.alphax) + mx[0,1] * mx[1,1]) / t.betax
        n.betay  =  ((my[0,0] * t.betay - my[0,1] * t.alphay)**2 + my[0,1]**2) / t.betay
        n.alphay = -((my[0,0] * t.betay - my[0,1] * t.alphay) * (my[1,0] * t.betay - my[1,1] * t.alphay) + my[0,1] * my[1,1]) / t.betay
        ''' calcs phase advance based on R(mu) = U(2) M(2|1) U^-1(1) '''
        n.mux    = t.mux + _math.asin(mx[0,1]/_math.sqrt(n.betax * t.betax))
        n.muy    = t.muy + _math.asin(my[0,1]/_math.sqrt(n.betay * t.betay))
        ''' dispersion function '''
        n.etax = Dx + _np.dot(mx, t.etax)
        n.etay = Dy + _np.dot(my, t.etay)

        if i in indices:
            tw.append(n)
        t = _copy.deepcopy(n)

    ''' converts eta format '''
    for t in tw:
        t.etaxl, t.etayl = (t.etax[1,0], t.etay[1,0])
        t.etax,  t.etay  = (t.etax[0,0], t.etay[0,0])

    return tw