def test_chained_quad(self): pvs = ['V:3-BSR-MG{QL3G2C29A_T1:3694}Fld:I', 'V:3-BSR-MG{QL3G2C29A_T2:7304}Fld:I', 'V:3-BSR-MG{QL3G2C29A_T3:10914}Fld:I'] qs = ap.getElements('ql3g2c29a') self.assertEqual(len(qs), 1) k1 = ap.caget(pvs) self.assertLess(k1[1]/k1[0] - 1.0, 0.005) self.assertLess(k1[2]/k1[0] - 1.0, 0.005) qs[0].k1 = k1[0] * (1+0.01) k1b = ap.caget(pvs) self.assertGreater(qs[0].k1 / k1[0] - 1, 0.005) self.assertLess(k1b[1]/k1b[0] - 1.0, 0.005) self.assertLess(k1b[2]/k1b[0] - 1.0, 0.005)
def test_chained_quad(self): pvs = [ "V:3-BSR-MG{QL3G2C29A_T1:3694}Fld:I", "V:3-BSR-MG{QL3G2C29A_T2:7304}Fld:I", "V:3-BSR-MG{QL3G2C29A_T3:10914}Fld:I", ] qs = ap.getElements("ql3g2c29a") self.assertEqual(len(qs), 1) k1 = ap.caget(pvs) self.assertLess(k1[1] / k1[0] - 1.0, 0.005) self.assertLess(k1[2] / k1[0] - 1.0, 0.005) qs[0].k1 = k1[0] * (1 + 0.01) k1b = ap.caget(pvs) self.assertGreater(qs[0].k1 / k1[0] - 1, 0.005) self.assertLess(k1b[1] / k1b[0] - 1.0, 0.005) self.assertLess(k1b[2] / k1b[0] - 1.0, 0.005)
def run_single_bumps(pvmaps): for pvm in pvmaps: if ap.caget(pvm["cmd"]) == 0: continue ap.caput(pvm["cmddone"], 0) ename = pvm["idname"] if not ename: continue if ap.caget(pvm["op"]) == 0: continue xc, xangle = ap.caget([pvm["offset"], pvm["angle"]]) plane = pvm["XY"].lower() print ename, xc, xangle, plane norm0, norm1, norm2, corvals = ap.setIdBump( ename, xc, xangle, plane=plane, check=False, ncor=6, dImax=0.5) print "Norm:", norm0, norm1, norm2 print corvals ap.caput(pvm["cmddone"], 1) ap.caput(pvm["cmd"], 0) cothread.Yield(0.1)
def run_single_bumps(pvmaps): for pvm in pvmaps: if ap.caget(pvm["cmd"]) == 0: continue ap.caput(pvm["cmddone"], 0) ename = pvm["idname"] if not ename: continue if ap.caget(pvm["op"]) == 0: continue xc, xangle = ap.caget([pvm["offset"], pvm["angle"]]) plane = pvm["XY"].lower() print ename, xc, xangle, plane dImax = ap.caget("SR:APHLA:SOFB{BUMP:ALL}Single-dImax-I") norm0, norm1, norm2, corvals = ap.setIdBump( ename, xc, xangle, plane=plane, check=False, ncor=4, dImax=dImax, bbpms=[pvm["bpm1"], pvm["bpm2"]]) #norm0, norm1, norm2, corvals = ap.setIdBump( # ename, xc, xangle, plane=plane, check=False, ncor=6, dImax=0.5) print "Norm:", norm0, norm1, norm2 print corvals ap.caput(pvm["cmddone"], 1) ap.caput(pvm["cmd"], 0) cothread.Yield(0.1)
def saveState(idobj, output, iiter, parnames=None, background=None, extdata={}): """ parnames - list of extra fields of idobj to be saved. background - the group name for its last background. extdata - extra data dictionary. returns data group name """ t1 = datetime.now() prefix = "background" if background is None else "iter" # create background subgroup with index fid = h5py.File(output, 'a') iterindex = max([int(g[len(prefix)+1:]) for g in list(fid[idobj.name]) if g.startswith(prefix)] + [-1]) + 1 groupName = "{0}_{1:04d}".format(prefix, iterindex) grp = fid[idobj.name].create_group(groupName) orb0 = ap.getOrbit(spos=True) grp["orbit"] = orb0 tau, I = ap.getLifetimeCurrent() grp["lifetime"] = tau grp["current"] = I if parnames is None: parnames = ['gap', 'phase', 'mode'] else: parnames = ['gap', 'phase', 'mode'] + list(parnames) parnames = np.unique(parnames).tolist() fields = idobj.fields() for par in parnames: if par in fields: grp[par] = idobj.get(par, unitsys=None) grp[par].attrs['unitsymb'] = idobj.getUnit(par, unitsys=None) for k,v in extdata.items(): grp[k] = v grp.attrs["iter"] = iiter if background: grp.attrs["background"] = background else: # Save current ID trim setpoints elemflds = createCorrectorField(idobj) _, flds = zip(*elemflds) trim_sps = [idobj.get(ch, unitsys=None, handle='setpoint') for ch in flds] grp['trim_sp'] = trim_sps grp['trim_sp'].attrs['fields'] = flds # Save current BPM offsets try: bpm_offset_pvs = saveState.bpm_offset_pvs bpm_offset_pv_suffixes = saveState.bpm_offset_pv_suffixes bpm_offset_fields = saveState.bpm_offset_fields bpm_names = saveState.bpm_names except AttributeError: bpms = ap.getElements('p[uhlm]*') bpm_names = [b.name for b in bpms] bpm_pv_prefixes = [b.pv(field='xbba')[0].replace('BbaXOff-SP', '') for b in bpms] bpm_offset_fields = ['xbba', 'ybba', 'xref1', 'yref1', 'xref2', 'yref2'] bpm_offset_pv_suffixes = [ bpms[0].pv(field=f)[0].replace(bpm_pv_prefixes[0], '') for f in bpm_offset_fields] bpm_offset_pvs = [] for suf in bpm_offset_pv_suffixes: bpm_offset_pvs += [prefix+suf for prefix in bpm_pv_prefixes] saveState.bpm_offset_pvs = bpm_offset_pvs saveState.bpm_offset_pv_suffixes = bpm_offset_pv_suffixes saveState.bpm_offset_fields = bpm_offset_fields saveState.bpm_names = bpm_names bpm_offsets = np.array( [d.real if d.ok else np.nan for d in ap.caget(bpm_offset_pvs, throw=False)]).reshape( (len(bpm_offset_pv_suffixes), -1)).T grp.create_dataset('bpm_offsets', data=bpm_offsets, compression='gzip') grp['bpm_offsets'].attrs['fields'] = bpm_offset_fields grp['bpm_offsets'].attrs['pv_suffixes'] = bpm_offset_pv_suffixes grp['bpm_offsets'].attrs['bpm_names'] = bpm_names grp.attrs["state_saved"] = t1.strftime("%Y-%m-%d %H:%M:%S.%f") fid.close() return groupName
def createParList(ID, parScale): """ create parameter list based on the paraneter range, spaced type parRange: 2d parameter range in the format of [[name, spacedType, start, end, step, tolerance],...] example:[['gap','log',150,15,21,0.1]] scan table will cover 15~150 with 21 steps, tolerance is 0.1, spacedType: log or linear return parameter list for communicating with hardware, table for data archive """ # Make sure that "gap" specification (if exists) comes at the end. # This is important since, for example, adjusting the gap first and then # adjusting the phase would may well result in an unintentional gap change # due to the associated magnetic force change. fields = [fld for fld, _ in parScale] if 'gap' in fields: gap_index = fields.index('gap') gap_scale = parScale.pop(gap_index) parScale.append(gap_scale) nlist,vlist,tlist = [],[],[] #name, value and tolerance list for fld, scale in parScale: if not _params[ID.name].get(fld, None): continue nlist.append(fld) vmin, vmax, vstep, vtol = _params[ID.name][fld] # Make sure that the scan vector and background values stay within # the minimum and maximum gap/phase allowed. raw2phy = ID.convertUnit(fld, 1.0, None, 'phy', handle='setpoint') field_pvsp = ID.pv(field=fld, handle='setpoint')[0] try: LLim_pv = field_pvsp + '.DRVL' LLim_mm = ap.caget(LLim_pv)*raw2phy print('Lower Limit for {0} = {1:.3g} mm'.format(fld, LLim_mm)) if vmin < LLim_mm: vmin = LLim_mm temp_list = list(_params[ID.name][fld]) temp_list[0] = LLim_mm _params[ID.name][fld] = tuple(temp_list) except: raise print('# WARNING # Lower limit for {0} could not be retrieved.'.format(fld)) LLim_mm = None # try: HLim_pv = field_pvsp + '.DRVH' HLim_mm = ap.caget(HLim_pv)*raw2phy print('Upper Limit for {0} = {1:.3g} mm'.format(fld, HLim_mm)) if vmax < HLim_mm: vmax = HLim_mm temp_list = list(_params[ID.name][fld]) temp_list[1] = HLim_mm _params[ID.name][fld] = tuple(temp_list) except: print('# WARNING # Upper limit for {0} could not be retrieved.'.format(fld)) HLim_mm = None if scale == 'linear': vlist.append(list(np.linspace(vmin, vmax, int(vstep)))) elif scale == 'log': if vmin<=0 or vmax<=0: raise RuntimeError('negative boundary can not be spaced Logarithmically') else: vlist.append(list(np.logspace(np.log10(vmin),np.log10(vmax),int(vstep)))) elif not isinstance(scale, string_types): # "scale" is a user-specified array for the parameter vmin = np.min(scale) vmax = np.max(scale) if (LLim_mm is not None) and (vmin < LLim_mm): raise ValueError( ('Specified array for {0} contains a value smaller than ' 'the lower limit ({1:.3g} mm)').format(fld, LLim_mm)) if (HLim_mm is not None) and (vmax > HLim_mm): raise ValueError( ('Specified array for {0} contains a value larger than ' 'the upper limit ({1:.3g} mm)').format(fld, HLim_mm)) vlist.append(list(scale)) if fld == 'gap': print('Resetting the background "gap" to be the max of user-specified gap array') _params[ID.name]['background'][fld] = vmax # Reset the "gap" or "phase" tuples in _params temp_tup = (vmin, vmax, _params[ID.name][fld][2], _params[ID.name][fld][3]) _params[ID.name][fld] = temp_tup else: raise RuntimeError('unknown spaced pattern: %s'%p[1]) if (HLim_mm is not None) and (_params[ID.name]['background'][fld] > HLim_mm): _params[ID.name]['background'][fld] = HLim_mm print(('Background value of {0} cannot be larger than the ' 'upper limit ({1:.3g} mm)').format(fld, HLim_mm)) if (LLim_mm is not None) and (_params[ID.name]['background'][fld] < LLim_mm): raise ValueError( ('Background value of {0} cannot be smaller than the ' 'lower limit ({1:.3g} mm)').format(fld, LLim_mm)) tlist.append(vtol) valueList = itertools.product(*vlist) parList = [] for v in valueList: tmp = [] for i,n in enumerate(nlist): tmp.append([n,v[i],tlist[i]]) parList.append(tmp) valueList = itertools.product(*vlist) table = [vi for vi in valueList] return parList, nlist, table
for k,v in _tmpl.items(): pv = v.format(**mac) pvls.append((k, pv)) pvdict = dict(pvls) #print k, pv, caget(pv) bpm = ap.getElements(pvdict["bpm1"])[0] if mac["HV"] == "H" and pvdict["hv1"] != bpm.pv(field="xref1")[0]: print bpm.name, mac["HV"], pvdict["hv1"], bpm.pv(field="xref1")[0] pvmaps.append(pvdict) #for b in ap.getElements("UBPM"): # print b.name, b.pv(field="x") print "Start checking IDLocalBump command ..." while True: run_single_bumps(pvmaps) if ap.caget(_pvcmd) == 0: time.sleep(1) continue #obt = ap.getOrbit(spos=True) #print "BPMS:", len(ap.getElements("BPM")), #print np.average(obt[:,0]), np.std(obt[:,0]) for pvm in pvmaps: ap.caput(pvm["cmddone"], 0) for pvm in pvmaps: ename = pvm["idname"] if not ename: continue if ap.caget(pvm["op"]) == 0: continue xc, xangle = ap.caget([pvm["offset"], pvm["angle"]]) plane = pvm["XY"].lower() print ename, xc, xangle, plane dImax = ap.caget("SR:APHLA:SOFB{BUMP:ALL}dImax-I")
def saveState(idobj, output, iiter, parnames=None, background=None, extdata={}): """ parnames - list of extra fields of idobj to be saved. background - the group name for its last background. extdata - extra data dictionary. returns data group name """ t1 = datetime.now() prefix = "background" if background is None else "iter" # create background subgroup with index fid = h5py.File(output) iterindex = max([int(g[len(prefix) + 1 :]) for g in fid[idobj.name].keys() if g.startswith(prefix)] + [-1]) + 1 groupName = "{0}_{1:04d}".format(prefix, iterindex) grp = fid[idobj.name].create_group(groupName) orb0 = ap.getOrbit(spos=True) grp["orbit"] = orb0 tau, I = ap.getLifetimeCurrent() grp["lifetime"] = tau grp["current"] = I if parnames is None: parnames = ["gap", "phase", "mode"] else: parnames = ["gap", "phase", "mode"] + list(parnames) parnames = np.unique(parnames).tolist() fields = idobj.fields() for par in parnames: if par in fields: grp[par] = idobj.get(par, unitsys=None) grp[par].attrs["unitsymb"] = idobj.getUnit(par, unitsys=None) for k, v in extdata.items(): grp[k] = v grp.attrs["iter"] = iiter if background: grp.attrs["background"] = background else: # Save current ID trim setpoints elemflds = createCorrectorField(idobj) _, flds = zip(*elemflds) trim_sps = [idobj.get(ch, unitsys=None, handle="setpoint") for ch in flds] grp["trim_sp"] = trim_sps grp["trim_sp"].attrs["fields"] = flds # Save current BPM offsets try: bpm_offset_pvs = saveState.bpm_offset_pvs bpm_offset_pv_suffixes = saveState.bpm_offset_pv_suffixes bpm_offset_fields = saveState.bpm_offset_fields bpm_names = saveState.bpm_names except AttributeError: bpms = ap.getElements("p[uhlm]*") bpm_names = [b.name for b in bpms] bpm_pv_prefixes = [b.pv(field="xbba")[0].replace("BbaXOff-SP", "") for b in bpms] bpm_offset_fields = ["xbba", "ybba", "xref1", "yref1", "xref2", "yref2"] bpm_offset_pv_suffixes = [bpms[0].pv(field=f)[0].replace(bpm_pv_prefixes[0], "") for f in bpm_offset_fields] bpm_offset_pvs = [] for suf in bpm_offset_pv_suffixes: bpm_offset_pvs += [prefix + suf for prefix in bpm_pv_prefixes] saveState.bpm_offset_pvs = bpm_offset_pvs saveState.bpm_offset_pv_suffixes = bpm_offset_pv_suffixes saveState.bpm_offset_fields = bpm_offset_fields saveState.bpm_names = bpm_names bpm_offsets = ( np.array([d.real if d.ok else np.nan for d in ap.caget(bpm_offset_pvs, throw=False)]) .reshape((len(bpm_offset_pv_suffixes), -1)) .T ) grp.create_dataset("bpm_offsets", data=bpm_offsets, compression="gzip") grp["bpm_offsets"].attrs["fields"] = bpm_offset_fields grp["bpm_offsets"].attrs["pv_suffixes"] = bpm_offset_pv_suffixes grp["bpm_offsets"].attrs["bpm_names"] = bpm_names grp.attrs["state_saved"] = t1.strftime("%Y-%m-%d %H:%M:%S.%f") fid.close() return groupName
def createParList(ID, parScale): """ create parameter list based on the paraneter range, spaced type parRange: 2d parameter range in the format of [[name, spacedType, start, end, step, tolerance],...] example:[['gap','log',150,15,21,0.1]] scan table will cover 15~150 with 21 steps, tolerance is 0.1, spacedType: log or linear return parameter list for communicating with hardware, table for data archive """ # Make sure that "gap" specification (if exists) comes at the end. # This is important since, for example, adjusting the gap first and then # adjusting the phase would may well result in an unintentional gap change # due to the associated magnetic force change. fields = [fld for fld, _ in parScale] if "gap" in fields: gap_index = fields.index("gap") gap_scale = parScale.pop(gap_index) parScale.append(gap_scale) nlist, vlist, tlist = [], [], [] # name, value and tolerance list for fld, scale in parScale: if not _params[ID.name].get(fld, None): continue nlist.append(fld) vmin, vmax, vstep, vtol = _params[ID.name][fld] # Make sure that the scan vector and background values stay within # the minimum and maximum gap/phase allowed. raw2phy = ID.convertUnit(fld, 1.0, None, "phy", handle="setpoint") field_pvsp = ID.pv(field=fld, handle="setpoint")[0] try: LLim_pv = field_pvsp + ".DRVL" LLim_mm = ap.caget(LLim_pv) * raw2phy print "Lower Limit for {0} = {1:.3g} mm".format(fld, LLim_mm) if vmin < LLim_mm: vmin = LLim_mm temp_list = list(_params[ID.name][fld]) temp_list[0] = LLim_mm _params[ID.name][fld] = tuple(temp_list) except: raise print "# WARNING # Lower limit for {0} could not be retrieved.".format(fld) LLim_mm = None # try: HLim_pv = field_pvsp + ".DRVH" HLim_mm = ap.caget(HLim_pv) * raw2phy print "Upper Limit for {0} = {1:.3g} mm".format(fld, HLim_mm) if vmax < HLim_mm: vmax = HLim_mm temp_list = list(_params[ID.name][fld]) temp_list[1] = HLim_mm _params[ID.name][fld] = tuple(temp_list) except: print "# WARNING # Upper limit for {0} could not be retrieved.".format(fld) HLim_mm = None if scale == "linear": vlist.append(list(np.linspace(vmin, vmax, int(vstep)))) elif scale == "log": if vmin <= 0 or vmax <= 0: raise RuntimeError("negative boundary can not be spaced Logarithmically") else: vlist.append(list(np.logspace(np.log10(vmin), np.log10(vmax), int(vstep)))) elif not isinstance(scale, (str, unicode)): # "scale" is a user-specified array for the parameter vmin = np.min(scale) vmax = np.max(scale) if (LLim_mm is not None) and (vmin < LLim_mm): raise ValueError( ("Specified array for {0} contains a value smaller than " "the lower limit ({1:.3g} mm)").format( fld, LLim_mm ) ) if (HLim_mm is not None) and (vmax > HLim_mm): raise ValueError( ("Specified array for {0} contains a value larger than " "the upper limit ({1:.3g} mm)").format( fld, HLim_mm ) ) vlist.append(list(scale)) if fld == "gap": print 'Resetting the background "gap" to be the max of user-specified gap array' _params[ID.name]["background"][fld] = vmax # Reset the "gap" or "phase" tuples in _params temp_tup = (vmin, vmax, _params[ID.name][fld][2], _params[ID.name][fld][3]) _params[ID.name][fld] = temp_tup else: raise RuntimeError("unknown spaced pattern: %s" % p[1]) if (HLim_mm is not None) and (_params[ID.name]["background"][fld] > HLim_mm): _params[ID.name]["background"][fld] = HLim_mm print ("Background value of {0} cannot be larger than the " "upper limit ({1:.3g} mm)").format(fld, HLim_mm) if (LLim_mm is not None) and (_params[ID.name]["background"][fld] < LLim_mm): raise ValueError( ("Background value of {0} cannot be smaller than the " "lower limit ({1:.3g} mm)").format(fld, LLim_mm) ) tlist.append(vtol) valueList = itertools.product(*vlist) parList = [] for v in valueList: tmp = [] for i, n in enumerate(nlist): tmp.append([n, v[i], tlist[i]]) parList.append(tmp) valueList = itertools.product(*vlist) table = [vi for vi in valueList] return parList, nlist, table
def markForStablePv(): global ref_v0, PV_REF_RB ref_v0 = np.array(ap.caget(PV_REF_RB), 'd')
PV_SR_DCCT='V:2-SR-BI{DCCT}CUR-I' PV_REF_RB = [ "V:2-SR:C15-BI:G2{PL1:1845}SA:X", "V:2-SR:C15-BI:G2{PL1:1845}SA:Y", "V:2-SR:C15-BI:G2{PL2:1865}SA:X", "V:2-SR:C15-BI:G2{PL2:1865}SA:Y", "V:2-SR:C15-BI:G4{PM1:1890}SA:X", "V:2-SR:C15-BI:G4{PM1:1890}SA:Y", "V:2-SR:C15-BI:G4{PM1:1900}SA:X", "V:2-SR:C15-BI:G4{PM1:1900}SA:Y", "V:2-SR:C15-BI:G6{PH2:1924}SA:X", "V:2-SR:C15-BI:G6{PH2:1924}SA:Y", "V:2-SR:C15-BI:G6{PH1:1939}SA:X", "V:2-SR:C15-BI:G6{PH1:1939}SA:Y" ] ref_v0 = np.array(ap.caget(PV_REF_RB), 'd') # name of BPMs BPM1='ph2g2c30a' BPM2='pm1g4c30a' # plotting ? PLOTTING = True V1LTD1_OFFLINE = False try: catools.caget("LTB:BI{BPM:1}Pos:X-I") except: V1LTD1_OFFLINE = True logging.info("V1LTD1_OFFLINE={0}".format(V1LTD1_OFFLINE))
for k,v in _tmpl.items(): pv = v.format(**mac) pvls.append((k, pv)) pvdict = dict(pvls) #print k, pv, caget(pv) bpm = ap.getElements(pvdict["bpm1"])[0] if mac["HV"] == "H" and pvdict["hv1"] != bpm.pv(field="xref1")[0]: print bpm.name, mac["HV"], pvdict["hv1"], bpm.pv(field="xref1")[0] pvmaps.append(pvdict) #for b in ap.getElements("UBPM"): # print b.name, b.pv(field="x") print "Start checking IDLocalBump command ..." while True: run_single_bumps(pvmaps) if ap.caget(_pvcmd) == 0: time.sleep(1) continue #obt = ap.getOrbit(spos=True) #print "BPMS:", len(ap.getElements("BPM")), #print np.average(obt[:,0]), np.std(obt[:,0]) for pvm in pvmaps: ap.caput(pvm["cmddone"], 0) for pvm in pvmaps: ename = pvm["idname"] if not ename: continue if ap.caget(pvm["op"]) == 0: continue xc, xangle = ap.caget([pvm["offset"], pvm["angle"]]) plane = pvm["XY"].lower() print ename, xc, xangle, plane norm0, norm1, norm2, corvals = ap.setIdBump(