Exemple #1
0
def _set3CorBump(cors, dIc0, bpmins, bpmouts, **kwargs):
    """
    cors - list of three correctors
    dIc0 - the I change for the first corrector in *cors* (i.e. raw unit)
    bpmouts - bpm outside the bump
    bpmins - bpm inside the bump
    plane - 'x' or 'y' (default 'x')
    dxmax - max dI for ORM measurement, default 0.2
    orm - optional, orbit response matrix (n,3) shape.

    set the cors and returns the current change (i.e. delta I)

    returns orbit change outside bump, inside bump and current change of cors.
    if no bpmins provided, None returned for orbit change inside bump.
    """
    corls = getElements(cors)
    plane = kwargs.get("plane", 'x').lower()
    dxmax = kwargs.get("dxmax", 0.2)
    m = kwargs.get("orm", None)

    obt0 = fget(bpmouts + bpmins, plane, unitsys=None, sample=5)

    # remeasure the response matrix (n,3)
    if m is None:
        m, output = measOrbitRm([(b, plane) for b in bpmouts],
                                [(c, plane) for c in corls[1:]],
                                dxmax=dxmax,
                                nx=2,
                                unitsys=None)
    print("ORM:", m)
    print("output:", output)
    bpmpvs = [b.pv(field=plane)[0] for b in bpmouts]
    corpvs = [c.pv(field=plane)[0] for c in corls[1:]]

    cv0 = fget(corls, plane, unitsys=None, handle="setpoint")
    cors[0].put(plane, cv0[0] + dIc0, unitsys=None)
    time.sleep(0.3)

    obt1 = fget(bpmouts + bpmins, plane, unitsys=None, sample=5)
    print("dx after one kick:", obt1 - obt0)
    err, msg = caRmCorrect(bpmpvs, corpvs, m)
    cv1 = fget(cors, plane, unitsys=None)
    obt2 = fget(bpmouts + bpmins, plane, unitsys=None, sample=5)
    dc = [cv1[i] - cv0[i] for i, c in enumerate(corls)]
    dxins = (obt2 - obt0)[len(bpmouts):] if bpmins else None
    dxouts = (obt2 - obt0)[:len(bpmouts)]
    return dxouts, dxins, dc
Exemple #2
0
def setLocalBump(bpmrec, correc, ref, **kwargs):
    """
    create a local bump at certain BPM, while keep all other orbit untouched
    
    :param list bpm: list of (name, field) for BPMs. 
    :param list trim: list of (name, field) for correctors. 
    :param list dead: name list of dead BPMs and correctors names.
    :param list ref: target values for the list of (bpmname, field).
    :param float scale: optional, factor to scale calculated kick strength change, between 0 and 1.0
    :param bool check: optional, roll back the corrector settings if the orbit gets worse.
    :param float rcond: optional, (1e-4). rcond*max_singularvalue will be kept.
    :param ormdata: optional, :class:`~aphla.apdata.OrmData`. Use provided OrmData instead of the system default.
    :return: `(err, msg)`. The error code and message.

    Notes
    ------
    if `ref[i][j]` is `None`, use the current hardware result, i.e. try not to
    change the orbit at that location.

    The bpm and corrector must have 'x' and 'y' field.

    This is a least square fitting method. It is possible that the orbit at
    the other BPMs may change slightly although they are told to be fixed.

    see also :func:`~aphla.catools.caRmCorrect` for EPICS based
    system. :func:`~aphla.apdata.OrmData.getMatrix`

    Examples
    ---------
    >>> bpms = getGroupMembers(['BPM', 'C02'])
    >>> newobt = [[1.0, 1.5]] * len(bpms)
    >>> createLocalBump(bpms, getElements('HCOR'), newobt)
    
    """

    ormdata = kwargs.pop('ormdata', machines._lat.ormdata)
    repeat = kwargs.pop('repeat', 1)
    fullm = kwargs.pop("fullm", True)

    if ormdata is None:
        raise RuntimeError("No Orbit Response Matrix available for '%s'" %
                           machines._lat.name)
    if fullm:
        # use the full available matrix
        bpmr = ormdata.getBpm()
        corr = ormdata.getCor()
        m = ormdata.m
        obtref = [None] * len(m)
        for i, (b, fld) in enumerate(bpmr):
            if (b, fld) not in bpmrec: continue
            k = bpmrec.index((b, fld))
            obtref[i] = ref[k]
    else:
        # use the sub common set
        bpmr = [r for r in ormdata.bpm if r in bpmrec]
        corr = [r for r in ormdata.cor if r in correc]
        m = np.zeros((len(bpmr), len(corr)), 'd')
        obtref = [None] * len(bpmr)
        for i, br in enumerate(bpmr):
            k = bpmrec.index(br)
            obtref[i] = ref[k]
            for j, cr in enumerate(corr):
                m[i, j] = ormdata.get(br, cr)

    for i, (name, field) in enumerate(bpmr):
        if obtref[i] is not None: continue
        obtref[i] = getExactElement(name).get(field, unitsys=None)

    bpmpvs = [getExactElement(b).pv(field=f)[0] for b, f in bpmr]
    corpvs = [
        getExactElement(t).pv(field=f, handle='setpoint')[0] for t, f in corr
    ]

    # correct orbit using default ORM (from current lattice)
    norm0, norm1, norm2, corvals = None, None, None, None
    for i in range(repeat):
        #for k,b in enumerate(bpmpvs):
        #    if bpmref[k] != 0.0: print(k, bpmlst[k], b, bpmref[k])
        norm0, norm1, norm2, corvals = \
            caRmCorrect(bpmpvs, corpvs, m, ref=np.array(obtref), **kwargs)
        if corvals is None: break

    return norm0, norm1, norm2, corvals