Exemplo n.º 1
0
def test_checktype(simple_ring):
    assert checktype(elements.Drift)(simple_ring[0]) is True
    assert checktype(elements.Marker)(simple_ring[0]) is False
    assert (list(filter(checktype(elements.Drift), simple_ring)) == [
        simple_ring[0], simple_ring[3], simple_ring[4], simple_ring[5]
    ])
    assert list(filter(checktype(elements.Monitor), simple_ring)) == []
Exemplo n.º 2
0
def set_cavity_phase(ring,
                     method=ELossMethod.INTEGRAL,
                     refpts=None,
                     cavpts=None,
                     copy=False):
    """
   Adjust the TimeLag attribute of RF cavities based on frequency,
   voltage and energy loss per turn, so that the synchronous phase is zero.
   An error occurs if all cavities do not have the same frequency.

   !!!!WARNING!!!: This function changes the time reference, this should be 
   avoided

    PARAMETERS
        ring        lattice description

    KEYWORDS
        method=ELossMethod.INTEGRAL
                            method for energy loss computation.
                            See "get_energy_loss".
        cavpts=None         Cavity location. If None, use all cavities.
                            This allows to ignore harmonic cavities.
        copy=False          If True, returns a shallow copy of ring with new
                            cavity elements. Otherwise, modify ring in-place.
    """
    # refpts is kept for backward compatibility
    if cavpts is None and refpts is not None:
        warn(FutureWarning('You should use "cavpts" instead of "refpts"'))
        cavpts = refpts
    elif cavpts is None:
        cavpts = get_cells(ring, checktype(RFCavity))
    timelag, ts = get_timelag_fromU0(ring, method=method, cavpts=cavpts)
    set_value_refpts(ring, cavpts, 'TimeLag', timelag, copy=copy)
Exemplo n.º 3
0
def get_timelag_fromU0(ring, method=ELossMethod.INTEGRAL, cavpts=None):
    """
    Get the TimeLag attribute of RF cavities based on frequency,
    voltage and energy loss per turn, so that the synchronous phase is zero.
    An error occurs if all cavities do not have the same frequency.
    Used in set_cavity_phase()

    PARAMETERS
        ring        lattice description

    KEYWORDS
        method=ELossMethod.INTEGRAL
                            method for energy loss computation.
                            See "get_energy_loss".
        cavpts=None         Cavity location. If None, use all cavities.
                            This allows to ignore harmonic cavities.
    RETURN
        timelag
    """
    if cavpts is None:
        cavpts = get_cells(ring, checktype(RFCavity))
    u0 = get_energy_loss(ring, method=method)
    try:
        rfv = ring.get_rf_voltage(cavpts=cavpts)
        freq = ring.get_rf_frequency(cavpts=cavpts)
        tl0 = ring.get_rf_timelag(cavpts=cavpts)
    except AtError:
        freq = numpy.array([cav.Frequency for cav in ring.select(cavpts)])
        rfv = numpy.array([cav.Voltage for cav in ring.select(cavpts)])
        tl0 = numpy.array([cav.TimeLag for cav in ring.select(cavpts)])
        if u0 > numpy.sum(rfv):
            raise AtError('Not enough RF voltage: unstable ring')
        ctmax = 1 / numpy.amin(freq) * clight / 2
        tt0 = tl0[numpy.argmin(freq)]
        eq = lambda x: numpy.sum(rfv * numpy.sin(2 * pi * freq *
                                                 (x + tl0) / clight)) - u0
        deq = lambda x: numpy.sum(rfv * numpy.cos(2 * pi * freq *
                                                  (x + tl0) / clight))
        zero_diff = least_squares(deq,
                                  -tt0 + ctmax / 2,
                                  bounds=(-tt0, ctmax - tt0)).x[0]
        if numpy.sign(deq(zero_diff - 1.0e-6)) > 0:
            ts = least_squares(eq, (zero_diff - tt0) / 2,
                               bounds=(-tt0, zero_diff)).x[0]
        else:
            ts = least_squares(eq, (ctmax - tt0 + zero_diff) / 2,
                               bounds=(zero_diff, ctmax - tt0)).x[0]
        timelag = ts + tl0
    else:
        if u0 > rfv:
            raise AtError('Not enough RF voltage: unstable ring')
        timelag = clight / (2 * pi * freq) * numpy.arcsin(u0 / rfv)
        ts = timelag - tl0
        timelag *= numpy.ones(refpts_len(ring, cavpts))
    return timelag, ts
Exemplo n.º 4
0
def set_cavity(ring,
               Voltage=None,
               Frequency=None,
               HarmNumber=None,
               TimeLag=None,
               cavpts=None,
               copy=False):
    """
    PARAMETERS
        ring                lattice description

    KEYWORDS
        Frequency=None      RF frequency. The special enum value Frf.NOMINAL
                            sets the frequency to the nominal value, given
                            ring length and harmonic number.
        Voltage=None        RF voltage for the full ring.
        HarmNumber=None     Harmonic number for the full ring.
        TimeLag=None
        cavpts=None         Cavity location. If None, use all cavities.
                            This allows to ignore harmonic cavities.
        copy=False          If True, returns a shallow copy of ring with new
                            cavity elements. Otherwise, modify ring in-place
    """
    def get_harm(hcell):
        if hcell is not None:
            return hcell * n_periods
        else:
            return ring.get_rf_harmonic_number(cavpts=cavpts)

    if cavpts is None:
        cavpts = get_cells(ring, checktype(elements.RFCavity))
    n_cavities = ring.refcount(cavpts)
    if n_cavities < 1:
        raise AtError('No cavity found in the lattice')
    n_periods = ring.periodicity

    modif = {}
    if Frequency is not None:
        if Frequency is Frf.NOMINAL:
            Frequency = (clight / ring.circumference) * get_harm(HarmNumber)
        modif['Frequency'] = Frequency
    if HarmNumber is not None:
        modif['HarmNumber'] = HarmNumber / n_periods
    if TimeLag is not None:
        modif['TimeLag'] = TimeLag
    if Voltage is not None:
        modif['Voltage'] = Voltage / n_periods / n_cavities

    # noinspection PyShadowingNames
    @make_copy(copy)
    def apply(ring, cavpts, modif):
        for cavity in ring.select(cavpts):
            cavity.update(modif)

    return apply(ring, cavpts, modif)
Exemplo n.º 5
0
def _get_rf_attr(ring, attr, cavpts=None):
    if cavpts is None:
        cavpts = checktype(elements.RFCavity)
    cavities = ring.select(cavpts)
    return numpy.array([getattr(cavity, attr) for cavity in cavities])