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
def test_panel_creation(qtbot): panel = SignalPanel( signals={ # Signal is its own write 'Standard': EpicsSignal('Tst:Pv'), # Signal has separate write/read 'Read and Write': EpicsSignal('Tst:Read', write_pv='Tst:Write'), # Signal is read-only 'Read Only': EpicsSignalRO('Tst:Pv:RO'), # Simulated Signal 'Simulated': SynSignal(name='simul'), 'SimulatedRO': SynSignalRO(name='simul_ro') }) widget = QWidget() qtbot.addWidget(widget) widget.setLayout(panel) assert len(panel.signals) == 5 # Check read-only channels do not have write widgets panel.layout().itemAtPosition(2, 1).layout().count() == 1 panel.layout().itemAtPosition(4, 1).layout().count() == 1 # Check write widgets are present panel.layout().itemAtPosition(0, 1).layout().count() == 2 panel.layout().itemAtPosition(1, 1).layout().count() == 2 panel.layout().itemAtPosition(3, 1).layout().count() == 2 return panel
def __init__(self, pvname, sleep=0, pre_plan=None, post_plan=None, tripped_message="", averages=1, **kwargs): sig = EpicsSignalRO(pvname) if averages > 1: sig = AvgSignal(sig, averages, name=sig.name + "_avg") def pre_plan(*args, **kwargs): logger.debug("starting suspender") return (yield from null()) def post_plan(*args, **kwargs): logger.debug("releasing suspender") return (yield from null()) super().__init__(sig, sleep=sleep, pre_plan=pre_plan(), post_plan=post_plan(), tripped_message=tripped_message, **kwargs)
def test_epics_signal_derived(): signal = EpicsSignalRO('fakepv', name='original') derived = DerivedSignal(derived_from=signal, name='derived') derived.wait_for_connection() derived.connected
def add_pv(self, read_pv, name, write_pv=None): """ Add PVs to the SignalPanel Parameters --------- read_pv : pyepics.PV name : str Name of signal to display write_pv : pyepics.PV, optional Returns ------- loc : int Row number that the signal information was added to in the `SignalPanel.layout()`` """ logger.debug("Adding PV %s", name) # Configure optional write PV settings if write_pv: sig = EpicsSignal(read_pv, name=name, write_pv=write_pv) else: sig = EpicsSignalRO(read_pv, name=name) return self.add_signal(sig, name)
def add_pv(self, read_pv, name, write_pv=None): """ Add a row, given PV names. Parameters --------- read_pv : str The readback PV name. name : str Name of signal to display. write_pv : str, optional The setpoint PV name. Returns ------- row : int Row number that the signal information was added to in the `SignalPanel.layout()``. """ logger.debug("Adding PV %s", name) # Configure optional write PV settings if write_pv: sig = EpicsSignal(read_pv, name=name, write_pv=write_pv) else: sig = EpicsSignalRO(read_pv, name=name) return self.add_signal(sig, name)
def __init__(self, suspend_thresh, resume_thresh=None, sleep=5.0, averages=120, **kwargs): sig = EpicsSignalRO('GDET:FEE1:241:ENRC') if averages > 1: sig = AvgSignal(sig, averages, name=sig.name + "_avg") super().__init__(sig, suspend_thresh, resume_thresh=resume_thresh, sleep=sleep, **kwargs)
def test_epics_signal_derived(cleanup, signal_test_ioc): signal = EpicsSignalRO( read_pv=signal_test_ioc.pvs['read_only'], name='original', ) cleanup.add(signal) signal.wait_for_connection() assert signal.connected assert signal.read_access assert not signal.write_access derived = DerivedSignal(derived_from=signal, name='derived') derived.wait_for_connection() assert derived.connected assert derived.read_access assert not derived.write_access assert derived.timestamp == signal.timestamp assert derived.get() == signal.value
def test_panel_creation(): panel = SignalPanel( "Test Signals", signals={ # Signal is its own write 'Standard': EpicsSignal('Tst:Pv'), # Signal has separate write/read 'Read and Write': EpicsSignal('Tst:Read', write_pv='Tst:Write'), # Signal is read-only 'Read Only': EpicsSignalRO('Tst:Pv:RO') }) assert len(panel.pvs) == 3 return panel
def test_epicssignal_readonly(cleanup, signal_test_ioc): signal = EpicsSignalRO(signal_test_ioc.pvs['read_only']) cleanup.add(signal) signal.wait_for_connection() print('EpicsSignalRO.metadata=', signal.metadata) signal.get() assert not signal.write_access assert signal.read_access with pytest.raises(ReadOnlyError): signal.value = 10 with pytest.raises(ReadOnlyError): signal.put(10) with pytest.raises(ReadOnlyError): signal.set(10) # vestigial, to be removed with pytest.raises(AttributeError): signal.setpoint_ts # vestigial, to be removed with pytest.raises(AttributeError): signal.setpoint signal.precision signal.timestamp signal.limits signal.read() signal.describe() signal.read_configuration() signal.describe_configuration() eval(repr(signal)) time.sleep(0.2)
def test_epicssignalro_alarm_status(): sig = EpicsSignalRO('XF:31IDA-OP{Tbl-Ax:X1}Mtr.RBV') sig.alarm_status sig.alarm_severity
def test_hints(): sig = EpicsSignalRO('XF:31IDA-OP{Tbl-Ax:X1}Mtr.RBV') assert sig.hints == {'fields': [sig.name]}
def test_epicssignal_readonly(): signal = EpicsSignalRO('readpv') signal.wait_for_connection() signal.value with pytest.raises(ReadOnlyError): signal.value = 10 with pytest.raises(ReadOnlyError): signal.put(10) with pytest.raises(ReadOnlyError): signal.set(10) # vestigial, to be removed with pytest.raises(AttributeError): signal.setpoint_ts # vestigial, to be removed with pytest.raises(AttributeError): signal.setpoint signal.precision signal.timestamp signal.limits signal.read() signal.describe() signal.read_configuration() signal.describe_configuration() eval(repr(signal)) time.sleep(0.2)
def test_hints(cleanup, motor): sig = EpicsSignalRO(motor.user_readback.pvname) cleanup.add(sig) assert sig.hints == {'fields': [sig.name]}
def test_hints(cleanup, fake_motor_ioc): sig = EpicsSignalRO(fake_motor_ioc.pvs['setpoint']) cleanup.add(sig) assert sig.hints == {'fields': [sig.name]}
import logging from nslsii import configure_base from IPython import get_ipython from bluesky.callbacks.zmq import Publisher import functools from ophyd.signal import EpicsSignal, EpicsSignalRO EpicsSignal.set_defaults(connection_timeout=10) EpicsSignalRO.set_defaults(connection_timeout=10) configure_base(get_ipython().user_ns, "jpls") publisher = Publisher("xf12id1-ws2:5577") RE.subscribe(publisher) # Optional: set any metadata that rarely changes. RE.md["beamline_id"] = "OPLS" # For debug mode from bluesky.utils import ts_msg_hook # RE.msg_hook = ts_msg_hook # THIS NEEDS TO MOVE UPSTREAM async def reset_user_position(msg): obj = msg.obj (val,) = msg.args old_value = obj.position obj.set_current_position(val) print(f"{obj.name} reset from {old_value:.4f} to {val:.4f}")
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))
#Defines relationships between centroids and motors x_centroid = SynSignal(func=partial(centroid_from_motor_cross, x_motor, y_motor, noise_scale=1), name='x_syn') y_centroid = SynSignal(func=partial(centroid_from_motor_cross, y_motor, x_motor), name='y_syn') print('Running Simulated Scan') else: #The Newport motors x_motor = Newport('XPP:LAS:MMN:13', name='real_x') y_motor = Newport('XPP:LAS:MMN:14', name='real_y') #Readback from actual beamline devices x_centroid = EpicsSignalRO('XPP:OPAL1K:01:Stats2:CentroidX_RBV', name='x_readback') y_centroid = EpicsSignalRO('XPP:OPAL1K:01:Stats2:CentroidY_RBV', name='y_readback') print('Running Real Scan') if args.tol: if args.sim: atol = args.tol print(atol) else: atol = args.tol print(atol) #Executes the plan RE(plan_simultaneously(x_centroid, y_centroid, x_motor, y_motor, atol),
def ro_signal(cleanup, signal_test_ioc): sig = EpicsSignalRO(signal_test_ioc.pvs['pair_rbv'], name='pair_rbv') cleanup.add(sig) sig.wait_for_connection() return sig
def test_epicssignalro_alarm_status(cleanup, motor): sig = EpicsSignalRO(motor.user_readback.pvname) cleanup.add(sig) sig.wait_for_connection() sig.alarm_status sig.alarm_severity
def multiScan(detX, detX_name, detTh, detTh_name, motorX, mX_name, motorTh, mTh_name, motorTTh, mTTh_name, iterations = 1, alignCriteria = {}, theta_kws = None, x_kws = None, SimAlign = False, xPlot = [], thPlot = [], sumPlot = None, sumAxes = None, verbose = False): """ multiScan: -set tthMotor to 0 degrees -set thMotor to 0 degrees -scan x-direction for transition from no-beam to full-beam -scan theta direction with detector at 2theta = 10 degrees -plot summary (if flagged) of x(half-max), theta(peak) Parameters ---------- detX : X detector object (in real alignment, same as detTh) detX_name : X detector object's name (in real alignment, same as detTh_name) detTh : Theta detector object (in real alignment, same as detX) detTh_name : Theta detector object's name (in real alignment, same as detX_name) motorX : X motor object motorX_name : X motor object's name motorTh : Theta motor object mTh_name : Theta motor object's name motorTTh : 2theta motor object mTTh_name : 2theta motor object's name iterations : Number of iterations of the X, Theta alignment scans to run through alignCriteria : dict of criteria for ending alignment Default value is None, theta_kws : dict for arguments to be passed to theta-alignment Default value is None, x_kws : dict for arguments to be passed to x-alignment Default value is None xPlot : axes object for x-alignment plot thPlot : axes object for theta-alignment plot sumPlot : plot object for usmmary plot sumAxes : axes for the x-/theta-alignment summaries SimAlign : boolean flag for simulation/testing Default value is False, verbose : boolean for showing alignment process using LiveTable callbacks. Default value is False """ if not SimAlign: motorTh.move(0) try: motorTTh.move(theta_kws['det40ffset']) except: d4offset = EpicsSignalRO('29idd:userCalcOut2.VAL', name = 'd4offset') det4offset = d4offset.get() motorTTh.move(det4offset) for i in range(iterations): asd.sequence = np.arange(i+1)+1 yield from xScanAndCenter(i+1, detX, detX_name, motorX, mX_name, plotter = xPlot, SimAlign = SimAlign, verbose = verbose, **x_kws) yield from thetaScanAndCenter(i+1, detTh, detTh_name, motorTh, mTh_name, motorTTh, mTTh_name, plotter = thPlot, SimAlign = SimAlign, verbose = verbose, **theta_kws) if sumPlot is not None: if i == 0: xLine, = sumAxes[0].plot(asd.sequence, asd.x0, markeredgecolor = 'r', markerfacecolor = 'none', marker = '^', linestyle='none', label = 'x_offset') thetaLine, = sumAxes[1].plot(asd.sequence, asd.theta5, markeredgecolor = 'b', markerfacecolor = 'none', marker = 'o', linestyle='none', label = 'theta_offset') else: xLine.set_data(asd.sequence, asd.x0) thetaLine.set_data(asd.sequence, asd.theta5) cleanAxes(sumPlot, xLine, thetaLine, sumAxes[0], sumAxes[1], 'r', 'b', 'x offset (mm)', 'theta @ 2theta = 10', 'Iteration')
plotter : axis object for theta alignment data, Default value is None which later creates new object det4offset : Detector's offset from 0 (for 2theta motor), defaults to None leading to attempt to get it from PV 29idd:userCalcOut2.VAL SimAlign : boolean flag for simulation/testing Default value is False, verbose : boolean for showing alignment process using LiveTable callbacks. Default value is False """ # detector offset angle PV: 29idd:userCalcOut2.VAL # motor2 move to offset + 10 degrees if det4offset is None: d4offset = EpicsSignalRO('29idd:userCalcOut2.VAL', name = 'd4offset') det4offset = d4offset.get() if not SimAlign: motor2.move(det4offset+10.0) motor.move(alignRange[0]) if plotter is None: figTh, thAx = plt.subplots() else: thAx = plotter cur_color = fit_colors[iteration % len(fit_colors)] coarsePlot = LivePlot(detector_name,x=motor_name, linestyle = 'none', marker = '^', markerfacecolor = 'none',
print('Input Arguments In Wrong Order') usage() sys.exit(1) if acq_time % EPICS_SAMPLE_TIME != 0: print('Acquisition Time Should Be An Integer Multiple Of %s s' % EPICS_SAMPLE_TIME) usage() sys.exit(1) outfile_name = args[3] ############################################################################## # Instantiate EpicsSignalRO sig_name = enc_pv.lower().replace(':', '_') sig = EpicsSignalRO(enc_pv, auto_monitor=True, name=sig_name) try: sig.wait_for_connection(timeout=3.0) except TimeoutError: print('Could not connect to data from PV %s, timed out.' % enc_pv) print('Either on wrong subnet or the ioc is off.') print('Make sure you are on one of the following machines:') print('psbuild-rhel7-01, psbuild-rhel7-02, lfe-console (lfe PVs),' 'kfe-console (kfe PVs') sys.exit(1) tvals = [] # Time values associated with each encoder RBV enc_vals = [] # Encoder RBV arrays, 1000 elements each timestamps = [] # timestamp for each encoder array
def test_epicssignalro(): with pytest.raises(TypeError): # not in initializer parameters anymore EpicsSignalRO('test', write_pv='nope_sorry')
def test_epicssignal_readonly(cleanup, signal_test_ioc): signal = EpicsSignalRO(signal_test_ioc.pvs['read_only']) cleanup.add(signal) signal.wait_for_connection() print('EpicsSignalRO.metadata=', signal.metadata) signal.value assert not signal.write_access assert signal.read_access with pytest.raises(ReadOnlyError): signal.value = 10 with pytest.raises(ReadOnlyError): signal.put(10) with pytest.raises(ReadOnlyError): signal.set(10) # vestigial, to be removed with pytest.raises(AttributeError): signal.setpoint_ts # vestigial, to be removed with pytest.raises(AttributeError): signal.setpoint signal.precision signal.timestamp signal.limits signal.read() signal.describe() signal.read_configuration() signal.describe_configuration() eval(repr(signal)) time.sleep(0.2)