Пример #1
0
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
Пример #2
0
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
Пример #3
0
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)
Пример #4
0
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)
Пример #5
0
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)
Пример #6
0
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)
Пример #7
0
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
Пример #8
0
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
Пример #9
0
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
Пример #10
0
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])
Пример #11
0
    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
Пример #12
0
    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
Пример #13
0
    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
Пример #14
0
    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
Пример #15
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
Пример #16
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)
Пример #17
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
Пример #18
0
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)
Пример #19
0
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)
Пример #20
0
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)
Пример #21
0
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
Пример #22
0
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
Пример #23
0
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
Пример #24
0
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
Пример #25
0
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()])
Пример #26
0
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
Пример #27
0
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
Пример #28
0
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)