예제 #1
0
 def matlabPV_FB(feedbackvalue):  #get and put timedelay signal
     matPV = EpicsSignal('LAS:FS4:VIT:matlab:04')
     org_matPV = matPV.get()  #the matlab PV value before FB
     fbvalns = feedbackvalue * 1e+9  #feedback value in ns
     fbinput = org_matPV + fbvalns  #relative to absolute value
     matPV.put(fbinput)
     return
예제 #2
0
def test_epicssignal_get_in_callback(fake_motor_ioc, cleanup):
    pvs = fake_motor_ioc.pvs
    sig = EpicsSignal(write_pv=pvs['setpoint'],
                      read_pv=pvs['readback'],
                      name='motor')
    cleanup.add(sig)

    called = []

    def generic_sub(sub_type, **kwargs):
        called.append((sub_type, sig.get(), sig.get_setpoint()))

    for event_type in (sig.SUB_VALUE, sig.SUB_META, sig.SUB_SETPOINT,
                       sig.SUB_SETPOINT_META):
        sig.subscribe(generic_sub, event_type=event_type)

    sig.wait_for_connection()

    sig.put(1, wait=True)
    sig.put(2, wait=True)
    time.sleep(0.5)

    print(called)
    # Arbitrary threshold, but if @klauer screwed something up again, this will
    # blow up
    assert len(called) < 20
    print('total', len(called))
    sig.unsubscribe_all()
예제 #3
0
def test_epicssignal_get_in_callback(cleanup, fake_motor_ioc):
    pvs = fake_motor_ioc.pvs
    sig = EpicsSignal(write_pv=pvs['setpoint'], read_pv=pvs['readback'],
                      name='motor')
    cleanup.add(sig)

    called = []

    def generic_sub(sub_type, **kwargs):
        called.append((sub_type, sig.get(), sig.get_setpoint()))

    for event_type in (sig.SUB_VALUE, sig.SUB_META,
                       sig.SUB_SETPOINT, sig.SUB_SETPOINT_META):
        sig.subscribe(generic_sub, event_type=event_type)

    sig.wait_for_connection()

    sig.put(1, wait=True)
    sig.put(2, wait=True)
    time.sleep(0.5)

    print(called)
    # Arbitrary threshold, but if @klauer screwed something up again, this will
    # blow up
    assert len(called) < 20
    print('total', len(called))
예제 #4
0
def test_epicssignal_sub_setpoint(cleanup, fake_motor_ioc):
    pvs = fake_motor_ioc.pvs
    pv = EpicsSignal(write_pv=pvs['setpoint'],
                     read_pv=pvs['readback'],
                     name='pv')
    cleanup.add(pv)

    setpoint_called = []
    setpoint_meta_called = []

    def sub_setpoint(old_value, value, **kwargs):
        setpoint_called.append((old_value, value))

    def sub_setpoint_meta(timestamp, **kwargs):
        setpoint_meta_called.append(timestamp)

    pv.subscribe(sub_setpoint, event_type=pv.SUB_SETPOINT)
    pv.subscribe(sub_setpoint_meta, event_type=pv.SUB_SETPOINT_META)

    pv.wait_for_connection()

    pv.put(1, wait=True)
    pv.put(2, wait=True)
    time.sleep(1.0)

    assert len(setpoint_called) >= 3
    assert len(setpoint_meta_called) >= 3
예제 #5
0
class Watchman:
    cbid = None
    retries = 3

    def __init__(self, door_state, voltage_read, voltage_write):
        self.door_state = EpicsSignalRO(door_state)
        self.mesh_voltage = EpicsSignal(voltage_read, write_pv=voltage_write)
        print('Using door pv {}'.format(door_state))

    def start(self):
        """Sets up self.callback to be run when door state changes"""
        # Make sure we don't start 2 processes
        self.stop()
        print('Starting door watcher')
        self.door_state.subscribe(self.callback)

    def callback(self, old_value=None, value=None, **kwargs):
        """To be run every time the door state changes"""
        print('Door PV changed from {} to {}'.format(old_value, value))
        if old_value == 1 and value == 0:
            print('Zeroing the mesh voltage because door was opened')
            # Let's retry a few times in case of a network error
            for i in range(self.retries):
                try:
                    self.mesh_voltage.put(0)
                except Exception:
                    pass

    def stop(self):
        """Shutdown the watcher"""
        if self.cbid is not None:
            print('Stopping door watcher')
            self.door_state.unsubscribe(self.cbid)
            self.cbid = None
예제 #6
0
def test_epicssignal_sub_setpoint(cleanup, fake_motor_ioc):
    pvs = fake_motor_ioc.pvs
    pv = EpicsSignal(write_pv=pvs['setpoint'], read_pv=pvs['readback'],
                     name='pv')
    cleanup.add(pv)

    setpoint_called = []
    setpoint_meta_called = []

    def sub_setpoint(old_value, value, **kwargs):
        setpoint_called.append((old_value, value))

    def sub_setpoint_meta(timestamp, **kwargs):
        setpoint_meta_called.append(timestamp)

    pv.subscribe(sub_setpoint, event_type=pv.SUB_SETPOINT)
    pv.subscribe(sub_setpoint_meta, event_type=pv.SUB_SETPOINT_META)

    pv.wait_for_connection()

    pv.put(1, wait=True)
    pv.put(2, wait=True)
    time.sleep(0.5)

    assert len(setpoint_called) >= 3
    assert len(setpoint_meta_called) >= 3
예제 #7
0
def test_describe():
    sig = EpicsSignal('my_pv')
    sig._write_pv.enum_strs = ('enum1', 'enum2')
    sig.wait_for_connection()

    sig.put(1)
    desc = sig.describe()['my_pv']
    assert desc['dtype'] == 'integer'
    assert desc['shape'] == []
    assert 'precision' in desc
    assert 'enum_strs' in desc
    assert 'upper_ctrl_limit' in desc
    assert 'lower_ctrl_limit' in desc

    sig.put('foo')
    desc = sig.describe()['my_pv']
    assert desc['dtype'] == 'string'
    assert desc['shape'] == []

    sig.put(3.14)
    desc = sig.describe()['my_pv']
    assert desc['dtype'] == 'number'
    assert desc['shape'] == []

    import numpy as np
    sig.put(np.array([1,]))
    desc = sig.describe()['my_pv']
    assert desc['dtype'] == 'array'
    assert desc['shape'] == [1,]
예제 #8
0
def test_describe():
    sig = EpicsSignal('my_pv')
    sig._write_pv.enum_strs = ('enum1', 'enum2')
    sig.wait_for_connection()

    sig.put(1)
    desc = sig.describe()['my_pv']
    assert desc['dtype'] == 'integer'
    assert desc['shape'] == []
    assert 'precision' in desc
    assert 'enum_strs' in desc
    assert 'upper_ctrl_limit' in desc
    assert 'lower_ctrl_limit' in desc

    sig.put('foo')
    desc = sig.describe()['my_pv']
    assert desc['dtype'] == 'string'
    assert desc['shape'] == []

    sig.put(3.14)
    desc = sig.describe()['my_pv']
    assert desc['dtype'] == 'number'
    assert desc['shape'] == []

    import numpy as np
    sig.put(np.array([1,]))
    desc = sig.describe()['my_pv']
    assert desc['dtype'] == 'array'
    assert desc['shape'] == [1,]
예제 #9
0
파일: test_signal.py 프로젝트: klauer/ophyd
    def test_describe(self):
        epics.PV = FakeEpicsPV
        sig = EpicsSignal('my_pv')
        sig._write_pv.enum_strs = ('enum1', 'enum2')
        sig.wait_for_connection()

        sig.put(1)
        desc = sig.describe()['my_pv']
        self.assertEquals(desc['dtype'], 'integer')
        self.assertEquals(desc['shape'], [])
        self.assertIn('precision', desc)
        self.assertIn('enum_strs', desc)
        self.assertIn('upper_ctrl_limit', desc)
        self.assertIn('lower_ctrl_limit', desc)

        sig.put('foo')
        desc = sig.describe()['my_pv']
        self.assertEquals(desc['dtype'], 'string')
        self.assertEquals(desc['shape'], [])

        sig.put(3.14)
        desc = sig.describe()['my_pv']
        self.assertEquals(desc['dtype'], 'number')
        self.assertEquals(desc['shape'], [])

        import numpy as np
        sig.put(np.array([
            1,
        ]))
        desc = sig.describe()['my_pv']
        self.assertEquals(desc['dtype'], 'array')
        self.assertEquals(desc['shape'], [
            1,
        ])
예제 #10
0
def test_describe(cleanup, signal_test_ioc):
    sig = EpicsSignal(signal_test_ioc.pvs['bool_enum'], name='my_pv')
    cleanup.add(sig)
    sig.wait_for_connection()

    sig.put(1)
    desc = sig.describe()['my_pv']
    assert desc['dtype'] == 'integer'
    assert desc['shape'] == []
    # assert 'precision' in desc
    assert desc['enum_strs'] == ['Off', 'On']
    assert 'upper_ctrl_limit' in desc
    assert 'lower_ctrl_limit' in desc

    sig = Signal(name='my_pv')
    sig.put('Off')
    desc = sig.describe()['my_pv']
    assert desc['dtype'] == 'string'
    assert desc['shape'] == []

    sig.put(3.14)
    desc = sig.describe()['my_pv']
    assert desc['dtype'] == 'number'
    assert desc['shape'] == []

    import numpy as np
    sig.put(np.array([
        1,
    ]))
    desc = sig.describe()['my_pv']
    assert desc['dtype'] == 'array'
    assert desc['shape'] == [
        1,
    ]
예제 #11
0
    def test_describe(self):
        epics.PV = FakeEpicsPV
        sig = EpicsSignal('my_pv')
        sig._write_pv.enum_strs = ('enum1', 'enum2')
        sig.wait_for_connection()

        sig.put(1)
        desc = sig.describe()['my_pv']
        self.assertEquals(desc['dtype'], 'integer')
        self.assertEquals(desc['shape'], [])
        self.assertIn('precision', desc)
        self.assertIn('enum_strs', desc)
        self.assertIn('upper_ctrl_limit', desc)
        self.assertIn('lower_ctrl_limit', desc)

        sig.put('foo')
        desc = sig.describe()['my_pv']
        self.assertEquals(desc['dtype'], 'string')
        self.assertEquals(desc['shape'], [])

        sig.put(3.14)
        desc = sig.describe()['my_pv']
        self.assertEquals(desc['dtype'], 'number')
        self.assertEquals(desc['shape'], [])

        import numpy as np
        sig.put(np.array([1,]))
        desc = sig.describe()['my_pv']
        self.assertEquals(desc['dtype'], 'array')
        self.assertEquals(desc['shape'], [1,])
예제 #12
0
def test_no_connection(cleanup, signal_test_ioc):
    sig = EpicsSignal('does_not_connect')
    cleanup.add(sig)

    with pytest.raises(TimeoutError):
        sig.wait_for_connection()

    sig = EpicsSignal('does_not_connect')
    cleanup.add(sig)

    with pytest.raises(TimeoutError):
        sig.put(0.0)

    with pytest.raises(TimeoutError):
        sig.get()

    sig = EpicsSignal(signal_test_ioc.pvs['read_only'], write_pv='does_not_connect')
    cleanup.add(sig)
    with pytest.raises(TimeoutError):
        sig.wait_for_connection()
예제 #13
0
def test_no_connection(cleanup, signal_test_ioc):
    sig = EpicsSignal('does_not_connect')
    cleanup.add(sig)

    with pytest.raises(TimeoutError):
        sig.wait_for_connection()

    sig = EpicsSignal('does_not_connect')
    cleanup.add(sig)

    with pytest.raises(TimeoutError):
        sig.put(0.0)

    with pytest.raises(TimeoutError):
        sig.get()

    sig = EpicsSignal(signal_test_ioc.pvs['read_only'], write_pv='does_not_connect')
    cleanup.add(sig)
    with pytest.raises(TimeoutError):
        sig.wait_for_connection()
예제 #14
0
파일: lv8018.py 프로젝트: slactjohnson/mec
class TimingChannel(object):
    def __init__(self, setpoint_PV, readback_PV, name):
        self.control_PV = EpicsSignal(setpoint_PV)  # DG/Vitara PV
        self.storage_PV = EpicsSignal(readback_PV)  # Notepad PV
        self.name = name

    def save_t0(self, val=None):
        """
        Set the t0 value directly, or save the current value as t0.
        """
        if not val:  # Take current value to be t0 if not provided
            val = self.control_PV.get()
        self.storage_PV.put(val)  # Save t0 value

    def restore_t0(self):
        """
        Restore the t0 value from the current saved value for t0.
        """
        val = self.storage_PV.get()
        self.control_PV.put(val)  # write t0 value

    def mvr(self, relval):
        """
        Move the control PV relative to it's current value.
        """
        currval = self.control_PV.get()
        self.control_PV.put(currval - relval)

    def mv(self, val):
        t0 = self.storage_PV.get()
        self.control_PV.put(t0 - val)

    def get_delay(self, verbose=False):
        delay = self.control_PV.get() - self.storage_PV.get()
        if delay > 0:
            print("X-rays arrive {} s before the optical laser".format(
                abs(delay)))
        elif delay < 0:
            print("X-rays arrive {} s after the optical laser".format(
                abs(delay)))
        else:  # delay is 0
            print("X-rays arrive at the same time as the optical laser")
        if verbose:
            control_data = (self.name, self.control_PV.pvname,
                            self.control_PV.get())
            storage_data = (self.name, self.storage_PV.pvname,
                            self.storage_PV.get())
            print("{} Control PV: {}, Control Value: {}".format(*control_data))
            print("{} Storage PV: {}, Storage Value: {}".format(*storage_data))
예제 #15
0
class FuncPositioner(FltMvInterface, SoftPositioner):
    """
    Class for hacking together a positioner-like object.

    Before you use this, make sure your use case cannot be easily handled by a
    `PVPositioner` or by a `PseudoPositioner`.

    This should be fast to set up, but has the following limitations:
    - Inspection tools will not work properly, in general
    - typhos, happi, and similar tools will not work
    - It is not possible to know ahead of time if any control layer signals
      poked by this device are connected.
    - Metadata about the control layer will not be provided.
    - It's not possible to intelligently subscribe to control layer signals.
      Everything will be periodic polls on background threads.
    - Session performance may be negatively impacted by slow polling functions.

    Parameters
    ----------
    name : str, keyword-only
        The name to use when we refer to this positioner.

    move : func, keyword-only
        The function to call to cause the device to move.
        The signature must be def fn(position)

    get_pos : func, keyword-only
        The function to call to check the device's position.
        The signature must be def fn()

    set_pos : func, optional, keyword-only
        If provided, the function to call to change the device's shown
        position without moving it. The signature must be def fn(position)

    stop : func, optional, keyword-only
        If provided, the function to call to stop the motor.
        The signature must be def fn()

    done : func, optional, keyword-only
        If provided, the function to call to check if the device
        is done moving. The signature must be def fn() -> bool, and it
        must return True when motion is complete and false otherwise.

    check_value : func, optional, keyword-only
        If provided, an extra function to call to check if it is safe to
        move. The signature must be def fn(position) -> raise ValueError

    info : func, optional, keyword-only
        If provided, an extra function to add data to the ipython console
        pretty-print. The signature must be def fn() -> dict{str: value}.

    egu : str, optional
        If provided, the metadata units for the positioner.

    limits : tuple of floats, optional
        If provided, we'll raise an exception to reject moves outside of this
        range.

    update_rate : float, optional
        How often to update the position and check for move completion during a
        move. Defaults to 1 second.

    timeout : float, optional
        How long to wait before marking an in-progress move as failed.
        Defaults to 60 seconds.

    notepad_pv : str, optional
        If provided, a PV to put to whenever we move. This can be used to allow
        other elements in the control system to see what this positioner is
        doing.
    """
    def __init__(self,
                 *,
                 name,
                 move,
                 get_pos,
                 set_pos=None,
                 stop=None,
                 done=None,
                 check_value=None,
                 info=None,
                 egu='',
                 limits=None,
                 update_rate=1,
                 timeout=60,
                 notepad_pv=None,
                 parent=None,
                 kind=None,
                 **kwargs):
        self._check_signature('move', move, 1)
        self._move = move
        self._check_signature('get_pos', get_pos, 0)
        self._get_pos = get_pos
        self._check_signature('set_pos', set_pos, 1)
        self._set_pos = set_pos
        self._check_signature('stop', stop, 0)
        self._stop = stop
        self._check_signature('done', done, 0)
        self._done = done
        self._check_signature('check_value', check_value, 1)
        self._check = check_value
        self._info = info
        self._last_update = 0
        self._goal = None
        self.update_rate = 1
        notepad_name = name + '_notepad'
        if notepad_pv is None:
            self.notepad_signal = Signal(name=notepad_name)
        else:
            self.notepad_signal = EpicsSignal(notepad_pv, name=notepad_name)
        if parent is None and kind is None:
            kind = 'hinted'
        super().__init__(name=name,
                         egu=egu,
                         limits=limits,
                         source='func',
                         timeout=timeout,
                         parent=parent,
                         kind=kind,
                         **kwargs)

    def _check_signature(self, name, func, nargs):
        if func is None:
            return
        sig = inspect.signature(func)
        try:
            sig.bind(*(0, ) * nargs)
        except TypeError:
            raise ValueError(
                f'FuncPositioner recieved {name} with an incorrect. '
                f'signature. Must be able to take {nargs} args.') from None

    def _setup_move(self, position, status):
        self._run_subs(sub_type=self.SUB_START, timestamp=time.time())
        self._goal = position
        self._started_moving = True
        self._moving = True
        self._finished = False
        self._move(position)
        self._new_update(status)

    def _new_update(self, status):
        schedule_task(self._update_task,
                      args=(status, ),
                      delay=self.update_rate)

    def _update_task(self, status):
        self._update_position()
        if self._check_finished():
            self._started_moving = False
            self._moving = False
            self._update_position(force=True)
            try:
                status.set_finished()
            except InvalidState:
                pass
        else:
            self._new_update(status)

    @property
    def position(self):
        self._update_position()
        return self._position

    def _update_position(self, force=False):
        if force or time.monotonic() - self._last_update > self.update_rate:
            self._last_update = time.monotonic()
            pos = self._get_pos()
            self.notepad_signal.put(pos)
            self._set_position(pos)

    def _check_finished(self):
        if self._done is None:
            finished = np.isclose(self._goal, self.position)
        else:
            finished = self._done()
        if finished:
            self._done_moving()
        return finished

    def set_position(self, position):
        if self._set_pos is None:
            raise NotImplementedError(f'FuncPositioner {self.name} was not '
                                      'given a set_pos argument.')
        else:
            self._set_pos(position)

    def stop(self, *args, **kwargs):
        if self._stop is None:
            # Often called by bluesky, don't throw an exception
            self.log.warning(f'Called stop on FuncPositioner {self.name}, '
                             'but was not given a stop argument.')
        else:
            self._stop()
        super().stop(*args, **kwargs)

    def check_value(self, pos):
        super().check_value(pos)
        if self._check is not None:
            self._check(pos)

    def status_info(self):
        info = super().status_info()
        if self._info is not None:
            info.update(self._info())
        return info
예제 #16
0
class User():
    def __init__(self):
        #switch to trigger instead of full evr
        self._sync_markers = {
            0.5: 0,
            1: 1,
            5: 2,
            10: 3,
            30: 4,
            60: 5,
            120: 6,
            360: 7
        }
        self.trigger_mag = Trigger('XCS:R42:EVR:01:TRIG4', name='trigger_mag')
        self.trigger_pp = Trigger('XCS:USR:EVR:TRIG1', name='trigger_pp')
        #self.nemptyshots = actions(0, name='nemptyshots')
        #self.isfire = actions(False, name='isfire')
        #self.emptyshotspacing = actions(0, name='emptyshotspacing')
        #self.nshots = actions(0, name='nshots')
        #self.shotspacing = actions(0, name='shotspacing')
        #with safe_load('Pirani and Cold Cathode Gauges'):
        #    self.mag_pirani = BaseGauge('XCS:USR:GPI:01', name='mag_pirani')
        #    self.mag_cc = BaseGauge('XCS:USR:GCC:01', name='mag_cc')
        self.sample_temp = LakeShoreChannel('XCS:USR:TCT:02', name='A')
        self.mag_temp = LakeShoreChannel('XCS:USR:TCT:02', name='B')
        self.ttl_high = 2.0
        self.ttl_low = 0.8
        self._ready_sig = EpicsSignal('XCS:USR:ai1:0',
                                      name='User Analog Input channel 0',
                                      kind='omitted')
        self.i0_threshold = 4000  # default threshold is 0
        self.i0_avg = AvgSignal(ipm4.wave8.isum, 30, name='ipm4_sum_avg')
        self.i0_mag_retry = 10
        self._gdet_threshold_pv = EpicsSignal('XCS:VARS:J78:GDET_THRES',
                                              kind='normal')
        #self.gdet_avg_count = 30
        #self.gdet_mag_retry = 10
        #self.gdet = GasDetector('GDET:FEE1', name='gas detector')
        #self._bykik_pv = Cpt(EpicsSignal('IOC:IN20:EV01:BYKIK_ABTACT', kind = 'normal', string=True, doc='BYKIK: Abort Active')
        self._req_burst_rate = 'Full'
        self._test_burst_rate = EpicsSignal('PATT:SYS0:1:TESTBURSTRATE',
                                            name='test_burst_rate',
                                            kind='normal')
        self._mps_burst_rate = EpicsSignal('PATT:SYS0:1:MPSBURSTRATE',
                                           name='mps_burst_rate')
        # number of seconds to pause between empty and magnet
        self.pause_time = 2.
        self._min_empty_delay = 4
        self._beam_owner = EpicsSignal('ECS:SYS0:0:BEAM_OWNER_ID',
                                       name='beam_owner',
                                       kind='normal')
        self._att = att
        self.hutch = 'xcs'
        self._hutch_id = EpicsSignal('ECS:SYS0:4:HUTCH_ID',
                                     name='hutch_id',
                                     kind='normal')
        self.aliases = ['BEAM']
        self.gainmodes = ''

#use lcls.(tab) to find bykik controls

    @property
    def machine_burst_rate(self):
        if self._beam_owner.get() == self._hutch_id.get():
            self._mps_burst_rate.get()
        else:
            self._test_burst_rate.get()

    @machine_burst_rate.setter
    def machine_burst_rate(self, rate):
        if self._beam_owner.get() == self._hutch_id.get():
            self._mps_burst_rate.put(rate)
        else:
            self._test_burst_rate.put(rate)

    def check_burst_rate(self):
        if self.machine_burst_rate != self._req_burst_rate:
            print('Machine burst frequency not set to %s! - fixing...' %
                  self._req_burst_rate)
            if self._beam_owner.get() == self._hutch_id.get():
                set_and_wait(
                    self._mps_burst_rate, self._req_burst_rate
                )  #ophyd set and wait() - ophyd.utils.epics_pvs.set_and_wait
            else:
                set_and_wait(self._test_burst_rate, self._req_burst_rate)
            print('done.')

    @property
    def ready_sig(self):
        return self._ready_sig.get()

    def seq_wait(self, timeout=0, sleeptime=1.0):
        print(f'timeout = {timeout}, sleep = {sleeptime}')
        sleep(sleeptime)
        start = time.time()
        print(f'start time: {start}')
        while seq.play_status.get() != 0:
            if timeout > 0 and (time.time() - start >= timeout):
                raise ValueError('Timed out')

    def _prepare_burst(self,
                       Nshots,
                       Nbursts=1,
                       freq=120,
                       delay=None,
                       burstMode=False):
        if Nshots == 1:
            pp.flipflop()
        elif Nshots > 1:
            pp.burst()
        if Nbursts == 1:
            seq.play_mode.put(0)
        elif Nbursts > 1:
            seq.play_mode.put(1)
            seq.rep_count.put(Nbursts)
        elif Nbursts < 0:
            seq.play_mode.put(2)
        if burstMode:
            burst = Nshots + 2
        else:
            burst = 0
        if not freq == 120:
            raise (NotImplementedError('Not implemented yet!'))
        if Nshots == 1:
            if delay is None:
                delay = 3
            elif delay < 2:
                raise ValueError(
                    'Delay between flip flops of less than two is not allowed')
            ff_seq = [[84, delay, 0, burst], [86, 0, 0, burst],
                      [85, 2, 0, burst]]
        elif Nshots > 1:
            if delay is None:
                delay = 1
            elif delay < 1:
                raise ValueError(
                    'Delay between bursts of less than one is not allowed')
            ff_seq = [[84, delay, 0, burst], [86, 0, 0, burst],
                      [86, 1, 0, burst]]
            for shotNo in range(Nshots):
                ff_seq.append([85, 1, 0, burst])
                if shotNo == Nshots - 2:
                    ff_seq.append([84, 0, 0, burst])

        seq.sequence.put_seq(ff_seq)

    def _prepNonMagShots(self, nshots):
        #copy code from old pulsepicker.py file in (blinst) and change where needed or xpp experiment
        self._prepare_burst(nshots, burstMode=True)

    def _prepSpacedNonMagShots(self, nshots_per_burst, spacing):
        nshots = 1
        burstDelay = spacing - 2
        self.prepare_burst(nshots,
                           Nbursts=nshots_per_burst,
                           delay=burstDelay,
                           burstMode=True)

    def _takeNonMagShots(self):
        seq.start()

    def _prepMagShot(self, isfire, delay=1):
        pp.flipflop()
        seq.play_mode.put(0)
        ff_seq = [[84, delay, 0, 3], [86, 0, 0, 0]]
        if isfire:
            ff_seq.append([self.trigger_mag.get_eventcode(), 2, 0, 0])
            ff_seq.append([85, 0, 0, 0])
        else:
            ff_seq.append([85, 2, 0, 0])
        seq.sequence.put_seq(ff_seq)

    def _takeMagShot(self):
        seq.start()

    def _laserOn(self):
        """
        laser on by goose trigger 88
        """
        os.system('caput XCS:ECS:IOC:01:EC_11:00 88')
        os.system('caput ECS:SYS0:11:LEN 1')
        os.system('caput ECS:SYS0:11:PLYCTL 1')

    def _laserOff(self):
        """
        laser off by goose trigger 89
        """
        os.system('caput XCS:ECS:IOC:01:EC_11:00 89')
        os.system('caput ECS:SYS0:11:LEN 1')
        os.system('caput ECS:SYS0:11:PLYCTL 1')

    def _laserNormal(self):
        """
        normal on/off mode
        """
        os.system('caput XCS:ECS:IOC:01:EC_11:00 88')
        os.system('caput ECS:SYS0:11:LEN 7')
        os.system('caput ECS:SYS0:11:PLYCTL 1')

    def takeEmptyShots(self, nshots, shotspacing, use_daq=False, record=None):
        calibcontrols = {
            'nshots': ConfigVal(nshots),
            'shotspacing': ConfigVal(shotspacing)
        }

        if shotspacing > 0:
            self._prepSpacedNonMagShots(nshots, shotspacing)
        else:
            self._prepNonMagShots(nshots)
        #configure daq if being used
        if use_daq:
            daq.record = record
            daq.configure(events=0, controls=calibcontrols)
        try:
            if use_daq:
                daq.begin(events=nshots, controls=calibcontrols)
            seq.start()
            self.seq_wait()
            if use_daq:
                daq.wait()
        except KeyboardInterrupt:
            seq.stop()
        finally:
            if use_daq:
                daq.record = None
                daq.disconnect()

    def takeMagnetShot(self,
                       nemptyshots,
                       emptyshotspacing=0,
                       isfire=False,
                       record=None):
        calibcontrols = {
            'mag_isfire': ConfigVal(isfire),
            'mag_trigger_delay': self.trigger_mag.ns_delay,
            'mag_trig_width': self.trigger_mag.width,
            'mag_trig_eventcode': self.trigger_mag.eventcode,
            'nemptyshots': ConfigVal(nemptyshots),
            'emptyshotspacing': ConfigVal(emptyshotspacing)
        }
        # check the machine burst rate and set to Full rate if not
        self.check_burst_rate()
        # disable BYKIK before taking shots
        lcls.bykik_disable()
        # check if emptyshotspacing is valid
        if 0 < emptyshotspacing < self._min_empty_delay:
            raise ValueError(
                "When using spacing between empty shots it must be >= %d" %
                self._min_empty_delay)
        spacer = "*********************************"
        print("\n%s\n* Preparing to take magnet shot *\n%s\n" %
              (spacer, spacer))
        if emptyshotspacing > 0:
            mag_status = "Taking %d shots, with a spacing between each of %d beam pulses, before firing the magnet\n" % (
                nemptyshots, emptyshotspacing)
        else:
            mag_status = "Taking %d shots before firing the magnet\n" % nemptyshots
        mag_status += "Magnet pulse eventcode: %d\n" % self.trigger_mag.get_eventcode(
        )
        mag_status += "Magnet pulse trigger delay: %f\n" % self.trigger_mag.get_delay(
        )
        mag_status += "Magnet pulse trigger width: %f\n" % self.trigger_mag.get_width(
        )
        mag_status += "Magnet to be fired: %s\n" % isfire
        print(mag_status)
        try:
            daq.record = record
            daq.configure(events=0, controls=calibcontrols)
            # Pre empty shots
            if nemptyshots > 0:
                print("\nPreparing sequencer for pre-firing, non-magnet shots")
                if emptyshotspacing > 0:
                    self._prepSpacedNonMagShots(nemptyshots, emptyshotspacing)
                else:
                    self._prepNonMagShots(nemptyshots)
                    time.sleep(self.pause_time)
                daq.begin(events=nemptyshots, controls=calibcontrols)
                print("\nTaking %d pre-firing, non-magnet shots\n" %
                      nemptyshots)
                # pause after changing pulse picker mode
                time.sleep(self.pause_time)
                self._takeNonMagShots()
                print('Taking shots')
                self.seq_wait()
                print('seq finished')
                daq.wait()
                print('daq finished')
            else:
                print("\nSkipping prefiring, non-magnet shots\n")
            # pause after empty shots
            time.sleep(self.pause_time)
            print('sleep finished')
            # Fire the magnet sequence based on isfire flag
            if isfire:
                print("Start magnet firing sequence\n")
            else:
                print("Start magnet test 'firing' sequence\n")
            print("\nPreparing sequencer for magnet shot")
            if emptyshotspacing > 0:
                self._prepMagShot(isfire, emptyshotspacing)
            else:
                self._prepMagShot(isfire)
                time.sleep(self.pause_time)
            # pause after changing pulse picker mode
            time.sleep(self.pause_time)
            #checking ipm4??
            num_tries = 0
            i0_good = False
            while num_tries < self.i0_mag_retry:
                i0_val = self.i0_avg.get()
                if i0_val < self.i0_threshold:
                    print(
                        "\nNot firing magnet due to low beam current (ipm4): %.3f \n"
                        % (i0_val))
                    backoff_time = 2**num_tries
                    print("Sleeping for %d seconds...\n" % backoff_time)
                    time.sleep(backoff_time)
                    num_tries += 1
                else:
                    #ipm4 is good - fire!
                    i0_good = True
                    print("\nInitial intensity(ipm4) looks good: %.3f\n" %
                          i0_val)
                    break
            if not i0_good:
                print(
                    "Max number of i0 checks (%d) exceeded! - Abort shot attempt.\n"
                    % self.i0_mag_retry)
                return False
            # take the magnet shot
            daq.begin(events=1, controls=calibcontrols)
            print("\nTaking magnet shot\n")
            self._takeMagShot()
            self.seq_wait()
            daq.wait()
            #pause after magnet shots
            time.sleep(self.pause_time)
            #post empty shots
            if nemptyshots > 0:
                print(
                    "\nPreparing sequencer for post-firing, non-magnet shots")
                if emptyshotspacing > 0:
                    self._prepSpacedNonMagShots(nemptyshots, emptyshotspacing)
                else:
                    self._prepNonMagShots(nemptyshots)
                    time.sleep(self.pause_time)
                daq.begin(events=nemptyshots, controls=calibcontrols)
                print("\nTaking %d post-firing, non-magnet shots\n" %
                      nemptyshots)
                # pause after changing pulse picker mode
                time.sleep(self.pause_time)
                self._takeNonMagShots()
                self.seq_wait()
                daq.wait()
            else:
                print("\nSkipping post-firing, non-magnet shots\n")
            return True
        except KeyboardInterrupt:
            seq.stop()
            daq.stop()
            return False
        finally:
            daq.record = None
            daq.disconnect()
            lcls.bykik_enable()

    def takeMagnetShotMulti(self,
                            nemptyshots,
                            emptyshotspacing=0,
                            isfire=False,
                            record=None,
                            ignore_ready=False):
        """
        Takes magnet shots in a continous fashion waiting for a ready signal from the magnet controller
        """
        latch = False
        nmagshots = 0
        shotgood = True
        spacer = '##############################'
        try:
            while shotgood:
                if not latch and (self.ready_sig > self.ttl_high
                                  or ignore_ready):
                    i0_val = self.i0_avg.get()
                    if i0_val < self.i0_threshold:
                        print(
                            "\nNot firing magnet due to low beam current (ipm4): %.3f \n"
                            % (i0_val))
                        backoff_time = 1
                        print("Sleeping for %d second...\n" % backoff_time)
                        time.sleep(backoff_time)
                        continue
                    latch = True
                    print("\n%s\nStarting shot %d\n%s\n" %
                          (spacer, nmagshots, spacer))
                    start_time = time.time()
                    shotgood = self.takeMagnetShot(nemptyshots,
                                                   emptyshotspacing, isfire,
                                                   record)
                    stop_time = time.time()
                    print("\n%s\nCompleted shot %d in %.2f s\n%s\n" %
                          (spacer, nmagshots,
                           (stop_time - start_time), spacer))
                    nmagshots += 1
                if latch and (self.ready_sig < self.ttl_low or ignore_ready):
                    latch = False
                time.sleep(0.25)
        except KeyboardInterrupt:
            print('\nExiting...\n')
        finally:
            print('Took %d total magnet shots\n' % nmagshots)

    def takeRun(self, nEvents, record=None, use_l3t=False):
        daq.configure(events=120, record=record, use_l3t=use_l3t)
        daq.begin(events=nEvents)
        daq.wait()
        daq.end_run()

    def ascan(self,
              motor,
              start,
              end,
              nsteps,
              nEvents,
              record=None,
              use_l3t=False):
        self.cleanup_RE()
        currPos = motor.wm()
        daq.configure(nEvents,
                      record=record,
                      controls=[motor],
                      use_l3t=use_l3t)
        try:
            RE(scan([daq], motor, start, end, nsteps))
        except Exception:
            logger.debug('RE Exit', exc_info=True)
        finally:
            self.cleanup_RE()
        motor.mv(currPos)

    def pv_ascan(self,
                 signal,
                 start,
                 end,
                 nsteps,
                 nEvents,
                 record=None,
                 use_l3t=False):
        self.cleanup_RE()
        currPos = signal.get()
        daq.configure(nEvents,
                      record=record,
                      controls=[signal],
                      use_l3t=use_l3t)
        try:
            RE(scan([daq], signal, start, end, nsteps))
        except Exception:
            logger.debug('RE Exit', exc_info=True)
        finally:
            self.cleanup_RE()
        signal.put(currPos)

    def listscan(self, motor, posList, nEvents, record=None, use_l3t=False):
        self.cleanup_RE()
        currPos = motor.wm()
        daq.configure(nEvents,
                      record=record,
                      controls=[motor],
                      use_l3t=use_l3t)
        try:
            RE(list_scan([daq], motor, posList))
        except Exception:
            logger.debug('RE Exit', exc_info=True)
        finally:
            self.cleanup_RE()
        motor.mv(currPos)

    def list3scan(self,
                  m1,
                  p1,
                  m2,
                  p2,
                  m3,
                  p3,
                  nEvents,
                  record=None,
                  use_l3t=False):
        self.cleanup_RE()
        currPos1 = m1.wm()
        currPos2 = m2.wm()
        currPos3 = m3.wm()
        daq.configure(nEvents,
                      record=record,
                      controls=[m1, m2, m3],
                      use_l3t=use_l3t)
        try:
            RE(list_scan([daq], m1, p1, m2, p2, m3, p3))
        except Exception:
            logger.debug('RE Exit', exc_info=True)
        finally:
            self.cleanup_RE()
        m1.mv(currPos1)
        m2.mv(currPos2)
        m3.mv(currPos3)

    def dscan(self,
              motor,
              start,
              end,
              nsteps,
              nEvents,
              record=None,
              use_l3t=False):
        self.cleanup_RE()
        daq.configure(nEvents,
                      record=record,
                      controls=[motor],
                      use_l3t=use_l3t)
        currPos = motor.wm()
        try:
            RE(scan([daq], motor, currPos + start, currPos + end, nsteps))
        except Exception:
            logger.debug('RE Exit', exc_info=True)
        finally:
            self.cleanup_RE()
        motor.mv(currPos)

    def pv_dscan(self,
                 signal,
                 start,
                 end,
                 nsteps,
                 nEvents,
                 record=None,
                 use_l3t=False):
        self.cleanup_RE()
        daq.configure(nEvents,
                      record=record,
                      controls=[signal],
                      use_l3t=use_l3t)
        currPos = signal.get()
        try:
            RE(scan([daq], signal, currPos + start, currPos + end, nsteps))
        except Exception:
            logger.debug('RE Exit', exc_info=True)
        finally:
            self.cleanup_RE()
        signal.put(currPos)

    def a2scan(self,
               m1,
               a1,
               b1,
               m2,
               a2,
               b2,
               nsteps,
               nEvents,
               record=True,
               use_l3t=False):
        self.cleanup_RE()
        daq.configure(nEvents,
                      record=record,
                      controls=[m1, m2],
                      use_l3t=use_l3t)
        try:
            RE(scan([daq], m1, a1, b1, m2, a2, b2, nsteps))
        except Exception:
            logger.debug('RE Exit', exc_info=True)
        finally:
            self.cleanup_RE()

    def a3scan(self,
               m1,
               a1,
               b1,
               m2,
               a2,
               b2,
               m3,
               a3,
               b3,
               nsteps,
               nEvents,
               record=True):
        self.cleanup_RE()
        daq.configure(nEvents, record=record, controls=[m1, m2, m3])
        try:
            RE(scan([daq], m1, a1, b1, m2, a2, b2, m3, a3, b3, nsteps))
        except Exception:
            logger.debug('RE Exit', exc_info=True)
        finally:
            self.cleanup_RE()

    def delay_scan(self,
                   start,
                   end,
                   sweep_time,
                   record=None,
                   use_l3t=False,
                   duration=None):
        """Delay scan with the daq."""
        self.cleanup_RE()
        daq.configure(events=None,
                      duration=None,
                      record=record,
                      use_l3t=use_l3t,
                      controls=[lxt_fast])
        try:
            RE(
                delay_scan(daq,
                           lxt_fast, [start, end],
                           sweep_time,
                           duration=duration))
        except Exception:
            logger.debug('RE Exit', exc_info=True)
        finally:
            self.cleanup_RE()

    def empty_delay_scan(self,
                         start,
                         end,
                         sweep_time,
                         record=None,
                         use_l3t=False,
                         duration=None):
        """Delay scan without the daq."""
        self.cleanup_RE()
        #daq.configure(events=None, duration=None, record=record,
        #              use_l3t=use_l3t, controls=[lxt_fast])
        try:
            RE(
                delay_scan(None,
                           lxt_fast, [start, end],
                           sweep_time,
                           duration=duration))
        except Exception:
            logger.debug('RE Exit', exc_info=True)
        finally:
            self.cleanup_RE()

    def cleanup_RE(self):
        if not RE.state.is_idle:
            print('Cleaning up RunEngine')
            print('Stopping previous run')
            try:
                RE.stop()
            except Exception:
                pass