Пример #1
0
def _setIdBump(idname, xc, thetac, **kwargs):
    """
    idname - name of ID in the middle of 4 BPMs. 2 BPMs each side.
    xc - beam position at center of ID. [mm]
    thetac - bema angle at center of ID. [mrad]
    plane - 'x' or 'y'. default 'x'.

    Hard coded Error if absolute value:
      - bpms distance > 20.0m or,
      - xc > 5mm, or
      - thetac > 1mrad

    TODO: fix the [mm], [mrad] default unit
    """
    if np.abs(xc) > 5.0 or np.abs(thetac) > 1.0:
        raise RuntimeError("xc or thetac overflow: {0}, {1}".format(
            xc, thetac))

    plane = kwargs.get("plane", 'x')

    nbs = getNeighbors(idname, "COR", n=2)
    cors = [nbs[0], nbs[1], nbs[-2], nbs[-1]]
    cx0 = fget(cors, plane, unitsys=None, handle="setpoint")

    # assuming each ID has two UBPM
    bpmsact = getNeighbors(idname, "BPM", n=1)
    if len(bpmsact) < 3:
        raise RuntimeError("can not find two bounding UBPMs "
                           "for {0}".format(idname))
    bpmsact = [bpmsact[0], bpmsact[-1]]
    allbpms = getGroupMembers(["BPM", "UBPM"], op="union")
    bpmsi, bpmso = getBoundedElements(allbpms, cors[0].sb, cors[-1].se)
    vx0 = fget(bpmsact, plane, unitsys=None)
    # sposition of bpms and ID center
    s0, s1 = [(b.se + b.sb) / 2.0 for b in bpmsact]
    sc = [(c.sb + c.se) / 2.0 for c in getElements(idname)][0]
    L = (bpmsact[-1].se + bpmsact[-1].sb) / 2.0 - \
        (bpmsact[0].se + bpmsact[0].sb) / 2.0
    if L <= 0.0 or L > 20.0:
        raise RuntimeError("ID BPM distance might be wrong: {0}".format(L))
    x0 = xc - (sc - s0) / 1000.0 * thetac
    x1 = xc + (s1 - sc) / 1000.0 * thetac
    dvx = np.array([x0, x1], 'd') - vx0
    dcs = meas4CorBump(cors, bpmsact, bpmso, dvx)
    for i, c in enumerate(cors):
        print(i, c.name, dcs[i])
        c.put(plane, dcs[i] + cx0[i], unitsys=None)
Пример #2
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
Пример #3
0
def _meas4CorBump(cors, bpmins, bpmouts, bpmdx, **kwargs):
    """
    superposition of two 3Cor bumps
    
    cors - list of correctors (4)
    bpmins - BPMs inside the bump
    bpmouts - 
    bpmdx - desired change of orbit for bpmins

    dA1 - change of one cor for ORM fitting, default 0.2
    dA2 - change of one cor for ORM fitting, default 0.2

    """
    dA1 = kwargs.pop("dA1", 0.2)
    dA2 = kwargs.pop("dA2", 0.2)
    plane = kwargs.get("plane", 'x')

    # two bpms
    if len(bpmins) != 2 or len(cors) != 4:
        raise RuntimeError("wrong number of bpms/cors, {0}/{1}".format(
            len(bpmins), len(cors)))

    xv0 = fget(bpmins, plane, unitsys=None, sample=5)
    cv0 = fget(cors, plane, unitsys=None, handle="setpoint")

    m = np.zeros((2, 2), 'd')
    dxout1, dxin1, dcls1 = set3CorBump(cors[:3], dA1, bpmins, bpmouts,
                                       **kwargs)
    fput([(cors[i], plane, cv0[i]) for i in range(len(cors))], unitsys=None)
    time.sleep(0.5)
    xv1 = fget(bpmins, plane, unitsys=None, sample=5)
    cv1 = fget(cors, plane, unitsys=None, handle="setpoint")

    dxout2, dxin2, dcls2 = set3CorBump(cors[1:], dA2, bpmins, bpmouts,
                                       **kwargs)
    fput([(cors[i], plane, cv0[i]) for i in range(len(cors))], unitsys=None)
    time.sleep(0.5)
    xv2 = fget(bpmins, plane, unitsys=None, sample=5)
    cv2 = fget(cors, plane, unitsys=None, handle="setpoint")

    m[:, 0] = dxin1 / dA1
    m[:, 1] = dxin2 / dA2

    mdet = np.linalg.det(m)
    if mdet == 0.0:
        raise RuntimeError("singular config of ({0},{1}) vs ({2},{3})".format(
            bpmins[0].name, bpmins[1].name, cors[0].name, cors[1].name))
    dc1 = (m[1, 1] * bpmdx[0] - m[0, 1] * bpmdx[1]) / mdet
    dc2 = (-m[1, 0] * bpmdx[0] + m[0, 0] * bpmdx[1]) / mdet
    dcs = np.zeros(4, 'd')
    for i in range(3):
        dcs[i] = dcs[i] + dcls1[i] / dA1 * dc1
        dcs[i + 1] = dcs[i + 1] + dcls2[i] / dA2 * dc2
    return dcs
Пример #4
0
def plotLattice(fname,
                h5group="/",
                pvs=[],
                elemflds=[],
                withLive=False,
                figsize=(16, 4)):
    """
    pvs
    elemflds - use readback of this set of (elemobj, field)

    >>> elemflds = [(e, 'b1') for e in ap.getElements("QUAD")]
    >>> plotLattice("snapshot.hdf5", h5group="SR", elemflds=elemflds)
    """
    h5g = h5py.File(fname, 'r')[h5group]
    # assumes scalar, not waveform
    data = np.zeros((len(pvs) + len(elemflds), 2), 'd')
    for i, pv in enumerate(pvs):
        try:
            data[i, 0] = h5g[pv]
        except:
            data[i, 0] = np.nan
    # from (elemname, field) to "element.field" as in h5ds.attrs
    slst = ["%s.%s" % (e.name, fld) for e, fld in elemflds]
    for pv, val in h5g.items():
        if all([v not in slst for v in val.attrs.get("element.field", [])]) or \
                val.size > 1:
            continue
        i = slst.index(val.attrs["element.field"])
        #print i, pv, np.shape(val), val
        data[i + len(pvs), 0] = val.value
    import matplotlib.pylab as plt
    fig = plt.figure(figsize=figsize)
    if withLive:
        data[:len(pvs), 1] = caget(pvs)
        data[len(pvs):, 1] = fget(elemflds, unitsys=None)
        ax1 = plt.subplot(2, 1, 1)
        ax1.plot(data[:, 0], '-x', label="snapshot")
        ax1.plot(data[:, 1], '-o', label="Live")
        ax2 = plt.subplot(2, 1, 2)
        ax2.plot(data[:, 1] - data[:, 0], '-o', label="diff")
        ax2.set_ylabel("Live-snapshot")
    else:
        plt.plot(data[:, 0], '-x', label="snapshot")

    plt.grid(True)
    return fig
Пример #5
0
def setIdBump(idname, xc, thetac, **kwargs):
    """
    idname - name of ID in the middle of 4 BPMs. 2 BPMs each side.
    xc - beam position at center of ID. [mm]
    thetac - bema angle at center of ID. [mrad]
    plane - 'x' or 'y'. default 'x'.
    ncor - number of correctors, default 6 each side.

    Hard coded Error if absolute value:
      - bpms distance > 20.0m or,
      - xc > 5mm, or
      - thetac > 1mrad

    TODO: fix the [mm], [mrad] default unit
    """
    if np.abs(xc) > 5.0 or np.abs(thetac) > 1.0:
        raise RuntimeError("xc or thetac overflow: {0}, {1}".format(
            xc, thetac))

    fld = kwargs.get("plane", 'x')
    ncor = kwargs.get("ncor", 6)
    dImax = kwargs.get("dImax", 0.5)

    idobj = getElements(idname)[0]

    # find the correctors, 3 before ID, 3 after
    cors_ = getNeighbors(idname, "COR", n=ncor)
    cors = cors_[:ncor] + cors_[-ncor:]

    bpms_c = getNeighbors(idname, ["BPM", "UBPM"], n=1)
    bpms_l = getNeighbors(cors[0].name, "BPM", n=ncor - 1)[:ncor - 1]
    bpms_r = getNeighbors(cors[-1].name, "BPM", n=ncor - 1)[1 - ncor:]
    bpms = bpms_l + bpms_c[:1] + bpms_c[-1:] + bpms_r

    ref = fget(bpms, fld, unitsys=None)
    b0, b1 = bpms[ncor - 1], bpms[ncor]
    L = b1.sb - b0.sb
    ref[ncor - 1] = xc - L * thetac / 2.0
    ref[ncor] = xc + L * thetac / 2.0
    norm0, norm1, norm2, corvals = \
        setLocalBump([(b.name, fld) for b in bpms],
                     [(c.name, fld) for c in cors],
                     ref, dImax=dImax, check=True, fullm=False)
    return norm0, norm1, norm2, corvals
Пример #6
0
def plotLattice(fname, h5group="/", pvs=[], elemflds=[], withLive=False, figsize=(16, 4)):
    """
    pvs
    elemflds - use readback of this set of (elemobj, field)

    >>> elemflds = [(e, 'b1') for e in ap.getElements("QUAD")]
    >>> plotLattice("snapshot.hdf5", h5group="SR", elemflds=elemflds)
    """
    h5g = h5py.File(fname, "r")[h5group]
    # assumes scalar, not waveform
    data = np.zeros((len(pvs) + len(elemflds), 2), "d")
    for i, pv in enumerate(pvs):
        try:
            data[i, 0] = h5g[pv]
        except:
            data[i, 0] = np.nan
    # from (elemname, field) to "element.field" as in h5ds.attrs
    slst = ["%s.%s" % (e.name, fld) for e, fld in elemflds]
    for pv, val in h5g.items():
        if all([v not in slst for v in val.attrs.get("element.field", [])]) or val.size > 1:
            continue
        i = slst.index(val.attrs["element.field"])
        # print i, pv, np.shape(val), val
        data[i + len(pvs), 0] = val.value
    import matplotlib.pylab as plt

    fig = plt.figure(figsize=figsize)
    if withLive:
        data[: len(pvs), 1] = caget(pvs)
        data[len(pvs) :, 1] = fget(elemflds, unitsys=None)
        ax1 = plt.subplot(2, 1, 1)
        ax1.plot(data[:, 0], "-x", label="snapshot")
        ax1.plot(data[:, 1], "-o", label="Live")
        ax2 = plt.subplot(2, 1, 2)
        ax2.plot(data[:, 1] - data[:, 0], "-o", label="diff")
        ax2.set_ylabel("Live-snapshot")
    else:
        plt.plot(data[:, 0], "-x", label="snapshot")

    plt.grid(True)
    return fig
Пример #7
0
def measRmCol(resp, kker, kfld, dklst, **kwargs):
    """
    measure the response matrix of `resp` from `kicker`

    :param list resp: list of the response (elem, field)
    :param kker: the kicker object
    :param kfld: the kicker field
    :param list dklst: the kicker setpoints (ki0, ki1, ...)
    :param int sample: observatins per kicker setpoint
    :param int deg: degree of the fitting polynomial
    :param int verbose:

    returns slope, klst(readback), rawdata (nk, nresp, nsamle)
    """
    unitsys = kwargs.pop("unitsys", None)
    sample = kwargs.pop("sample", 3)
    deg = kwargs.pop("deg", 1)
    minwait = kwargs.pop("minwait", 0.0)

    dat = np.zeros((len(dklst), len(resp), sample), 'd')
    klstrb = np.zeros((len(dklst), sample), 'd')
    k0 = kker.get(kfld, handle="setpoint", unitsys=None)
    for i, dki in enumerate(dklst):
        try:
            fput([
                (kker, kfld, k0 + dki),
            ],
                 unitsys=unitsys,
                 wait_readback=True,
                 verbose=1)
        except:
            #kker.put(kfld, k0, unitsys=None)
            _logger.error("{0}".format(sys.exc_info()[0]))
            _logger.error("{0}".format(sys.exc_info()[1]))
            #_logger.error("{0}".format(sys.exc_info()[2]))
            msg = "Timeout at setting {0}.{1}= {2}, i= {3}, delta= {4}".format(
                kker.name, kfld, k0 + dki, i, dki)
            _logger.warn(msg)
            time.sleep(5.0)
            print("{0}.{1}= {2} (set:{3}). continued after 5.0 second".format(
                kker.name, kfld, kker.get(kfld, unitsys=unitsys), k0 + dki))
            sys.stdout.flush()

        time.sleep(minwait)
        for j in range(sample):
            klstrb[i, j] = kker.get(kfld, handle="readback", unitsys=unitsys)
            if kwargs.get("verbose", 0) > 0:
                print("Reading", kker, klstrb[i, j])
            dat[i, :, j] = fget(resp, unitsys=None, **kwargs)

    # nonblocking
    kker.put(kfld, k0, unitsys=None)
    p, resi, rank, sv, rcond = np.polyfit(dklst,
                                          np.average(dat, axis=-1),
                                          deg,
                                          full=True)
    # blocking
    try:
        fput([
            (kker, kfld, k0),
        ], unitsys=None, wait_readback=True)
    except:
        kker.put(kfld, k0, unitsys=None)
        msg = "Timeout at restoring {0}.{1}= {2}".format(kker.name, kfld, k0)
        _logger.warn(msg)
        print(msg)
        sys.stdout.flush()

    return p[-2, :], klstrb, dat