Skip to content

Commit

Permalink
Merge pull request #244 from BCDA-APS/240-swait-refactor
Browse files Browse the repository at this point in the history
refactor swait like calcout
  • Loading branch information
prjemian authored Sep 2, 2019
2 parents fa72d63 + 965b83e commit 729014d
Show file tree
Hide file tree
Showing 7 changed files with 393 additions and 172 deletions.
31 changes: 21 additions & 10 deletions apstools/synApps_ophyd/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
EXAMPLES:;
import apstools.synApps_ophyd
scans = apstools.synApps_ophyd.sscanDevice("xxx:", name="scans")
scans = apstools.synApps_ophyd.SscanDevice("xxx:", name="scans")
calcs = apstools.synApps_ophyd.userCalcsDevice("xxx:", name="calcs")
calc1 = calcs.calc1
Expand All @@ -34,22 +34,33 @@


from .busy import *
from .calcout import *
from .epid import *
from .save_data import *
from .sscan import *
from .swait import *
from .transform import *

__all__ = """
busyRecord
BusyRecord
BusyStatus
CalcoutRecord
CalcoutRecordChannel
EpidRecord
SaveData
sscanRecord
sscanDevice
swaitRecord
userCalcsDevice
swait_setup_random_number
swait_setup_gaussian
swait_setup_lorentzian
swait_setup_incrementer
SscanRecord
SscanDevice
SwaitRecord
SwaitRecordChannel
TransformRecord
UserCalcoutDevice
UserCalcsDevice
UserTransformsDevice
setup_gaussian_calcout
setup_gaussian_swait
setup_incrementer_calcout
setup_incrementer_swait
setup_lorentzian_calcout
setup_lorentzian_swait
setup_random_number_swait
""".split()
4 changes: 2 additions & 2 deletions apstools/synApps_ophyd/busy.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@


__all__ = """
busyRecord
BusyRecord
BusyStatus
""".split()

Expand All @@ -37,7 +37,7 @@ class BusyStatus(str, Enum):
done = "Done"


class busyRecord(Device):
class BusyRecord(Device):
state = Component(EpicsSignal, "")
output_link = Component(EpicsSignal, ".OUT")
forward_link = Component(EpicsSignal, ".FLNK")
149 changes: 125 additions & 24 deletions apstools/synApps_ophyd/calcout.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,20 @@
Component as Cpt,
DynamicDeviceComponent as DDC,
FormattedComponent as FC)
from ophyd import EpicsSignal, EpicsSignalRO, EpicsMotor
from ophyd import EpicsSignal, EpicsSignalRO

from ._common import EpicsRecordDeviceCommonAll, EpicsRecordFloatFields
# from .. import utils as APS_utils
from .. import utils as APS_utils


__all__ = [
"UserCalcoutDevice",
"CalcoutRecord",
"CalcoutRecordChannel",
"setup_gaussian_calcout",
"setup_lorentzian_calcout",
"setup_incrementer_calcout",
]
__all__ = """
UserCalcoutDevice
CalcoutRecord
CalcoutRecordChannel
setup_gaussian_calcout
setup_lorentzian_calcout
setup_incrementer_calcout
""".split()

CHANNEL_LETTERS_LIST = "A B C D E F G H I J K L".split()

Expand All @@ -73,8 +72,8 @@ def __init__(self, prefix, letter, **kwargs):

def reset(self):
"""set all fields to default values"""
self.input_value.put(0)
self.input_pv.put("")
self.input_value.put(0)


def _channels(channel_list):
Expand Down Expand Up @@ -192,56 +191,158 @@ def reset(self):
self.read_attrs.insert(0, "enable")


def _setup_peak_calcout_(calc, desc, calcout, motor, center=0, width=1, scale=1, noise=0.05):
"""internal: setup that is common to both Gaussian and Lorentzian calcout"""
def _setup_peak_calcout_(calc, desc, calcout, ref_signal, center=0, width=1, scale=1, noise=0.05):
"""
internal: setup that is common to both Gaussian and Lorentzian calcouts
PARAMETERS
calcout : object
instance of :class:`CalcoutRecord`
ref_signal : object
instance of :class:`EpicsSignal` used as $A$
center : float
$B$,
default = 0
width : float
$C$,
default = 1
scale : float
$D$,
default = 1
noise : float
$E$,
default = 0.05
"""
# to add a noisy background will need another calc
assert(isinstance(motor, EpicsMotor))
assert(isinstance(calcout, CalcoutRecord))
assert(isinstance(ref_signal, EpicsSignal))
assert(width > 0)
assert(0.0 <= noise <= 1.0)
calcout.reset()
calcout.scanning_rate.put("Passive")
calcout.channels.A.input_pv.put(motor.user_readback.pvname)
calcout.description.put(desc)
calcout.channels.A.input_pv.put(ref_signal.pvname)
calcout.channels.B.input_value.put(center)
calcout.channels.C.input_value.put(width)
calcout.channels.D.input_value.put(scale)
calcout.channels.E.input_value.put(noise)
calcout.calculation.put(calc)
calcout.scanning_rate.put(".1 second")
calcout.description.put(desc)

calcout.read_attrs = ['input_value',]
calcout.hints = {"fields": calcout.read_attrs}


def setup_gaussian_calcout(calcout, motor, center=0, width=1, scale=1, noise=0.05):
"""setup calcout for noisy Gaussian"""
def setup_gaussian_calcout(calcout, ref_signal, center=0, width=1, scale=1, noise=0.05):
"""
setup calcout for noisy Gaussian
calculation: $D*(0.95+E*RNDM)/exp(((A-B)/C)^2)$
PARAMETERS
calcout : object
instance of :class:`CalcoutRecord`
ref_signal : object
instance of :class:`EpicsSignal` used as $A$
center : float
$B$,
default = 0
width : float
$C$,
default = 1
scale : float
$D$,
default = 1
noise : float
$E$,
default = 0.05
"""
_setup_peak_calcout_(
"D*(0.95+E*RNDM)/exp(((A-b)/c)^2)",
"noisy Gaussian curve",
calcout,
motor,
ref_signal,
center=center,
width=width,
scale=scale,
noise=noise)


def setup_lorentzian_calcout(calcout, motor, center=0, width=1, scale=1, noise=0.05):
"""setup calcout record for noisy Lorentzian"""
def setup_lorentzian_calcout(calcout, ref_signal,
center=0, width=1, scale=1, noise=0.05):
"""
setup calcout record for noisy Lorentzian
calculation: $D*(0.95+E*RNDM)/(1+((A-B)/C)^2)$
PARAMETERS
calcout : object
instance of :class:`CalcoutRecord`
ref_signal : object
instance of :class:`EpicsSignal` used as $A$
center : float
$B$,
default = 0
width : float
$C$,
default = 1
scale : float
$D$,
default = 1
noise : float
$E$,
default = 0.05
"""
_setup_peak_calcout_(
"D*(0.95+E*RNDM)/(1+((A-b)/c)^2)",
"D*(0.95+E*RNDM)/(1+((A-B)/C)^2)",
"noisy Lorentzian curve",
calcout,
motor,
ref_signal,
center=center,
width=width,
scale=scale,
noise=noise)


def setup_incrementer_calcout(calcout, scan=None, limit=100000):
"""setup calcout record as an incrementer"""
"""
setup calcout record as an incrementer
PARAMETERS
calcout : object
instance of :class:`CalcoutRecord`
scan : text or int or None
any of the EPICS record `.SCAN` values,
or the index number of the value,
set to default if `None`,
default: `.1 second`
limit : int or None
set the incrementer back to zero
when this number is reached (or passed),
default: 100000
"""
# consider a noisy background, as well (needs a couple calcs)
scan = scan or ".1 second"
calcout.reset()
Expand Down
26 changes: 13 additions & 13 deletions apstools/synApps_ophyd/sscan.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@
"""
Ophyd support for the EPICS synApps sscan record
see: https://epics.anl.gov/bcda/synApps/sscan/sscanRecord.html
see: https://epics.anl.gov/bcda/synApps/sscan/SscanRecord.html
EXAMPLE
import apstools.synApps_ophyd
scans = apstools.synApps_ophyd.sscanDevice("xxx:", name="scans")
scans = apstools.synApps_ophyd.SscanDevice("xxx:", name="scans")
scans.select_channels() # only the channels configured in EPICS
Public Structures
.. autosummary::
~sscanRecord
~sscanDevice
~SscanRecord
~SscanDevice
Private Structures
Expand Down Expand Up @@ -53,8 +53,8 @@


__all__ = """
sscanRecord
sscanDevice
SscanRecord
SscanDevice
""".split()


Expand Down Expand Up @@ -185,7 +185,7 @@ def _sscan_triggers(channel_list):
return defn


class sscanRecord(Device):
class SscanRecord(Device):
"""
EPICS synApps sscan record: used as $(P):scan(N)
Expand Down Expand Up @@ -315,7 +315,7 @@ def defined_in_EPICS(self):
return channels > 0


class sscanDevice(Device):
class SscanDevice(Device):
"""
synApps XXX IOC setup of sscan records: $(P):scan$(N)
Expand All @@ -329,11 +329,11 @@ class sscanDevice(Device):
scan_dimension = Cpt(EpicsSignalRO, 'ScanDim')
scan_pause = Cpt(EpicsSignal, 'scanPause')
abort_scans = Cpt(EpicsSignal, 'AbortScans')
scan1 = Cpt(sscanRecord, 'scan1')
scan2 = Cpt(sscanRecord, 'scan2')
scan3 = Cpt(sscanRecord, 'scan3')
scan4 = Cpt(sscanRecord, 'scan4')
scanH = Cpt(sscanRecord, 'scanH')
scan1 = Cpt(SscanRecord, 'scan1')
scan2 = Cpt(SscanRecord, 'scan2')
scan3 = Cpt(SscanRecord, 'scan3')
scan4 = Cpt(SscanRecord, 'scan4')
scanH = Cpt(SscanRecord, 'scanH')
resume_delay = Cpt(EpicsSignal, 'scanResumeSEQ.DLY1')

def reset(self):
Expand Down
Loading

0 comments on commit 729014d

Please sign in to comment.