Ejemplo n.º 1
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)
Ejemplo n.º 2
0
def measKickedTbtData(idriver, ampl, **kwargs):
    """
    take turn-by-turn BPM data after kicking the beam.

    Parameters
    -----------
    idriver : int
        which driver used to kick the beam: injection kicker 3(3) or 4(4),
        vertical pinger(5), horizontal pinger(6), both H/V pingers(7).
    ampl : float, tuple
        kicking amplitude.
    bpms : list of element objects.
        provide the BPMs to take data from, default ["BPM" or "UBPM"]
    count : int
        number of turns.
    output : str, True, False
        output file name, or default (True), or no output (False)
    verbose : int

    it will set kicker/pinger and wait 100sec or readback-setpoint agree.

    event code 47 will be used for kicker 3 and 4, 35 used for pingers.

    Same returns as `getSrBpmData`

    Examples
    ---------
    >>> (name, x, y, Isum, ts, offset) = measKickedTbtData(7, (0.15, 0.2))
    >>> (name, x, y, Isum, ts, offset), output = measKickedTbtData(7, (0.15, 0.2), output=True)
    """

    verbose = kwargs.get("verbose", 0)
    output = kwargs.get("output", True)
    sleep = kwargs.get("sleep", 5)
    count = kwargs.get("count", 2000)
    bpms  = [ b for b in kwargs.get("bpms",
                                   getGroupMembers(["BPM", "UBPM"], op="union"))
              if b.isEnabled()]

    bpmstats = getBpmStatus(bpms)

    kpvsp, kpvrb = None, None
    # 0 - both off, 1 - V-on, 2-H-on, 3-both-on
    pv_pinger_mode = "SR:C21-PS{Pinger}Mode:Trig-Sel"
    if idriver in [3,4,5,6]:
        if idriver in [3, 4]:
            kpvsp = 'SR:IS-PS{Kick:%d}V-Sp' % idriver
            kpvrb = 'SR:IS-PS{Kick:%d}Hvps-V-Rb-1st' % idriver
            kpvon = 'SR:IS-PS{Kick:%d}HvpsOnOff_Cmd' % idriver
        elif idriver in [5,]:
            # vertical pinger
            kpvsp = 'SR:C21-PS{Pinger:V}V-Sp'
            kpvrb = 'SR:C21-PS{Pinger:V}Setpoint-Rb.VALA'
            kpvon = 'SR:C21-PS{Pinger:V}HvpsOnOff_Cmd'
            caput(pv_pinger_mode, 1)
        elif idriver in [6,]:
            # horizontal pinger
            kpvsp = 'SR:C21-PS{Pinger:H}V-Sp'
            kpvrb = 'SR:C21-PS{Pinger:H}Setpoint-Rb.VALA'
            kpvon = 'SR:C21-PS{Pinger:H}HvpsOnOff_Cmd'
            caput(pv_pinger_mode, 2)
        #
        caput(kpvsp, 0.0)
        for i in range(100):
            if caget(kpvrb, count=1) < 0.001: break
            time.sleep(1)
        caput(kpvon, 1)
    elif idriver in [7,]:
        # both pinger
        kpvsp = ['SR:C21-PS{Pinger:H}V-Sp', 'SR:C21-PS{Pinger:V}V-Sp']
        kpvrb = ['SR:C21-PS{Pinger:H}Setpoint-Rb.VALA', 'SR:C21-PS{Pinger:V}Setpoint-Rb.VALA']
        kpvon = ['SR:C21-PS{Pinger:H}HvpsOnOff_Cmd', 'SR:C21-PS{Pinger:V}HvpsOnOff_Cmd']
        caput(pv_pinger_mode, 3)
        caput(kpvsp, [0.0, 0.0])
        for i in range(100):
            rb = caget(kpvrb, count=1)
            if rb[0] < 0.001 and rb[1] < 0.001: break
            time.sleep(0.5)
        caput(kpvon, [1, 1])

    # set the kicker/pinger voltage
    caput(kpvsp, ampl, wait=True)
    #(name, x, y, Isum, ts, offset), output = ap.nsls2.getSrBpmData(
    #    trig=1, count=5000, output=True, h5group="k_%d" % idriver)
    h5g = "k_%d" % idriver
    Idcct0 = caget('SR:C03-BI{DCCT:1}I:Total-I')
    time.sleep(sleep)

    # request an injection:
    if idriver in [3,4,]:
        resetSrBpm(bpms=bpms, evcode=47)
        time.sleep(1)
        caput('ACC-TS{EVG-SSC}Request-Sel', 1)
    elif idriver in [5,6,7]:
        resetSrBpms(bpms=bpms, evcode=35)
        # do it twice
        caput('SR:C21-PS{Pinger}Ping-Cmd', 1)
        time.sleep(1)
        caput('SR:C21-PS{Pinger}Ping-Cmd', 1)
    time.sleep(2)
    Idcct1 = caget('SR:C03-BI{DCCT:1}I:Total-I')
    bpmdata = getSrBpmData(trig=1, bpms=bpms, count=count,
                           output=output, h5group=h5g)
    # record pinger wave, V-chan1, H-chan2
    pinger_delay, pinger_wave, pinger_mode = None, None, None
    if idriver in [5,6,7]:
        pinger_wave = caget(["SR:C21-PS{Dig:Png1}TimeScale-I",
                             "SR:C21-PS{Dig:Png1}Data:Chan2-I",
                             "SR:C21-PS{Dig:Png1}Data:Chan1-I"])
        pinger_delay = caget(["SR:C21-PS{Pinger:H}Delay-SP",
                              "SR:C21-PS{Pinger:V}Delay-SP"])
        pinger_mode = caget("SR:C21-PS{Pinger}Mode:Trig-Sts")
        
    # repeat_value=True
    caput(kpvon, 0)
    caput(kpvsp, 0.0)
    
    if output:
        (name, x, y, Isum, ts, offset), output = bpmdata
        
        f = h5py.File(output)
        g = f[h5g]
        g["I"]  = Idcct1
        g["I"].attrs["dI"] = Idcct1 - Idcct0
        g["RF_SP"] = float(caget('RF{Osc:1}Freq:SP'))
        g["RF_I"]  = float(caget('RF{Osc:1}Freq:I'))
        g.attrs["ampl"]  = ampl
        g.attrs["idriver"] = idriver
        g.attrs["pvsp"] = kpvsp
        g.attrs["pvrb"] = kpvrb
        g.attrs["pvon"] = kpvon
        if pinger_wave is not None:
            g["pinger_wave"] = np.array(pinger_wave, 'd').transpose()
        if pinger_delay is not None:
            g["pinger_delay"] = pinger_delay
        if pinger_mode is not None:
            g["pinger_mode"] = pinger_mode
        f.close()

    # restore
    restoreBpmStatus(bpmstats)

    return bpmdata
Ejemplo n.º 3
0
def measKickedTbtData(idriver, ampl, **kwargs):
    """
    take turn-by-turn BPM data after kicking the beam.

    Parameters
    -----------
    idriver : int
        which driver used to kick the beam: injection kicker 3(3) or 4(4),
        vertical pinger(5), horizontal pinger(6), both H/V pingers(7).
    ampl : float, tuple
        kicking amplitude.
    bpms : list of element objects.
        provide the BPMs to take data from, default ["BPM" or "UBPM"]
    count : int
        number of turns.
    output : str, True, False
        output file name, or default (True), or no output (False)
    verbose : int

    it will set kicker/pinger and wait 100sec or readback-setpoint agree.

    event code 47 will be used for kicker 3 and 4, 35 used for pingers.

    Same returns as `getSrBpmData`

    Examples
    ---------
    >>> (name, x, y, Isum, ts, offset) = measKickedTbtData(7, (0.15, 0.2))
    >>> (name, x, y, Isum, ts, offset), output = measKickedTbtData(7, (0.15, 0.2), output=True)
    """

    verbose = kwargs.get("verbose", 0)
    output = kwargs.get("output", True)
    sleep = kwargs.get("sleep", 5)
    count = kwargs.get("count", 2000)
    bpms = [
        b for b in kwargs.get("bpms",
                              getGroupMembers(["BPM", "UBPM"], op="union"))
        if b.isEnabled()
    ]

    bpmstats = getBpmStatus(bpms)

    kpvsp, kpvrb = None, None
    # 0 - both off, 1 - V-on, 2-H-on, 3-both-on
    pv_pinger_mode = "SR:C21-PS{Pinger}Mode:Trig-Sel"
    if idriver in [3, 4, 5, 6]:
        if idriver in [3, 4]:
            kpvsp = 'SR:IS-PS{Kick:%d}V-Sp' % idriver
            kpvrb = 'SR:IS-PS{Kick:%d}Hvps-V-Rb-1st' % idriver
            kpvon = 'SR:IS-PS{Kick:%d}HvpsOnOff_Cmd' % idriver
        elif idriver in [
                5,
        ]:
            # vertical pinger
            kpvsp = 'SR:C21-PS{Pinger:V}V-Sp'
            kpvrb = 'SR:C21-PS{Pinger:V}Setpoint-Rb.VALA'
            kpvon = 'SR:C21-PS{Pinger:V}HvpsOnOff_Cmd'
            caput(pv_pinger_mode, 1)
        elif idriver in [
                6,
        ]:
            # horizontal pinger
            kpvsp = 'SR:C21-PS{Pinger:H}V-Sp'
            kpvrb = 'SR:C21-PS{Pinger:H}Setpoint-Rb.VALA'
            kpvon = 'SR:C21-PS{Pinger:H}HvpsOnOff_Cmd'
            caput(pv_pinger_mode, 2)
        #
        caput(kpvsp, 0.0)
        for i in range(100):
            if caget(kpvrb, count=1) < 0.001: break
            time.sleep(1)
        caput(kpvon, 1)
    elif idriver in [
            7,
    ]:
        # both pinger
        kpvsp = ['SR:C21-PS{Pinger:H}V-Sp', 'SR:C21-PS{Pinger:V}V-Sp']
        kpvrb = [
            'SR:C21-PS{Pinger:H}Setpoint-Rb.VALA',
            'SR:C21-PS{Pinger:V}Setpoint-Rb.VALA'
        ]
        kpvon = [
            'SR:C21-PS{Pinger:H}HvpsOnOff_Cmd',
            'SR:C21-PS{Pinger:V}HvpsOnOff_Cmd'
        ]
        caput(pv_pinger_mode, 3)
        caput(kpvsp, [0.0, 0.0])
        for i in range(100):
            rb = caget(kpvrb, count=1)
            if rb[0] < 0.001 and rb[1] < 0.001: break
            time.sleep(0.5)
        caput(kpvon, [1, 1])

    # set the kicker/pinger voltage
    caput(kpvsp, ampl, wait=True)
    #(name, x, y, Isum, ts, offset), output = ap.nsls2.getSrBpmData(
    #    trig=1, count=5000, output=True, h5group="k_%d" % idriver)
    h5g = "k_%d" % idriver
    Idcct0 = caget('SR:C03-BI{DCCT:1}I:Total-I')
    time.sleep(sleep)

    # request an injection:
    if idriver in [
            3,
            4,
    ]:
        resetSrBpm(bpms=bpms, evcode=47)
        time.sleep(1)
        caput('ACC-TS{EVG-SSC}Request-Sel', 1)
    elif idriver in [5, 6, 7]:
        resetSrBpms(bpms=bpms, evcode=35)
        # do it twice
        caput('SR:C21-PS{Pinger}Ping-Cmd', 1)
        time.sleep(1)
        caput('SR:C21-PS{Pinger}Ping-Cmd', 1)
    time.sleep(2)
    Idcct1 = caget('SR:C03-BI{DCCT:1}I:Total-I')
    bpmdata = getSrBpmData(trig=1,
                           bpms=bpms,
                           count=count,
                           output=output,
                           h5group=h5g)
    # record pinger wave, V-chan1, H-chan2
    pinger_delay, pinger_wave, pinger_mode = None, None, None
    if idriver in [5, 6, 7]:
        pinger_wave = caget([
            "SR:C21-PS{Dig:Png1}TimeScale-I",
            "SR:C21-PS{Dig:Png1}Data:Chan2-I",
            "SR:C21-PS{Dig:Png1}Data:Chan1-I"
        ])
        pinger_delay = caget(
            ["SR:C21-PS{Pinger:H}Delay-SP", "SR:C21-PS{Pinger:V}Delay-SP"])
        pinger_mode = caget("SR:C21-PS{Pinger}Mode:Trig-Sts")

    # repeat_value=True
    caput(kpvon, 0)
    caput(kpvsp, 0.0)

    if output:
        (name, x, y, Isum, ts, offset), output = bpmdata

        f = h5py.File(output)
        g = f[h5g]
        g["I"] = Idcct1
        g["I"].attrs["dI"] = Idcct1 - Idcct0
        g["RF_SP"] = float(caget('RF{Osc:1}Freq:SP'))
        g["RF_I"] = float(caget('RF{Osc:1}Freq:I'))
        g.attrs["ampl"] = ampl
        g.attrs["idriver"] = idriver
        g.attrs["pvsp"] = kpvsp
        g.attrs["pvrb"] = kpvrb
        g.attrs["pvon"] = kpvon
        if pinger_wave is not None:
            g["pinger_wave"] = np.array(pinger_wave, 'd').transpose()
        if pinger_delay is not None:
            g["pinger_delay"] = pinger_delay
        if pinger_mode is not None:
            g["pinger_mode"] = pinger_mode
        f.close()

    # restore
    restoreBpmStatus(bpmstats)

    return bpmdata