Commit fb7dead6 authored by Cyril Guilloud's avatar Cyril Guilloud
Browse files

lsconfig + lsobj + nicer print in lsmot

+ minimal tests to ensure execution.
parent 83016a90
Pipeline #47335 passed with stages
in 111 minutes and 19 seconds
......@@ -26,7 +26,7 @@ from bliss.config.channels import EventChannel
from bliss.config.conductor.client import get_text_file, get_python_modules, get_file
from bliss.common.proxy import Proxy
from bliss.common.logtools import log_warning
from bliss.common.utils import UserNamespace
from bliss.common.utils import UserNamespace, chunk_list
from bliss.common import constants
from bliss.scanning import scan_saving
from bliss.scanning import scan_display
......@@ -48,12 +48,6 @@ def get_current_session():
return CURRENT_SESSION
def chunk_list(lst, n):
"""Yield successive n-sized chunks from lst."""
for i in range(0, len(lst), n):
yield lst[i : i + n]
class _StringImporter(object):
BASE_MODULE_NAMESPACE = "bliss.session"
......
......@@ -11,6 +11,7 @@ Standard bliss macros (:func:`~bliss.common.standard.wa`, \
"""
from collections import namedtuple
import functools
import fnmatch
import inspect
import contextlib
import gevent
......@@ -298,13 +299,13 @@ def iter_counters(counters=None):
def info(obj):
"""
In Bliss `__info__` is used by the command line interface (Bliss shell or Bliss repl)
to enquire information of the internal state of any object / controller in case it is
available. this info function is to be seen as equivalent of str(obj) or repr(obj) in
this context.
In Bliss `__info__` is used by the command line interface (Bliss shell or
Bliss repl) to enquire information of the internal state of any object /
controller in case it is available. this info function is to be seen as
equivalent of str(obj) or repr(obj) in this context.
if *obj* has `__info__` implemented this `__info__` function will be called. As a fallback
option (`__info__` not implemented) repr(obj) is used.
if *obj* has `__info__` implemented this `__info__` function will be
called. As a fallback option (`__info__` not implemented) repr(obj) is used.
"""
if not inspect.isclass(obj) and hasattr(obj, "__info__"):
......@@ -324,6 +325,48 @@ def info(obj):
return info_str
def _lsobj(pattern=None):
"""
Used by bliss.shell.standard.lsobj()
"""
obj_list = list()
if pattern is None:
pattern = "*"
# Names of objects found in session
for name in current_session.object_names:
if fnmatch.fnmatch(name, pattern):
# check if an object is an aliased object.
try:
# "name" is aliased -> add it's alias name.
name = global_map.alias_or_name(name)
except AttributeError:
# "name" is not aliased -> add it.
pass
obj_list.append(name)
# Add aliases (some are not in config-objects)
for name in global_map.aliases.names_iter():
if fnmatch.fnmatch(name, pattern):
obj_list.append(name)
return obj_list
def _lsmot():
"""
Return list of motors configured in current session
Used by bliss.shell.standard.lsmot()
"""
motor_list = list()
for name in global_map.get_axes_names_iter():
motor_list.append(name)
return motor_list
def wid():
""" Print the list of undulators defined in the session and their
positions.
......
......@@ -103,6 +103,12 @@ def grouped_with_tail(iterable, n):
yield partial
def chunk_list(lst, n):
"""Yield successive n-sized chunks from lst."""
for i in range(0, len(lst), n):
yield lst[i : i + n]
def flatten_gen(items):
"""Yield items from any nested iterable; see Reference."""
for x in items:
......
......@@ -8,21 +8,22 @@
Standard functions provided to the BLISS shell.
"""
import logging
import contextlib
import time
import inspect
import itertools
import linecache
import sys
import os
import typing
import typeguard
import subprocess
import fnmatch
import logging
import numpy
import os
import shutil
import socket
from pprint import pprint
import subprocess
import sys
import time
import typeguard
import typing
from pprint import pprint # noqa (pprint is exported in shell from this module)
from gevent import sleep, Timeout
from pygments import highlight
......@@ -31,10 +32,11 @@ from pygments.formatters import TerminalFormatter
from prompt_toolkit import print_formatted_text, HTML
import bliss
from bliss import global_map, global_log, setup_globals, current_session
from bliss.common import timedisplay
from bliss.common.plot import plot
from bliss.common.standard import (
from bliss.common.plot import plot # noqa
from bliss.common.standard import ( # noqa
iter_counters,
iter_axes_state,
iter_axes_state_all,
......@@ -44,7 +46,7 @@ from bliss.common.standard import (
info,
__move,
reset_equipment,
) # noqa: F401
)
from bliss.common.standard import wid as std_wid
from bliss.common.event import connect
from bliss.controllers.lima.limatools import *
......@@ -52,8 +54,8 @@ from bliss.controllers.lima import limatools
from bliss.controllers.lima import roi as lima_roi
from bliss.common.protocols import CounterContainer
from bliss.common import measurementgroup
from bliss.common.soft_axis import SoftAxis
from bliss.common.counter import SoftCounter, Counter
from bliss.common.soft_axis import SoftAxis # noqa
from bliss.common.counter import SoftCounter, Counter # noqa
from bliss.common.utils import (
ShellStr,
typecheck_var_args_pattern,
......@@ -69,16 +71,15 @@ from bliss.shell.dialog.helpers import find_dialog, dialog as dialog_dec_cls
# objects given to Bliss shell user
from bliss.common.standard import mv, mvr, mvd, mvdr, move, rockit
from bliss.common.cleanup import cleanup, error_cleanup
from bliss.common.standard import mv, mvr, mvd, mvdr, move, rockit # noqa
from bliss.common.cleanup import cleanup, error_cleanup # noqa
from bliss.common import scans
from bliss.common.scans import *
from bliss.scanning.scan import Scan
from bliss.comm.rpc import Client
from bliss.common import logtools
from bliss.common.logtools import elog_print
from bliss.common.logtools import elog_print, user_print
from bliss.common.interlocks import interlock_state
from bliss.common.session import get_current_session
from bliss.data import lima_image
......@@ -103,7 +104,7 @@ from bliss.shell.cli import user_dialog, pt_widgets
import tabulate
from bliss.common.utils import typeguardTypeError_to_hint
from bliss.common.utils import typeguardTypeError_to_hint, chunk_list
from typing import Optional, Union
from bliss.controllers.lima.lima_base import Lima
from bliss.common.protocols import Scannable
......@@ -156,6 +157,7 @@ __all__ = (
"rockit",
"move",
"lsmot",
"lsconfig",
"plotinit",
"plotselect",
"flint",
......@@ -430,19 +432,6 @@ def lsmg():
print(_lsmg())
def _lsobj(pattern=None):
obj_list = list()
if pattern is None:
pattern = "*"
for name in current_session.object_names:
if fnmatch.fnmatch(name, pattern):
obj_list.append(name)
return obj_list
def lsobj(pattern=None):
"""
Print the list of BLISS object in current session matching the
......@@ -450,7 +439,8 @@ def lsobj(pattern=None):
<pattern> can contain jocker characters like '*' or '?'.
NB: print also badly initilized objects...
"""
for obj_name in _lsobj(pattern):
for obj_name in bliss.common.standard._lsobj(pattern):
print(obj_name, end=" ")
print("")
......@@ -642,11 +632,79 @@ def wa(**kwargs):
def lsmot():
"""
Display names of all motors
Display names of motors configured in current session.
"""
motor_list = bliss.common.standard._lsmot()
# Maximal length of objects names (min 5).
display_width = shutil.get_terminal_size().columns
if len(motor_list) == 0:
max_length = 5
print("No motor found in current session's config.")
else:
max_length = max([len(x) for x in motor_list])
# Number of items displayable on one line.
item_number = int(display_width / max_length) + 1
motor_list.sort(key=str.casefold)
user_print("Motors configured in current session:")
user_print("-------------------------------------")
print(tabulate.tabulate(chunk_list(motor_list, item_number), tablefmt="plain"))
user_print("\n")
from bliss.config import static
def lsconfig():
"""
Print all objects found in config.
Not only objects declared in current session's config.
"""
obj_dict = dict()
config = static.get_config()
# Maximal length of objects names (min 5).
display_width = shutil.get_terminal_size().columns
print()
for name in config.names_list:
c = config.get_config(name).get("class")
# print(f"{name}: {c}")
if c is None and config.get_config(name).plugin == "emotion":
c = "Motor"
try:
obj_dict[c].append(name)
except KeyError:
obj_dict[c] = list()
obj_dict[c].append(name)
# For each class
for cc in obj_dict.keys():
user_print(f"{cc}: ")
if cc is None:
user_print("----")
else:
user_print("-" * len(cc))
obj_list = list()
# put all objects of this class in a list
while obj_dict[cc]:
obj_list.append(obj_dict[cc].pop())
# print(obj_list)
max_length = max([len(x) for x in obj_list])
# Number of items displayable on one line.
item_count = int(display_width / max_length) + 1
for name in global_map.get_axes_names_iter():
print("* {}".format(name))
print(tabulate.tabulate(chunk_list(obj_list, item_count), tablefmt="plain"))
user_print()
@custom_error_msg(
......
......@@ -111,6 +111,22 @@ Current 2.00000 12.00000
Low -456.00000 -456.00000
```
### lsmot
* `lsmot()` : Print Motors configured in current session.
```python
DEMO [2]: lsmot()
Motors configured in current session:
-------------------------------------
att1z bad bsy bsz calc_mot1 calc_mot2
custom_axis hooked_error_m0 hooked_m0 hooked_m1 jogger m0
m1 omega roby robz robz2 s1b
s1d s1f s1hg s1ho s1u s1vg
s1vo
```
### sync
* `sync([<motor>]*)`: Force axes synchronization with the hardware. If no axis is
given, it syncs all all axes present in the session
......@@ -190,6 +206,8 @@ simul_mca.deadtime_det1 0D simul_mca
## Bliss Objects
### lsobj
* `lsobj()`: print the list of BLISS objects defined in a session. Can be used
with usual jocker characters:
......@@ -210,6 +228,53 @@ TEST_SESSION [6]: lsobj("???") # all objects with 3-lettres names
MG1 MG2 bad s1b s1d s1f s1u
```
### lsconfig
* `lsconfig()`: print the list of BLISS objects in config, not only objects
declared in current session.
Example:
```python
DEMO [2]: lsconfig()
MeasurementGroup:
----------------
demo_counters MG_tomo MG_sim MG_gauss MG_align
MultiplePositions:
-----------------
beamstop att1
Motor:
-----
wl_mono u42c u42b spec_m3 pzth_enc pzth psho pshg
psf psb motor7 motor6 mono mme mm_enc mm9
mm8 mm7 mm6 mm5 mm4 mm3 mm2 mm16
mm15 mm14 mm13 mm12 mm11 mm10 mm1 mech1
mc2 mc1_enc mc1 mbv4mot m5 m4 m3 m2
m1 kbvo kbvg kbho kbhg ice2 ice1 gal
fsh e_mono dummy2 dummy1 calc_mot blade_up blade_front blade_down
blade_back bend_u bend_d
None:
----
ser0 out1 kb1 hpz_rx hpz_off_2
hpz_off_1 hppstc2 hppstc1 controller_setting3 controller_setting2
controller_setting1
SimulationCounter:
-----------------
sim_ct_calib_gauss3 sim_ct_calib_gauss2 sim_ct_calib_gauss sim_ct_5 sim_ct_4
sim_ct_3 sim_ct_2 sim_ct_1 ct1
Session:
-------
test_session demo cyril
```
## Data Policy
* `newproposal()` `newsample()` `newdataset()`: Change the **proposal** **sample**
and **dataset** names used to determine the saving path.
......
import pytest
import gevent
import bliss
from bliss.shell.standard import wm
from bliss import global_map
from bliss.common.scans import loopscan
......@@ -236,3 +238,34 @@ def test_alias_connect(alias_session):
robzz.rmove(0.1)
assert move_done.is_set()
def test_alias_lsobj(alias_session):
"""
Ensure that lsobj() find all objects in the session.
"""
obj_in_session = [
"simu1",
"robu",
"lima_simulator",
"m1",
"m2",
"mot0",
"robyy",
"robzz",
"dtime",
"rtime",
"ltime",
"dtime1",
"dtime2",
"robenc",
]
obj_in_session.append("myroi") # myroi and myroi3 are added in test_alias
obj_in_session.append("myroi3") # session only during tests.
obj_in_session.sort()
obj_in_lsobj = bliss.common.standard._lsobj()
obj_in_lsobj = list(set(obj_in_lsobj)) # for uniqueness of names.
obj_in_lsobj.sort()
assert obj_in_session == obj_in_lsobj
import subprocess
# -*- coding: utf-8 -*-
#
# This file is part of the bliss project
#
# Copyright (c) 2015-2020 Beamline Control Unit, ESRF
# Distributed under the GNU LGPLv3. See LICENSE for more info.
import time
import builtins
import pytest
import numpy
import psutil
......@@ -8,6 +13,7 @@ import gevent
from bliss.shell import standard
from bliss.shell.standard import wa, wm, sta, stm, _launch_silx, umv
from bliss.shell.standard import lsmot, lsconfig, lsobj
from bliss.shell.standard import sin, cos, tan, arcsin, arccos, arctan, arctan2
from bliss.shell.standard import log, log10, sqrt, exp, power, deg2rad, rad2deg
......@@ -318,3 +324,54 @@ def test_edit_roi_counters(
assert "roi2" in cam.roi_profiles
plot_mock.select_shapes.assert_called_once()
plot_mock.focus.assert_called_once()
def test_lsmot(session, capsys, log_shell_mode):
lsmot()
captured = capsys.readouterr()
# print(captured.out)
# att1z bad bsy bsz calc_mot1 calc_mot2 custom_axis hooked_error_m0
# hooked_m0 hooked_m1 jogger m0 m1 omega roby robz robz2 s1b s1d s1f s1hg
# s1ho s1u s1vg s1vo
# Ensure to find only some motors to avoid formatting problems.
assert "att1z" in captured.out
assert "bad" in captured.out
assert "custom_axis" in captured.out
assert "hooked_error_m0" in captured.out
assert "omega" in captured.out
assert "roby" in captured.out
assert "s1d" in captured.out
assert "hooked_m1" in captured.out
def test_lsobj(session, capsys, log_shell_mode):
lsobj()
captured = capsys.readouterr()
# print(captured.out)
assert "att1" in captured.out
assert "calc_mot1" in captured.out
assert "diode0" in captured.out
assert "hooked_m0" in captured.out
assert "m1enc" in captured.out
assert "s1u" in captured.out
assert "sim_ct_gauss" in captured.out
assert "sim_ct_flat_12" in captured.out
assert "thermo_sample" in captured.out
assert "transfocator_simulator" in captured.out
def test_lsconfig(session, capsys, log_shell_mode):
lsconfig()
captured = capsys.readouterr()
# print(captured.out)
assert "Motor:" in captured.out
assert "v6biturbo" in captured.out
assert "wrong_counter" in captured.out
assert "dummy1" in captured.out
assert "xrfxrdMG" in captured.out
assert "working_ctrl" in captured.out
assert "machinfo" in captured.out
assert "times2_2d" in captured.out
assert "xia1" in captured.out
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment