def _checkOrbitRmData(od): vbpm, vtrim = [], [] for rec in od.bpm: if rec[0] is None: vbpm.append([None, None, None]) continue elem = getElements(rec[0].lower()) if not elem: vbpm.append([rec[0], None, None]) continue pv = elem[0].pv(field=rec[1].lower(), handle='readback') if pv != rec[2]: vbpm.append([elem[0].name, rec[2], pv]) #for v in vbpm: print (v) for rec in od.trim: if rec[0] is None: vtrim.append([None, None, None, None]) continue elem = getElements(rec[0].lower()) if not elem: vtrim.append([rec[0], None, None, None]) continue pv = elem[0].pv(field=rec[1].lower(), handle='readback') if pv != rec[2]: vtrim.append([elem[0].name, rec[2], pv]) pv = elem[0].pv(field=rec[1].lower(), handle='setpoint') if pv != rec[3]: vtrim.append([elem[0].name, rec[3], pv]) #for v in vtrim: print (v) return vbpm, vtrim
def measTuneRm(quad, **kwargs): """ measure the tune response matrix """ output = kwargs.pop("output", None) if output is True: output = outputFileName("respm", "tunerm") qls = getElements(quad) _logger.info("Tune RM: {0}".format([q.name for q in qls])) quads = [] for i, q in enumerate(qls): pv = q.pv(field="b1", handle="setpoint") if not pv: continue assert len(pv) == 1, "More than 1 pv found for {0}".format(q.name) quads.append((q.name, "b1", pv[0])) tune = getElements("tune") if not tune: raise RuntimeError("Can not find tune element") assert "x" in tune[0].fields(), "Can not find tune x" assert "y" in tune[0].fields(), "Can not find tune y" nupvs = [ tune[0].pv(field="x", handle="readback")[0], tune[0].pv(field="y", handle="readback")[0] ] m = np.zeros((2, len(quads)), 'd') for i, (name, fld, pv) in enumerate(quads): mc, dxlst, rawdat = measCaRmCol(pv, nupvs, **kwargs) m[:, i] = mc time.sleep(kwargs.get("wait", 1.5)) if output: f = h5py.File(output) if pv in f: del f[pv] g = f.create_group(pv) g["m"] = m[:, i] g["m"].attrs["quad_name"] = name g["m"].attrs["quad_field"] = fld g["m"].attrs["quad_pv"] = pv g["tunes"] = rawdat g["tunes"].attrs["pv"] = nupvs g["dx"] = dxlst f.close() if output: f = h5py.File(output) if "m" in f: del f["m"] f["m"] = m f["m"].attrs["quad_name"] = [r[0] for r in quads] f["m"].attrs["quad_field"] = [r[1] for r in quads] f["m"].attrs["quad_pv"] = [r[2] for r in quads] f.close() return m
def correctOrbit(bpm, cor, **kwargs): """ correct the orbit with given BPMs and Trims Parameters ----------- bpm : list of BPM objects, default all 'BPM' cor : list of Trim objects, default all 'COR' plane : optional, [ 'XY' | 'X' | 'Y' ], default 'XY' rcond : optional, cutting ratio for singular values, default 1e-4. scale : optional, scaling corrector strength, default 0.68 repeat : optional, integer, default 1. numbers of correction deadlst : list of dead BPM and corrector names. dImax : optional, maximum corrector change at correction. Notes ----- This routine prepares the target orbit and then calls :func:`setLocalBump`. seealso :func:`~aphla.hlalib.getElements`, :func:`~aphla.getSubOrm`, :func:`setLocalBump`. Examples --------- >>> bpms = getElements(['BPM1', 'BPM2']) >>> trims = getElements(['T1', 'T2', 'T3']) >>> correctOrbit(bpms, trims) """ plane = kwargs.pop('plane', 'XY').lower() # using rcond 1e-4 if not provided. kwargs.setdefault('rcond', 1e-4) kwargs.setdefault('scale', 0.68) bpmlst = [e for e in getElements(bpm) if e.isEnabled()] corlst = [e for e in getElements(cor) if e.isEnabled()] if kwargs.get("verbose", 0) > 0: print("Using: %d bpms, %d cors" % (len(bpmlst), len(corlst))) bpmr, corr, ref = [], [], [] for fld in ["x", "y"]: for bpm in bpmlst: if fld in bpm.fields() and fld in plane: bpmr.append((bpm.name, fld)) ref.append(0.0) for cor in corlst: if fld in cor.fields() and fld in plane: corr.append((cor.name, fld)) if kwargs.get("verbose", 0) > 0: print("Using: %d bpms, %d cors" % (len(bpmr), len(corr))) kwargs["fullm"] = False return setLocalBump(bpmr, corr, ref, **kwargs)
def resetBrBpms(wfmsel = 1): """ reset the BPMs to external trigger and Tbt waveform. Offset is 0 for all Adc, Tbt and Fa waveforms. """ pvprefs = [bpm.pv(field="x")[0].replace("Pos:X-I", "") for bpm in getElements("BPM")] for i,pvx in enumerate(pvprefs): pvs = [ pvx + "Trig:TrigSrc-SP" for pvx in pvprefs] caput(pvs, 1, wait=True) # 0 - Adc, 1 - Tbt, 2 - Fa pvs = [ pvx + "DDR:WfmSel-SP" for pvx in pvprefs] caput(pvs, wfmsel, wait=True) # enable all three waveforms pvs = [ pvx + "ddrAdcWfEnable" for pvx in pvprefs] caput(pvs, 1, wait=True) pvs = [ pvx + "ddrTbtWfEnable" for pvx in pvprefs] caput(pvs, 1, wait=True) pvs = [ pvx + "ddrFaWfEnable" for pvx in pvprefs] caput(pvs, 1, wait=True) # pvs = [ pvx + "ddrAdcOffset" for pvx in pvprefs] caput(pvs, 0, wait=True) pvs = [ pvx + "ddrTbtOffset" for pvx in pvprefs] caput(pvs, 0, wait=True) pvs = [ pvx + "ddrFaOffset" for pvx in pvprefs] caput(pvs, 0, wait=True)
def resetBrBpms(wfmsel=1): """ reset the BPMs to external trigger and Tbt waveform. Offset is 0 for all Adc, Tbt and Fa waveforms. """ pvprefs = [ bpm.pv(field="x")[0].replace("Pos:X-I", "") for bpm in getElements("BPM") ] for i, pvx in enumerate(pvprefs): pvs = [pvx + "Trig:TrigSrc-SP" for pvx in pvprefs] caput(pvs, 1, wait=True) # 0 - Adc, 1 - Tbt, 2 - Fa pvs = [pvx + "DDR:WfmSel-SP" for pvx in pvprefs] caput(pvs, wfmsel, wait=True) # enable all three waveforms pvs = [pvx + "ddrAdcWfEnable" for pvx in pvprefs] caput(pvs, 1, wait=True) pvs = [pvx + "ddrTbtWfEnable" for pvx in pvprefs] caput(pvs, 1, wait=True) pvs = [pvx + "ddrFaWfEnable" for pvx in pvprefs] caput(pvs, 1, wait=True) # pvs = [pvx + "ddrAdcOffset" for pvx in pvprefs] caput(pvs, 0, wait=True) pvs = [pvx + "ddrTbtOffset" for pvx in pvprefs] caput(pvs, 0, wait=True) pvs = [pvx + "ddrFaOffset" for pvx in pvprefs] caput(pvs, 0, wait=True)
def saveImage(elemname, filename, **kwargs): """ save field as image file :param field: element field to save, default 'image' :param filename: output file name :param width: image width (pixel), default 'image_nx' :param height: image height (pixel), default 'image_ny' :param xlim: range of pixels, e.g. (700, 900) :param ylim: range of pixels, e.g. (700, 900) :Example: >>> saveImage('VF1BD1', 'test.png', fitgaussian=True, xlim=(750,850), ylim=(550,650)) The tag of CFS should give "field_nx" and "field_ny" for field. if width or height is None, use "field_nx" and "field_ny". """ #import Image #import ImageDraw import matplotlib.pylab as plt import numpy as np field = kwargs.get('field', 'image') fitgaussian = kwargs.get('fitgaussian', False) elem = getElements(elemname)[0] d = elem.get(field, unitsys=None) width = kwargs.get('width', elem.get(field + "_nx", unitsys=None)) height = kwargs.get('height', elem.get(field + "_ny", unitsys=None)) xlim = kwargs.get('xlim', (0, width)) ylim = kwargs.get('ylim', (0, height)) d2 = np.reshape(d, (height, width)) use_pil = False if use_pil: im = Image.fromarray(d2) im.save(filename) else: plt.clf() fig = plt.figure() ax = fig.add_subplot(111) im = ax.imshow(d2, interpolation="nearest", cmap=plt.cm.jet, origin=kwargs.get("origin", "upper")) cb = plt.colorbar(im) #ax.set_xlim(xlim) #ax.set_ylim(ylim) if fitgaussian: params = fitGaussianImage(d2) (height, y, x, width_y, width_x) = params ax.text(0.95, 0.05, "x : %.1f\ny : %.1f\n" \ "width_x : %.1f\nwidth_y : %.1f" % \ (x, y, width_x, width_y), fontsize=16, horizontalalignment='right', verticalalignment='bottom', transform=ax.transAxes) plt.savefig(filename)
def _random_kick(plane='V', amp=1e-9, verbose=0): """ kick the beam with a random kicker """ dk = np.random.rand() * amp if plane == 'V': trim = getElements('VCOR') elif plane == 'H': trim = getElements('HCOR') else: raise ValueError("unknow plane '%s'" % plane) i = np.random.randint(len(trim)) k0 = trim[i].value if verbose: print("setting %s %e shift %e" % (trim[i].name, k0, dk)) trim[i].value = k0 + dk
def measBeta(elem, dqk1=0.01, full=False, num_points=3, verbose=0): """ Measure the beta function by varying quadrupole strength Parameters ----------- elem : element name, name list or pattern. dqk1 : float. the quadrupole change range [-dqk1, dqk1] full : bool. returns more data besides beta num_points : int. points in [-dqk1, dqk1] to fit the line, default 3. verbose : verbose Returns -------- beta : numpy array (N_elements, 3). fitted betax, betay and s_center k1, nu : optional. present only if *full*=True. k1 is numpy array (N_elements, num_points), quadrupole settings. nu is numpy array (N_elements, num_points, 2). tunes. Notes ------ see `getElements` for acceptable *elem* format. Some users prefer using turn-by-turn BPM data to calculate the beta functions """ elems = getElements(elem) if elems is None: raise ValueError("can not find element '%s'" % elem) if verbose: print("# fitting %d quadrupoles:" % len(elems)) print("# " + ' '.join([q.name for q in elems])) kwargs = {'dqk1': dqk1, 'num_points': num_points, 'verbose': verbose} nux, nuy = getTunes() nu = np.zeros((len(elems), num_points, 2), 'd') k1 = np.zeros((len(elems), num_points), 'd') beta = np.zeros((len(elems), 3), 'd') for i, q in enumerate(elems): beta[i, -1] = (q.sb + q.se) / 2.0 # is an element k1[i, :], nu[i, :, :] = _measBetaQuad(q, **kwargs) if verbose: print(i, q.name, q.k1, end=" ") p, res, rank, sv, rcond = np.polyfit(k1[i, :], nu[i, :, :], deg=1, full=True) # p[0,k] is the highest power for dataset k beta[i, :2] = p[0, :] * 4 * np.pi / q.length # reverse the k1 for vertical direction beta[i, 1] = -beta[i, 1] print(q.sb, q.name, beta[i, 0], beta[i, 1], p[0, :]) if full: return beta, k1, nu else: return beta
def measBeta(elem, dqk1=0.01, full=False, num_points=3, verbose=0): """ Measure the beta function by varying quadrupole strength Parameters ----------- elem : element name, name list or pattern. dqk1 : float. the quadrupole change range [-dqk1, dqk1] full : bool. returns more data besides beta num_points : int. points in [-dqk1, dqk1] to fit the line, default 3. verbose : verbose Returns -------- beta : numpy array (N_elements, 3). fitted betax, betay and s_center k1, nu : optional. present only if *full*=True. k1 is numpy array (N_elements, num_points), quadrupole settings. nu is numpy array (N_elements, num_points, 2). tunes. Notes ------ see `getElements` for acceptable *elem* format. Some users prefer using turn-by-turn BPM data to calculate the beta functions """ elems = getElements(elem) if elems is None: raise ValueError("can not find element '%s'" % elem) if verbose: print("# fitting %d quadrupoles:" % len(elems)) print("# " + " ".join([q.name for q in elems])) kwargs = {"dqk1": dqk1, "num_points": num_points, "verbose": verbose} nux, nuy = getTunes() nu = np.zeros((len(elems), num_points, 2), "d") k1 = np.zeros((len(elems), num_points), "d") beta = np.zeros((len(elems), 3), "d") for i, q in enumerate(elems): beta[i, -1] = (q.sb + q.se) / 2.0 # is an element k1[i, :], nu[i, :, :] = _measBetaQuad(q, **kwargs) if verbose: print(i, q.name, q.k1, end=" ") p, res, rank, sv, rcond = np.polyfit(k1[i, :], nu[i, :, :], deg=1, full=True) # p[0,k] is the highest power for dataset k beta[i, :2] = p[0, :] * 4 * np.pi / q.length # reverse the k1 for vertical direction beta[i, 1] = -beta[i, 1] print(q.sb, q.name, beta[i, 0], beta[i, 1], p[0, :]) if full: return beta, k1, nu else: return beta
def stripView(elempat, field, **kwargs): """ open a striptool to view live stream data - elempat, element name, name list, object list, family or pattern. - field, element field - handle, optional, "readback" or "setpoint" - pvs, optional, extra list of PVs. """ handle = kwargs.get("handle", "readback") pvs = kwargs.get("pvs", []) for e in getElements(elempat): pvs.extend(e.pv(field=field, handle=handle)) fcfg, fname = tempfile.mkstemp(suffix=".stp", prefix="aphla-", text=True) import os os.write( fcfg, """StripConfig 1.2 Strip.Time.Timespan 300 Strip.Time.NumSamples 7200 Strip.Time.SampleInterval 1.000000 Strip.Time.RefreshInterval 1.000000 Strip.Color.Background 65535 65535 65535 Strip.Color.Foreground 0 0 0 Strip.Color.Grid 49087 49087 49087 Strip.Color.Color1 0 0 65535 Strip.Color.Color2 27499 36494 8995 Strip.Color.Color3 42405 10794 10794 Strip.Color.Color4 24415 40606 41120 Strip.Color.Color5 65535 42405 0 Strip.Color.Color6 41120 8224 61680 Strip.Color.Color7 65535 0 0 Strip.Color.Color8 65535 55255 0 Strip.Color.Color9 48316 36751 36751 Strip.Color.Color10 39578 52685 12850 Strip.Option.GridXon 1 Strip.Option.GridYon 1 Strip.Option.AxisYcolorStat 1 Strip.Option.GraphLineWidth 2 """) for i, pv in enumerate(pvs): os.write(fcfg, "Strip.Curve.%d.Name %s\n" % (i, pv)) #os.write(fcfg, "Strip.Curve.%d.Units mA\n" % i) #os.write(fcfg, "Strip.Curve.%d.Min 0.0\n" % i) #os.write(fcfg, "Strip.Curve.%d.Max 1.0\n" % i) #os.write(fcfg, "Strip.Curve.%d.Comment %d\n" % (i, i)) os.write(fcfg, "Strip.Curve.%d.Precision 6\n" % i) os.write(fcfg, "Strip.Curve.%d.Scale 0\n" % i) os.write(fcfg, "Strip.Curve.%d.PlotStatus 1\n" % i) os.close(fcfg) from subprocess import Popen Popen(["striptool", fname])
def __init__(self, resplst, kicker): """ Initialization .. highlight:: python ormline = RmCol(['BPM1', 'BPM2'], 'trim') """ self.minwait = 4 self.stepwait = 2 self.bpmdiffstd = 1e-5 self.points = 6 self.resplst = getElements(resplst) self.kicker = getElements(kicker)[0] self.rawresp = None self.mask = None self.rawkick = None self.m = None self.header = None self._c = None self.unit = None # use lowerlevel unit self.maxdk = 1e-4 self.residuals = None
def __init__(self, bpm, trim): """ Initialize an Orm object with a list of BPMs and Trims .. highlight:: python orm = OrbitRespMat(['BPM1', 'BPM2'], ['TRIM1', 'TRIM2']) """ # points for trim setting when calc dx/dkick self.ormdata = None npts = 6 self.minwait = 3 # minimum wait 3 seconds self.stepwait = 1.5 self.bpmdiffstd = 1e-5 self.bpm = getElements(bpm) self.trim = getElements(trim) self.bpmhdr = None # the header [(name, sb, field, pv=None), ...] self.trimhdr = None # the header [(name, sb, field, pvrb, pvsp), ...] _logger.info("bpm rec: %s" % str(self.bpm)) _logger.info("trim rec: %s" % str(self.trim)) # count the dimension of matrix #nbpm, ntrim = len(set(bpm)), len(set(trim)) nbpmpv, ntrimpv = len(self.bpm), len(self.trim) # 3d raw data self._raworbit = None #np.zeros((npts+2, nbpmpv, ntrimpv), 'd') self._mask = None #np.zeros((nbpmpv, ntrimpv), 'i') self._rawkick = None #np.zeros((ntrimpv, npts+2), 'd') self.m = None # np.zeros((nbpmpv, ntrimpv), 'd') self.unit = None # raw unit
def __init__(self, bpm, trim): """ Initialize an Orm object with a list of BPMs and Trims .. highlight:: python orm = OrbitRespMat(['BPM1', 'BPM2'], ['TRIM1', 'TRIM2']) """ # points for trim setting when calc dx/dkick self.ormdata = None npts = 6 self.minwait = 3 # minimum wait 3 seconds self.stepwait = 1.5 self.bpmdiffstd = 1e-5 self.bpm = getElements(bpm) self.trim = getElements(trim) self.bpmhdr = None # the header [(name, sb, field, pv=None), ...] self.trimhdr = None # the header [(name, sb, field, pvrb, pvsp), ...] logger.info("bpm rec: %s" % str(self.bpm)) logger.info("trim rec: %s" % str(self.trim)) # count the dimension of matrix #nbpm, ntrim = len(set(bpm)), len(set(trim)) nbpmpv, ntrimpv = len(self.bpm), len(self.trim) # 3d raw data self._raworbit = None #np.zeros((npts+2, nbpmpv, ntrimpv), 'd') self._mask = None #np.zeros((nbpmpv, ntrimpv), 'i') self._rawkick = None #np.zeros((ntrimpv, npts+2), 'd') self.m = None # np.zeros((nbpmpv, ntrimpv), 'd') self.unit = None # raw unit
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 _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 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 _brBpmScrub(**kwargs): """ waveforms - list of Tbt, Fa and Adc """ lat = machines.getLattice() if lat.name != "BR": raise RuntimeError("the current lattice is not 'BR': %s" % lat.name) waveforms = kwargs.get("waveforms", ["Tbt", "Fa", "Adc"]) bpms = getElements("BPM") # did not consider the 'ddrTbtWfEnable' PV for bpm in bpms: pvx = bpm.pv(field="x")[0] pv = pvx.replace("Pos:X-I", "Trig:TrigSrc-SP") # 0 - internal, 1 - external caput(pv, 0, wait=True) pv = pvx.replace("Pos:X-I", "DDR:WfmSel-SP") for fld in waveforms: pv = pvx.replace("Pos:X-I", "ddr%sWfEnable" % fld) caput(pv, 0, wait=True) # offset pv = pvx.replace("Pos:X-I", "ddr%sOffset" % fld) caput(pv, 0, wait=True) time.sleep(2) for bpm in bpms: pvx = bpm.pv(field="x")[0] pv = pvx.replace("Pos:X-I", "Trig:TrigSrc-SP") # 0 - internal, 1 - external caput(pv, 1, wait=True) pv = pvx.replace("Pos:X-I", "DDR:WfmSel-SP") for fld in waveforms: pv = pvx.replace("Pos:X-I", "ddr%sWfEnable" % fld) caput(pv, 1, wait=True) time.sleep(2)
def resetSrBpms(wfmsel=None, name="BPM", evcode=None, verbose=0, bpms=None, trigsrc=None): """ reset the BPMs to external trigger and Tbt waveform. Offset is 0 for all Adc, Tbt and Fa waveforms. The Wfm size is set to 1,000,000 for ADC, 100,000 for Tbt and 9,000 for Fa. Parameters ----------- wfmsel : int, None Waveform selection: Adc(0), Tbt(1), Fa(2). default None, keep old values. name : str, list of element object Element name, group name or list of objects, as in ``getElements`` bpms : list of element object overwrite `name` if presents. evcode : int Event code: - 15(LINAC), 32(1Hz, sync acquisition), 33(SR RF BPM trigger), 47(SR first turn), 66(Booster extraction), 35(pinger). trigsrc : int, None None - default, keep original values. 0 - internal, 1 - external """ elems = bpms if bpms else [e for e in getElements(name) if e.pv(field="x")] pvprefs = [ bpm.pv(field="x")[0].replace("Pos:XwUsrOff-Calc", "") for bpm in elems ] if verbose: print "resetting {0} BPMS: {1}".format(len(elems), elems) if trigsrc is not None: pvs = [pvx + "Trig:TrigSrc-SP" for pvx in pvprefs] caput(pvs, [trigsrc] * len(pvs), wait=True) if wfmsel is not None: # 0 - Adc, 1 - Tbt, 2 - Fa pvs = [pvx + "DDR:WfmSel-SP" for pvx in pvprefs] caput(pvs, [wfmsel] * len(pvs), wait=True) # enable all three waveforms #pvs = [ pvx + "ddrAdcWfEnable" for pvx in pvprefs] #caput(pvs, 1, wait=True) #pvs = [ pvx + "ddrTbtWfEnable" for pvx in pvprefs] #caput(pvs, 1, wait=True) #pvs = [ pvx + "ddrFaWfEnable" for pvx in pvprefs] #caput(pvs, 1, wait=True) # pvs = [pvx + "ddrAdcOffset" for pvx in pvprefs] caput(pvs, [0] * len(pvs), wait=True) pvs = [pvx + "ddrTbtOffset" for pvx in pvprefs] caput(pvs, [0] * len(pvs), wait=True) pvs = [pvx + "ddrFaOffset" for pvx in pvprefs] caput(pvs, [0] * len(pvs), wait=True) # pvs = [pvx + "Burst:AdcEnableLen-SP" for pvx in pvprefs] caput(pvs, [1000000] * len(pvs), wait=True) pvs = [pvx + "Burst:TbtEnableLen-SP" for pvx in pvprefs] caput(pvs, [100000] * len(pvs), wait=True) pvs = [pvx + "Burst:FaEnableLen-SP" for pvx in pvprefs] caput(pvs, [9000] * len(pvs), wait=True) # pvs = [pvx + "ERec:AdcEnableLen-SP" for pvx in pvprefs] #if verbose: print pvs caput(pvs, [100000] * len(pvs), wait=True) pvs = [pvx + "ERec:TbtEnableLen-SP" for pvx in pvprefs] #if verbose: print pvs caput(pvs, [100000] * len(pvs), wait=True) pvs = [pvx + "ERec:FaEnableLen-SP" for pvx in pvprefs] #if verbose: print pvs caput(pvs, [9000] * len(pvs), wait=True) # if evcode is not None: pvs = [pvx + "Trig:EventNo-SP" for pvx in pvprefs] caput(pvs, evcode, wait=True)
def getSrBpmData(**kwargs): """ NSLS-II SR BPM data acquisition. Parameters ----------- trig : int, optional Internal(0) or external(1) trigger. verbose : int waveform : str Waveform selection: ``"Tbt"``, ``"Fa"`` bpms : list A list of BPM object. name : str BPM name or pattern, overwritten by parameter *bpms* count : int Waveform length. default all (0). output : str, True, False output file name, or default name (True), or no output (False). h5group : str output HDF5 group Returns -------- name : list a list of BPM name x : array (nbpm, count) x orbit, shape (nbpm, waveform_length). y : array (nbpm, count) y orbit Isum : array (nbpm, count) Sum signal timestamp : list offset : list offset from the FPGA buffer. There will be warning if timestamp differs more than 1 second """ trig_src = kwargs.get("trig", 0) verbose = kwargs.get("verbose", 0) waveform = kwargs.pop("waveform", "Tbt") name = kwargs.pop("bpms", kwargs.pop("name", "BPM")) count = kwargs.get("count", 0) #timeout = kwargs.get("timeout", 6) output = kwargs.get("output", None) lat = machines.getLattice() if lat.name != "SR": raise RuntimeError("the current lattice is not 'BR': %s" % lat.name) t0 = datetime.now() #pv_dcct = "BR-BI{DCCT:1}I-Wf" #dcct1 = caget(pv_dcct, count=1000) elems = [e for e in getElements(name) if e.pv(field="x")] pvpref = [ bpm.pv(field="x")[0].replace("Pos:XwUsrOff-Calc", "") for bpm in elems ] names = [bpm.name for bpm in elems] if trig_src == 0 and waveform in ["Tbt", "Fa"]: # internal trig # ret = _srBpmTrigData(pvpref, waveform, **kwargs) # x, y, Is, ts, offset, xbbaofst, ybbaofst, extdata = ret x, y, Is, extdata = _srBpmTrigData(pvpref, waveform, **kwargs) else: if waveform == "Tbt": pv_x = [pv + "TBT-X" for pv in pvpref] pv_y = [pv + "TBT-Y" for pv in pvpref] pv_S = [pv + "TBT-S" for pv in pvpref] pv_offset = [pv + "ddrTbtOffset" for pv in pvpref] elif waveform == "Fa": pv_x = [pv + "FA-X" for pv in pvpref] pv_y = [pv + "FA-Y" for pv in pvpref] pv_S = [pv + "FA-S" for pv in pvpref] pv_offset = [pv + "ddrFaOffset" for pv in pvpref] pv_ts = [pv + "TS:DdrTrigDate-I" for pv in pvpref] pv_bbaxoff = [pv + "BbaXOff-SP" for pv in pvpref] pv_bbayoff = [pv + "BbaYOff-SP" for pv in pvpref] pv_evtcode = [pv + "Trig:EventNo-I" for pv in pvpref] x = caget(pv_x, count=count, throw=False) y = caget(pv_y, count=count, throw=False) Is = caget(pv_S, count=count, throw=False) # check srBpmTrigData, key must agrees extdata = { "ddr_timestamp": np.array(caget(pv_ts)), "ddr_offset": np.array(caget(pv_offset), 'i'), "bba_xoffset": np.array(caget(pv_bbaxoff)), "bba_yoffset": np.array(caget(pv_bbayoff)), "event_code": np.array(caget(pv_evtcode)) } # in case they have difference size d = [] for v in [x, y, Is]: nx = max([len(r) for r in v if not isinstance(r, ca_nothing)]) rec = np.zeros((len(v), nx), 'd') for i in range(len(v)): rec[i, :len(v[i])] = v[i] d.append(rec) x, y, Is = d # get dcct #dcct2 = caget(pv_dcct, count=1000) #t1 = datetime.now() data = (names, x, y, Is, extdata["ddr_timestamp"], extdata["ddr_offset"]) if not output: return data if output is True: # use the default file name output_dir = os.path.join(machines.getOutputDir(), t0.strftime("%Y_%m"), "bpm") if not os.path.exists(output_dir): os.makedirs(output_dir) fopt = "bpm_%s_%d_" % (waveform, trig_src) + \ t0.strftime("%Y_%m_%d_%H%M%S.hdf5") output = os.path.join(output_dir, fopt) t1 = datetime.now() # save the data _saveSrBpmData(output, waveform, names, x, y, Is, h5group=kwargs.get("h5group", "/"), ts=(t0, t1), pvpref=pvpref, **extdata) return data, output
def measDispersion( elem, dfmax=5e-7, alphac=3.6261976841792413e-04, gamma=5.870841487279844e3, num_points=5, full=False, verbose=0 ): """measure dispersion at BPMs Parameters ----------- elem : BPM name, list or pattern dfmax : float. frequency change (check the unit) alphac : float. momentum compaction factor. gamma : float. beam energy. num_points : int. points to fit line full : reserved. Returns -------- eta : numpy.array. (nelem, 3) with columns etax, etay and s Examples --------- >>> eta = measDispersion('p*c0[1-4]*') """ eta = alphac - 1.0 / gamma / gamma bpmobj = [b for b in getElements(elem) if b.family == "BPM"] bpmnames = [b.name for b in bpmobj] nbpm = len(bpmnames) _logger.info("measure dispersions at %d elements '%s'" % (len(bpmnames), str(elem))) f0 = getRfFrequency(handle="setpoint") dflst = np.linspace(-abs(dfmax), abs(dfmax), num_points) # incase RF does not allow large step change, ramp down first for df in np.linspace(0, abs(dfmax), num_points)[1:-1]: putRfFrequency(f0 - df) time.sleep(2.0 / num_points) # avoid a bug in virtac obt0 = getOrbit(bpmnames) cod = np.zeros((len(dflst), 2 * nbpm), "d") for i, df in enumerate(dflst): v0 = getOrbit() putRfFrequency(f0 + df) if verbose > 0: print(i, "df=", df, " f=", f0) waitStableOrbit(v0) # repeat the put/get in case simulator did not response latest results obt = getOrbit(bpmnames) # print i, obt[0,:2], obt0[0,:2], np.shape(obt), np.shape(obt0) cod[i, :nbpm] = obt[:, 0] - obt0[:, 0] cod[i, nbpm:] = obt[:, 1] - obt0[:, 1] # restore for df in np.linspace(0, abs(dfmax), num_points): putRfFrequency(f0 + abs(dfmax) - df) time.sleep(2.0 / num_points) # fitting p = np.polyfit(dflst, cod, deg=1) disp = -p[0, :] * f0 * eta s = np.array([e.sb for e in bpmobj], "d") ret = np.zeros((len(bpmobj), 3), "d") ret[:, 0] = disp[:nbpm] ret[:, 1] = disp[nbpm:] ret[:, 2] = s if verbose > 0: for i, bpm in enumerate(bpmobj): print(i, bpm.name, bpm.sb, ret[i, 0], ret[i, 1]) return ret
def getBrBpmData(**kwargs): """ timeout - 6sec sleep - 4sec output - True, use default file name, str - user specified filename returns name, x, y, Isum, timestamp, offset There will be warning if timestamp differs more than 1 second """ trig_src = kwargs.get("trig", 0) verbose = kwargs.get("verbose", 0) waveform = kwargs.pop("waveform", "Tbt") name = kwargs.pop("name", "BPM") #timeout = kwargs.get("timeout", 6) lat = machines.getLattice() if lat.name != "BR": raise RuntimeError("the current lattice is not 'BR': %s" % lat.name) t0 = datetime.now() pv_dcct = "BR-BI{DCCT:1}I-Wf" dcct1 = caget(pv_dcct, count=1000) pvpref = [bpm.pv(field="x")[0].replace("Pos:X-I", "") for bpm in getElements(name)] names = [bpm.name for bpm in getElements(name)] if trig_src == 0 and waveform in ["Tbt", "Fa"]: ret = _brBpmTrigData(pvpref, waveform, **kwargs) x, y, Is, ts, offset = ret else: if waveform == "Tbt": pv_x = [pv + "TBT-X" for pv in pvpref] pv_y = [pv + "TBT-Y" for pv in pvpref] pv_S = [pv + "TBT-S" for pv in pvpref] pv_offset = [pv + "ddrTbtOffset" for pv in pvpref] elif waveform == "Fa": pv_x = [pv + "FA-X" for pv in pvpref] pv_y = [pv + "FA-Y" for pv in pvpref] pv_S = [pv + "FA-S" for pv in pvpref] pv_offset = [pv + "ddrFaOffset" for pv in pvpref] pv_ts = [pv + "TS:DdrTrigDate-I" for pv in pvpref] x = np.array(caget(pv_x), 'd') y = np.array(caget(pv_y), 'd') Is = np.array(caget(pv_S), 'd') ts = caget(pv_ts) offset = caget(pv_offset) # get dcct dcct2 = caget(pv_dcct, count=1000) t1 = datetime.now() data = (names, x, y, Is, ts, offset) if kwargs.get("output", None): # default output dir and file output_file = kwargs["output"] if output_file is True: # use the default file name output_dir = os.path.join(machines.getOutputDir(), t0.strftime("%Y_%m"), "bpm") if not os.path.exists(output_dir): os.makedirs(output_dir) fopt = "bpm_%s_%d_" % (waveform, trig_src) + \ t0.strftime("%Y_%m_%d_%H%M%S.hdf5") output_file = os.path.join(output_dir, fopt) # save the data _saveBrBpmData(output_file, waveform, data, h5group=kwargs.get("h5group", "/"), dcct_data = (dcct1, dcct2), ts = (t0, t1), pvpref = pvpref) return data, output_file else: return data
def getBrBpmData(**kwargs): """ timeout - 6sec sleep - 4sec output - True, use default file name, str - user specified filename returns name, x, y, Isum, timestamp, offset There will be warning if timestamp differs more than 1 second """ trig_src = kwargs.get("trig", 0) verbose = kwargs.get("verbose", 0) waveform = kwargs.pop("waveform", "Tbt") name = kwargs.pop("name", "BPM") #timeout = kwargs.get("timeout", 6) lat = machines.getLattice() if lat.name != "BR": raise RuntimeError("the current lattice is not 'BR': %s" % lat.name) t0 = datetime.now() pv_dcct = "BR-BI{DCCT:1}I-Wf" dcct1 = caget(pv_dcct, count=1000) pvpref = [ bpm.pv(field="x")[0].replace("Pos:X-I", "") for bpm in getElements(name) ] names = [bpm.name for bpm in getElements(name)] if trig_src == 0 and waveform in ["Tbt", "Fa"]: ret = _brBpmTrigData(pvpref, waveform, **kwargs) x, y, Is, ts, offset = ret else: if waveform == "Tbt": pv_x = [pv + "TBT-X" for pv in pvpref] pv_y = [pv + "TBT-Y" for pv in pvpref] pv_S = [pv + "TBT-S" for pv in pvpref] pv_offset = [pv + "ddrTbtOffset" for pv in pvpref] elif waveform == "Fa": pv_x = [pv + "FA-X" for pv in pvpref] pv_y = [pv + "FA-Y" for pv in pvpref] pv_S = [pv + "FA-S" for pv in pvpref] pv_offset = [pv + "ddrFaOffset" for pv in pvpref] pv_ts = [pv + "TS:DdrTrigDate-I" for pv in pvpref] x = np.array(caget(pv_x), 'd') y = np.array(caget(pv_y), 'd') Is = np.array(caget(pv_S), 'd') ts = caget(pv_ts) offset = caget(pv_offset) # get dcct dcct2 = caget(pv_dcct, count=1000) t1 = datetime.now() data = (names, x, y, Is, ts, offset) if kwargs.get("output", None): # default output dir and file output_file = kwargs["output"] if output_file is True: # use the default file name output_dir = os.path.join(machines.getOutputDir(), t0.strftime("%Y_%m"), "bpm") if not os.path.exists(output_dir): os.makedirs(output_dir) fopt = "bpm_%s_%d_" % (waveform, trig_src) + \ t0.strftime("%Y_%m_%d_%H%M%S.hdf5") output_file = os.path.join(output_dir, fopt) # save the data _saveBrBpmData(output_file, waveform, data, h5group=kwargs.get("h5group", "/"), dcct_data=(dcct1, dcct2), ts=(t0, t1), pvpref=pvpref) return data, output_file else: return data
def getArchiverData(*argv, **kwargs): """ >>> getArchiverData("DCCT", "I") >>> getArchiverData(["SR:C03-BI{DCCT:1}AveI-I",]) >>> getArchiverData(["pv1", "pv2"], s="-1 h") >>> getArchiverData(["pv1", "pv2"], s="-2 h", e="-1 h") >>> getArchiverData(["pv1", "pv2"], s="2014-11-11 00:00:00", e="-1 h") see manual arget for "-s" and "-e" parameter. Returns a dictionary of (pv, data). The data is (n,2) array. 2 columns are t seconds and the data. If data is an empty list, the pv might not being archived. """ if len(argv) == 1 and isinstance(argv[0], (str, unicode)): pvs = argv elif len(argv) == 1 and isinstance(argv[0], (list, tuple)): pvs = argv[0] elif len(argv) == 2: pvs = reduce(lambda x, y: x + y, [ e.pv(field=argv[1], handle=kwargs.get("handle", "readback")) for e in getElements(argv[0]) ]) fh, fname = tempfile.mkstemp(prefix="aphla_arget_") for pv in pvs: os.write(fh, "%s\n" % pv) os.close(fh) t0 = float(datetime.now().strftime("%s.%f")) import subprocess tspan = ["--start", kwargs.get("start", "-24 h")] if kwargs.has_key("end"): tspan.extend(["--end", kwargs["end"]]) if kwargs.has_key("count"): tspan.extend(["--count", str(kwargs["count"])]) out = subprocess.check_output( ["arget", "--pv-list", fname, "-T", "posix"] + tspan + pvs) if kwargs.get("debug", 0): print(out) os.remove(fname) import re pv, dat = "", {} for s in out.split("\n"): if re.match(r"Found [0-9]+ points", s): continue rec = s.split() #if s.find("Disconnected") > 0: continue if not rec: continue # a single line PV name if rec[0] in pvs: pv = s.strip() dat.setdefault(pv, []) continue try: d0, v = rec[0], rec[1] #dat[pv].append((float(d0)-t0, float(v))) dat[pv].append((float(d0), float(v))) except: print("invalid format '{0}' for {1}".format(s, pv)) raise return dict([(k, np.array(v)) for k, v in dat.items()])
def measDispersion(elem, dfmax=5e-7, alphac=3.6261976841792413e-04, gamma=5.870841487279844e3, num_points=5, full=False, verbose=0): """measure dispersion at BPMs Parameters ----------- elem : BPM name, list or pattern dfmax : float. frequency change (check the unit) alphac : float. momentum compaction factor. gamma : float. beam energy. num_points : int. points to fit line full : reserved. Returns -------- eta : numpy.array. (nelem, 3) with columns etax, etay and s Examples --------- >>> eta = measDispersion('p*c0[1-4]*') """ eta = alphac - 1.0 / gamma / gamma bpmobj = [b for b in getElements(elem) if b.family == 'BPM'] bpmnames = [b.name for b in bpmobj] nbpm = len(bpmnames) _logger.info("measure dispersions at %d elements '%s'" % (len(bpmnames), str(elem))) f0 = getRfFrequency(handle="setpoint") dflst = np.linspace(-abs(dfmax), abs(dfmax), num_points) # incase RF does not allow large step change, ramp down first for df in np.linspace(0, abs(dfmax), num_points)[1:-1]: putRfFrequency(f0 - df) time.sleep(2.0 / num_points) # avoid a bug in virtac obt0 = getOrbit(bpmnames) cod = np.zeros((len(dflst), 2 * nbpm), 'd') for i, df in enumerate(dflst): v0 = getOrbit() putRfFrequency(f0 + df) if verbose > 0: print(i, "df=", df, " f=", f0) waitStableOrbit(v0) # repeat the put/get in case simulator did not response latest results obt = getOrbit(bpmnames) #print i, obt[0,:2], obt0[0,:2], np.shape(obt), np.shape(obt0) cod[i, :nbpm] = obt[:, 0] - obt0[:, 0] cod[i, nbpm:] = obt[:, 1] - obt0[:, 1] # restore for df in np.linspace(0, abs(dfmax), num_points): putRfFrequency(f0 + abs(dfmax) - df) time.sleep(2.0 / num_points) # fitting p = np.polyfit(dflst, cod, deg=1) disp = -p[0, :] * f0 * eta s = np.array([e.sb for e in bpmobj], 'd') ret = np.zeros((len(bpmobj), 3), 'd') ret[:, 0] = disp[:nbpm] ret[:, 1] = disp[nbpm:] ret[:, 2] = s if verbose > 0: for i, bpm in enumerate(bpmobj): print(i, bpm.name, bpm.sb, ret[i, 0], ret[i, 1]) return ret
def getSrBpmData(**kwargs): """ NSLS-II SR BPM data acquisition. Parameters ----------- trig : int, optional Internal(0) or external(1) trigger. verbose : int waveform : str Waveform selection: ``"Tbt"``, ``"Fa"`` bpms : list A list of BPM object. name : str BPM name or pattern, overwritten by parameter *bpms* count : int Waveform length. default all (0). output : str, True, False output file name, or default name (True), or no output (False). h5group : str output HDF5 group Returns -------- name : list a list of BPM name x : array (nbpm, count) x orbit, shape (nbpm, waveform_length). y : array (nbpm, count) y orbit Isum : array (nbpm, count) Sum signal timestamp : list offset : list offset from the FPGA buffer. There will be warning if timestamp differs more than 1 second """ trig_src = kwargs.get("trig", 0) verbose = kwargs.get("verbose", 0) waveform = kwargs.pop("waveform", "Tbt") name = kwargs.pop("bpms", kwargs.pop("name", "BPM")) count = kwargs.get("count", 0) #timeout = kwargs.get("timeout", 6) output = kwargs.get("output", None) lat = machines.getLattice() if lat.name != "SR": raise RuntimeError("the current lattice is not 'BR': %s" % lat.name) t0 = datetime.now() #pv_dcct = "BR-BI{DCCT:1}I-Wf" #dcct1 = caget(pv_dcct, count=1000) elems = [e for e in getElements(name) if e.pv(field="x")] pvpref = [bpm.pv(field="x")[0].replace("Pos:XwUsrOff-Calc", "") for bpm in elems] names = [bpm.name for bpm in elems] if trig_src == 0 and waveform in ["Tbt", "Fa"]: # internal trig # ret = _srBpmTrigData(pvpref, waveform, **kwargs) # x, y, Is, ts, offset, xbbaofst, ybbaofst, extdata = ret x, y, Is, extdata = _srBpmTrigData(pvpref, waveform, **kwargs) else: if waveform == "Tbt": pv_x = [pv + "TBT-X" for pv in pvpref] pv_y = [pv + "TBT-Y" for pv in pvpref] pv_S = [pv + "TBT-S" for pv in pvpref] pv_offset = [pv + "ddrTbtOffset" for pv in pvpref] elif waveform == "Fa": pv_x = [pv + "FA-X" for pv in pvpref] pv_y = [pv + "FA-Y" for pv in pvpref] pv_S = [pv + "FA-S" for pv in pvpref] pv_offset = [pv + "ddrFaOffset" for pv in pvpref] pv_ts = [pv + "TS:DdrTrigDate-I" for pv in pvpref] pv_bbaxoff = [ pv + "BbaXOff-SP" for pv in pvpref] pv_bbayoff = [ pv + "BbaYOff-SP" for pv in pvpref] pv_evtcode = [ pv + "Trig:EventNo-I" for pv in pvpref] x = caget(pv_x, count=count, throw=False) y = caget(pv_y, count=count, throw=False) Is = caget(pv_S, count=count, throw=False) # check srBpmTrigData, key must agrees extdata = { "ddr_timestamp": np.array(caget(pv_ts)), "ddr_offset": np.array(caget(pv_offset), 'i'), "bba_xoffset": np.array(caget(pv_bbaxoff)), "bba_yoffset": np.array(caget(pv_bbayoff)), "event_code": np.array(caget(pv_evtcode))} # in case they have difference size d = [] for v in [x, y, Is]: nx = max([len(r) for r in v if not isinstance(r, ca_nothing)]) rec = np.zeros((len(v), nx), 'd') for i in range(len(v)): rec[i,:len(v[i])] = v[i] d.append(rec) x, y, Is = d # get dcct #dcct2 = caget(pv_dcct, count=1000) #t1 = datetime.now() data = (names, x, y, Is, extdata["ddr_timestamp"], extdata["ddr_offset"]) if not output: return data if output is True: # use the default file name output_dir = os.path.join(machines.getOutputDir(), t0.strftime("%Y_%m"), "bpm") if not os.path.exists(output_dir): os.makedirs(output_dir) fopt = "bpm_%s_%d_" % (waveform, trig_src) + \ t0.strftime("%Y_%m_%d_%H%M%S.hdf5") output = os.path.join(output_dir, fopt) t1 = datetime.now() # save the data _saveSrBpmData(output, waveform, names, x, y, Is, h5group=kwargs.get("h5group", "/"), ts = (t0, t1), pvpref = pvpref, **extdata) return data, output
def resetSrBpms(wfmsel = None, name = "BPM", evcode = None, verbose=0, bpms=None, trigsrc = None): """ reset the BPMs to external trigger and Tbt waveform. Offset is 0 for all Adc, Tbt and Fa waveforms. The Wfm size is set to 1,000,000 for ADC, 100,000 for Tbt and 9,000 for Fa. Parameters ----------- wfmsel : int, None Waveform selection: Adc(0), Tbt(1), Fa(2). default None, keep old values. name : str, list of element object Element name, group name or list of objects, as in ``getElements`` bpms : list of element object overwrite `name` if presents. evcode : int Event code: - 15(LINAC), 32(1Hz, sync acquisition), 33(SR RF BPM trigger), 47(SR first turn), 66(Booster extraction), 35(pinger). trigsrc : int, None None - default, keep original values. 0 - internal, 1 - external """ elems = bpms if bpms else [e for e in getElements(name) if e.pv(field="x")] pvprefs = [bpm.pv(field="x")[0].replace("Pos:XwUsrOff-Calc", "") for bpm in elems] if verbose: print "resetting {0} BPMS: {1}".format(len(elems), elems) if trigsrc is not None: pvs = [ pvx + "Trig:TrigSrc-SP" for pvx in pvprefs ] caput(pvs, [trigsrc] * len(pvs), wait=True) if wfmsel is not None: # 0 - Adc, 1 - Tbt, 2 - Fa pvs = [ pvx + "DDR:WfmSel-SP" for pvx in pvprefs] caput(pvs, [wfmsel] * len(pvs), wait=True) # enable all three waveforms #pvs = [ pvx + "ddrAdcWfEnable" for pvx in pvprefs] #caput(pvs, 1, wait=True) #pvs = [ pvx + "ddrTbtWfEnable" for pvx in pvprefs] #caput(pvs, 1, wait=True) #pvs = [ pvx + "ddrFaWfEnable" for pvx in pvprefs] #caput(pvs, 1, wait=True) # pvs = [ pvx + "ddrAdcOffset" for pvx in pvprefs] caput(pvs, [0] * len(pvs), wait=True) pvs = [ pvx + "ddrTbtOffset" for pvx in pvprefs] caput(pvs, [0] * len(pvs), wait=True) pvs = [ pvx + "ddrFaOffset" for pvx in pvprefs] caput(pvs, [0] * len(pvs), wait=True) # pvs = [ pvx + "Burst:AdcEnableLen-SP" for pvx in pvprefs] caput(pvs, [1000000] * len(pvs), wait=True) pvs = [ pvx + "Burst:TbtEnableLen-SP" for pvx in pvprefs] caput(pvs, [100000] * len(pvs), wait=True) pvs = [ pvx + "Burst:FaEnableLen-SP" for pvx in pvprefs] caput(pvs, [9000] * len(pvs), wait=True) # pvs = [ pvx + "ERec:AdcEnableLen-SP" for pvx in pvprefs] #if verbose: print pvs caput(pvs, [100000] * len(pvs), wait=True) pvs = [ pvx + "ERec:TbtEnableLen-SP" for pvx in pvprefs] #if verbose: print pvs caput(pvs, [100000] * len(pvs), wait=True) pvs = [ pvx + "ERec:FaEnableLen-SP" for pvx in pvprefs] #if verbose: print pvs caput(pvs, [9000] * len(pvs), wait=True) # if evcode is not None: pvs = [ pvx + "Trig:EventNo-SP" for pvx in pvprefs] caput(pvs, evcode, wait=True)