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)
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
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
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
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
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
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