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