예제 #1
0
def _fit_tune_chrom(ring, index, func, refpts1, refpts2, newval, tol=1.0e-12,
                    dp=0, niter=3):

    def _get_resp(ring, index, func, refpts, attname, delta, dp=0):
        set_value_refpts(ring, refpts, attname, delta, index=index,
                         increment=True)
        datap = func(ring, dp=dp)
        set_value_refpts(ring, refpts, attname, -2*delta, index=index,
                         increment=True)
        datan = func(ring, dp=dp)
        set_value_refpts(ring, refpts, attname, delta, index=index,
                         increment=True)
        data = numpy.subtract(datap, datan)/(2*delta)
        return data

    delta = 1e-6*10**(index)
    val = func(ring, dp=dp)
    dq1 = _get_resp(ring, index, func, refpts1, 'PolynomB', delta, dp=dp)
    dq2 = _get_resp(ring, index, func, refpts2, 'PolynomB', delta, dp=dp)
    J = [[dq1[0], dq2[0]], [dq1[1], dq2[1]]]
    dk = numpy.linalg.solve(J, numpy.subtract(newval, val))
    set_value_refpts(ring, refpts1, 'PolynomB', dk[0], index=index,
                     increment=True)
    set_value_refpts(ring, refpts2, 'PolynomB', dk[1], index=index,
                     increment=True)

    val = func(ring, dp=dp)
    sumsq = numpy.sum(numpy.square(numpy.subtract(val, newval)))
    if sumsq > tol and niter > 0:
        _fit_tune_chrom(ring, index, func, refpts1, refpts2, newval, tol=tol,
                        dp=dp, niter=niter-1)
    else:
        return
예제 #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)
예제 #3
0
def tapering(ring, multipoles=True, niter=1, **kwargs):
    """
    Scales magnet strength with local energy to cancel the closed orbit
    and optics errors due to synchrotron radiations. PolynomB is used for
    dipoles such that the machine geometry is maintained. This is the ideal
    tapering scheme where magnets and multipoles components (PolynomB and
    PolynomA) are scaled individually.
    !!! WARNING: This method works only for lattices without errors and
    corrections: if not all corrections and field errors will also be
    scaled !!!
    tapering(ring) or ring.tapering()
    PARAMETERS
        ring            lattice description.

    KEYWORDS
        multipoles=True scale all multipoles
        niter=1         number of iteration
        XYStep=1.0e-8   transverse step for numerical computation
        DPStep=1.0E-6   momentum deviation used for computation of orbit6
    """

    xy_step = kwargs.pop('XYStep', DConstant.XYStep)
    dp_step = kwargs.pop('DPStep', DConstant.DPStep)
    dipoles = get_refpts(ring, Dipole)
    b0 = get_value_refpts(ring, dipoles, 'BendingAngle')
    k0 = get_value_refpts(ring, dipoles, 'PolynomB', index=0)
    ld = get_value_refpts(ring, dipoles, 'Length')

    for i in range(niter):
        _, o6 = find_orbit6(ring,
                            refpts=range(len(ring) + 1),
                            XYStep=xy_step,
                            DPStep=dp_step)
        dpps = (o6[dipoles, 4] + o6[dipoles + 1, 4]) / 2
        set_value_refpts(ring,
                         dipoles,
                         'PolynomB',
                         b0 / ld * dpps + k0 * (1 + dpps),
                         index=0)

    if multipoles:
        mults = get_refpts(ring, Multipole)
        k0 = get_value_refpts(ring, dipoles, 'PolynomB', index=0)
        _, o6 = find_orbit6(ring,
                            refpts=range(len(ring) + 1),
                            XYStep=xy_step,
                            DPStep=dp_step)
        dpps = (o6[mults, 4] + o6[mults + 1, 4]) / 2
        for dpp, el in zip(dpps, ring[mults]):
            el.PolynomB *= 1 + dpp
            el.PolynomA *= 1 + dpp
        set_value_refpts(ring, dipoles, 'PolynomB', k0, index=0)
예제 #4
0
파일: globalfit.py 프로젝트: T-Nicholls/at
 def _fit(ring, index, func, refpts1, refpts2, newval, J, dp=0):
     val = func(ring, dp=dp)
     dk = numpy.linalg.solve(J, numpy.subtract(newval, val))
     set_value_refpts(ring,
                      refpts1,
                      'PolynomB',
                      dk[0],
                      index=index,
                      increment=True)
     set_value_refpts(ring,
                      refpts2,
                      'PolynomB',
                      dk[1],
                      index=index,
                      increment=True)
     val = func(ring, dp=dp)
     sumsq = numpy.sum(numpy.square(numpy.subtract(val, newval)))
     return sumsq
예제 #5
0
 def _get_resp(ring, index, func, refpts, attname, delta, dp=0):
     set_value_refpts(ring, refpts, attname, delta, index=index,
                      increment=True)
     datap = func(ring, dp=dp)
     set_value_refpts(ring, refpts, attname, -2*delta, index=index,
                      increment=True)
     datan = func(ring, dp=dp)
     set_value_refpts(ring, refpts, attname, delta, index=index,
                      increment=True)
     data = numpy.subtract(datap, datan)/(2*delta)
     return data