Skip to content

Commit

Permalink
Merge pull request #208 from BCDA-APS/202-spec2ophyd
Browse files Browse the repository at this point in the history
add labels attribute to enable wa and ct magic commands
  • Loading branch information
prjemian committed Jul 30, 2019
2 parents d977736 + 8349afc commit fb6f5fb
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 50 deletions.
18 changes: 13 additions & 5 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@
Change History
##############

:1.1.10: release *tba* : updates & bug fix

* `#207 <https://github.com/BCDA-APS/apstools/issues/207>`_
``show_ophyd_symbols`` also shows labels
* `#206 <https://github.com/BCDA-APS/apstools/issues/206>`_
new: ``apstools.utils.APS_utils.list_recent_scans()``
* `#205 <https://github.com/BCDA-APS/apstools/issues/205>`_
``show_ophyd_symbols`` uses ipython shell's namespace
* `#202 <https://github.com/BCDA-APS/apstools/issues/202>`_
add ``labels`` attribute to enable ``wa`` and ``ct`` magic commands

:1.1.9: released *2019-07-28* : updates & bug fix

* `#203 <https://github.com/BCDA-APS/apstools/issues/203>`_
Expand All @@ -28,13 +39,10 @@ Change History

:1.1.7: released 2019-07-04

.. note:: DEPRECATION:
* `DEPRECATION <https://github.com/BCDA-APS/apstools/issues/90#issuecomment-483405890>`_
`apstools.plans.run_blocker_in_plan()` will be removed by 2019-12-31.
`Do not write blocking code in bluesky plans.
<https://github.com/BCDA-APS/apstools/issues/90#issuecomment-483405890>`_

.. note:: Dropped python 3.5 from supported versions

* Dropped python 3.5 from supported versions
* `#175 <https://github.com/BCDA-APS/apstools/issues/175>`_
move `plans.run_in_thread()` to `utils.run_in_thread()`
* `#168 <https://github.com/BCDA-APS/apstools/issues/168>`_
Expand Down
10 changes: 5 additions & 5 deletions apstools/migration/spec2ophyd.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,12 +120,12 @@ def setDevice(self, devices):
self.ignore = True

def ophyd_config(self):
s = f"{self.mne} = {self.signal_name}('{self.pvname}', name='{self.mne}')"
s = f"{self.mne} = {self.signal_name}('{self.pvname}', name='{self.mne}', labels=('detectors',))"
suffix = None
if "misc_par_1" in self.cntpar:
suffix = self.cntpar.pop("misc_par_1")
pvname = f"{self.device.prefix}{suffix}"
s = f"{self.mne} = EpicsSignal('{pvname}', name='{self.mne}')"
s = f"{self.mne} = EpicsSignal('{pvname}', name='{self.mne}', labels=('detectors',))"
if self.mne != self.name:
s += f" # {self.name}"
if self.ignore:
Expand Down Expand Up @@ -200,12 +200,12 @@ def setDevice(self, devices):
self.ignore = True

def ophyd_config(self):
s = f"{self.mne} = EpicsMotor('{self.pvname}', name='{self.mne}')"
s = f"{self.mne} = EpicsMotor('{self.pvname}', name='{self.mne}', labels=('motor',))"
suffix = None
if "misc_par_1" in self.motpar:
suffix = self.motpar.pop("misc_par_1")
pvname = f"{self.device.prefix}{suffix}"
s = f"{self.mne} = EpicsMotor('{pvname}', name='{self.mne}')"
s = f"{self.mne} = EpicsMotor('{pvname}', name='{self.mne}', labels=('motor',))"
if self.pvname is None:
if self.macro_prefix is not None:
s = f"# Macro Motor: {self}"
Expand Down Expand Up @@ -288,7 +288,7 @@ def ophyd_config(self):
if "misc_par_1" in self.cntpar:
suffix = self.cntpar.pop("misc_par_1")
pvname = f"{self.device.prefix}{suffix}"
s = f"{self.mne} = EpicsSignal('{pvname}', name='{self.mne}')"
s = f"{self.mne} = EpicsSignal('{pvname}', name='{self.mne}', labels=('detectors',))"
if self.ignore:
s = f"# {self.config_line}: {self.raw}"
if len(self.cntpar) > 0:
Expand Down
108 changes: 81 additions & 27 deletions apstools/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@
~ExcelDatabaseFileBase
~ExcelDatabaseFileGeneric
~ExcelReadError
~ipython_profile_name
~itemizer
~json_export
~json_import
~ipython_profile_name
~list_recent_scans
~pairwise
~print_snapshot_list
~print_RE_md
Expand Down Expand Up @@ -140,7 +141,7 @@ def dictionary_table(dictionary, fmt="simple"):
default: ``simple``
.. [#] *pyRestTable* : https://pyresttable.readthedocs.io/en/latest/examples/index.html#examples
.. [#] *pyRestTable* : https://pyresttable.readthedocs.io/en/latest/examples/index.html#examples
RETURNS
Expand Down Expand Up @@ -181,6 +182,65 @@ def itemizer(fmt, items):
return [fmt % k for k in items]


def list_recent_scans(num=20, keys=[], printing=True, db=None):
"""
make a table of the most recent scans
PARAMETERS
num : int (default: ``20``)
Make the table include the ``num`` most recent scans.
keys : [str] (default: ``[]``)
Include these additional keys from the start document.
printing : bool (default: ``True``)
If True, print the table to stdout
db : object (default: ``db`` from the IPython shell)
Instance of ``databroker.Broker()``
RETURNS
object:
Instance of `pyRestTable.Table()``
EXAMPLE::
In [7]: APS_utils.list_recent_scans(num=5, keys=["proposal_id","pid"])
========= ========================== ======= ========= =========== =====
short_uid date/time scan_id plan_name proposal_id pid
========= ========================== ======= ========= =========== =====
235cc8e 2019-07-26 19:59:57.377210 156 scan testing 31185
82406dd 2019-07-26 19:57:30.607125 155 scan testing 31185
f6249d8 2019-07-25 16:45:36.114533 151 count testing 15321
9457fa4 2019-07-25 16:19:07.410803 150 count testing 4845
f17f026 2019-07-25 16:19:04.929030 149 count testing 4845
========= ========================== ======= ========= =========== =====
"""
try:
from IPython import get_ipython
global_db = get_ipython().user_ns["db"]
except AttributeError as _exc:
global_db = None
db = db or global_db

keys.insert(0, "plan_name")
keys.insert(0, "scan_id")

table = pyRestTable.Table()
table.labels = "short_uid date/time".split() + keys

for h in db[-abs(num):]:
row = [
h.start["uid"][:7],
datetime.datetime.fromtimestamp(h.start['time']),
] + [h.start.get(k, "") for k in keys]
table.addRow(row)

if printing:
print(table)
return table


def print_RE_md(dictionary=None, fmt="simple", printing=True):
"""
custom print the RunEngine metadata in a table
Expand Down Expand Up @@ -210,7 +270,11 @@ def print_RE_md(dictionary=None, fmt="simple", printing=True):
======================== ===================================
"""
global RE
try:
from IPython import get_ipython
RE = get_ipython().user_ns["RE"]
except AttributeError as _exc:
RE = None
dictionary = dictionary or RE.md
md = dict(dictionary) # copy of input for editing
v = dictionary_table(md["versions"], fmt=fmt) # sub-table
Expand Down Expand Up @@ -279,30 +343,13 @@ def show_ophyd_symbols(show_pv=True, printing=True, verbose=False, symbols=None)
If True, also show ``str(obj``.
symbols: dict (default: `globals()`)
If None, use global symbol table.
If not None, use provided dictionary.
**TIP** ``globals()`` only gets the module's globals
To get ``globals()`` from the global namespace, need to
pass that from the global namespace into this function.
Define this function *in* the global namespace::
from apstools import utils as APS_utils
def show_ophyd_symbols(
show_pv=True,
printing=True,
verbose=False,
symbols=None
):
symbols = symbols or globals()
return APS_utils.show_ophyd_symbols(
show_pv=show_pv,
printing=printing,
verbose=verbose,
symbols=symbols
)
If not None, use provided dictionary.
RETURNS
object:
Instance of `pyRestTable.Table()``
EXAMPLE::
In [1]: show_ophyd_symbols()
Expand Down Expand Up @@ -333,7 +380,13 @@ def show_ophyd_symbols(
table.addLabel("EPICS PV")
if verbose:
table.addLabel("object representation")
g = symbols or globals()
table.addLabel("label(s)")
try:
from IPython import get_ipython
g = get_ipython().user_ns
except AttributeError as _exc:
g = globals()
g = symbols or g
for k, v in sorted(g.items()):
if isinstance(v, (ophyd.Signal, ophyd.Device)):
row = [k, v.__class__.__name__]
Expand All @@ -346,6 +399,7 @@ def show_ophyd_symbols(
row.append("")
if verbose:
row.append(str(v))
row.append(' '.join(v._ophyd_labels_))
table.addRow(row)
if printing:
print(table)
Expand Down
31 changes: 18 additions & 13 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,21 +108,26 @@ def test_print_RE_md(self):

expected = [
'RunEngine metadata dictionary:',
'========= ================================',
'key value ',
'========= ================================',
'purpose testing ',
'something else ',
'versions ======== =======================',
' key value ',
' ======== =======================',
'========= ===============================',
'key value ',
'========= ===============================',
'purpose testing ',
'something else ',
'versions ======== ======================',
' key value ',
' ======== ======================',
f' apstools {APS__version__}',
' ======== =======================',
'========= ================================',
' ======== ======================',
'========= ===============================',
''
]
for r, e in zip(received, expected):
self.assertEqual(r, e)
self.assertEqual(len(received), len(expected))
self.assertEqual(received[4].strip(), expected[4].strip())
self.assertEqual(received[5].strip(), expected[5].strip())
self.assertEqual(
received[9].strip(),
expected[9].strip()
)

def test_pairwise(self):
items = [1.0, 1.1, 1.01, 1.001, 1.0001, 1.00001, 2]
Expand Down Expand Up @@ -160,7 +165,7 @@ def test_show_ophyd_symbols(self):
kk = sorted(sims.keys())
# sims hardware not found by show_ophyd_symbols() in globals!
table = APS_utils.show_ophyd_symbols(symbols=sims, printing=False)
self.assertEqual(3, len(table.labels))
self.assertEqual(4, len(table.labels))
rr = [r[0] for r in table.rows]
for k in kk:
msg = f"{k} not found"
Expand Down

0 comments on commit fb6f5fb

Please sign in to comment.