Skip to content

BLISS utils

bliss.common.utils module contains a collection of classes and functions used to ease BLISS programming.

class handling

wrap_methods(from_object, target_object)

add_property(inst, name, method)

data structures operations

grouped(iterable, n)

  • Group elements of an iterable n by n.
  • Return a zip object.
  • s -> (s0,s1,s2,...sn-1), (sn,sn+1,sn+2,...s2n-1), (s2n,s2n+1,s2n+2,...s3n-1), ...
  • Excedentary elements are discarded.
  • example:
    DEMO [8]: from bliss.common.utils import grouped
    DEMO [5]: list(grouped([1,2,3,4,5], 2))
     Out [5]: [(1, 2), (3, 4)]
    

grouped_with_tail(iterable, n)

  • Like grouped(), but do not remove last elements if they not reach the given length n.
  • example:
    DEMO [09]: from bliss.common.utils import grouped_with_tail
    DEMO [10]: list(grouped_with_tail([1,2,3,4,5], 2))
     Out [10]: [[1, 2], [3, 4], [5]]
    

flatten_gen(items)

Flatten nested structures.

DEMO [11]: from bliss.common.utils import flatten_gen
DEMO [13]: list(flatten_gen([1, [2, 3,[4, 5], 6]]))
 Out [13]: [1, 2, 3, 4, 5, 6]

flatten(items)

  • Idem but return a list.
  • example:
    DEMO [14]: from bliss.common.utils import flatten
    DEMO [15]: flatten([1, [2, 3,[4, 5], 6]])
     Out [15]: [1, 2, 3, 4, 5, 6]
    

merge(items)

Merge a list of list, first level only.

merge([ [1,2], [3] ]) -> [1,2,3]
merge([ [1,2], [[3,4]], [5] ]) -> [1,2,[3,4],5]

DEMO [16]: from bliss.common.utils import merge
DEMO [17]: merge([ [1,2], [[3,4]], [5] ])
 Out [17]: [1, 2, [3, 4], 5]

all_equal(iterable)

Objects customization

Functions to add custom attributes and commands to an object.

Decorators for set/get methods to access to custom attributes

add_object_method(obj, method)

object_method()

Decorator to add a custom method to an object.

The same as add_object_method but its purpose is to be used as a decorator to the controller method which is to be exported as object method.

Return a method where object_method attribute is filled with a dict of elements to characterize it.

object_method_type()

add_object_attribute()

object_attribute_type_get()

object_attribute_get()

object_attribute_type_set()

object_attribute_set()

set_custom_members(src, target, pre_call)

Creates custom methods and attributes for <target_obj> object using <src_object> object definitions. Populates __custom_methods_list and __custom_attributes_dict for tango device server.

with_custom_members

A class decorator to enable custom attributes and custom methods.

Various classes and functions

Null

StripIt(object)

Encapsulate object with a short str/repr/format. Useful to have in log messages since it only computes the representation if the log message is recorded.

periodic_exec

Class to create an object repetitively calling a method.

safe_get()

human_time_fmt()

timedisplay()

  • Allow to format a time duration in a human-readable way.
  • Units managed are :

    • microseconds
    • milliseconds
    • seconds
    • minutes
    • hours
    • days
  • example:

    --------------------{ timedisplay }----------------------------------
           0.000123 -> "123μs"
           0.123000 -> "123ms"
         123.000000 -> "2mn 3s"
         123.456789 -> "2mn 3s 456ms 789μs"
      123456.000000 -> "1day 10h 17mn 36s"
     1234567.000000 -> "14days 6h 56mn 7s"
    

  • example:

    from bliss.common import timedisplay
    print(f"duration: {timedisplay.duration_format(123.456789)}")
    
    result:
    duration: 2mn 3s 456ms 789μs
    

Statistics

Calculate statistics from a profiling dictionary

  • key == function name
  • values == list of tuple (start_time, end_time)
DEMO [29]: from bliss.common.utils import Statistics
DEMO [30]: profile = {"init()":[(0.1, 0.22)], "finalize()":[(0.01, 0.045)]}
DEMO [31]: Statistics(profile)
 Out [31]: func_name    min        mean       max            std
           -----------  ---------  ---------  ---------  -------
           finalize()   35.000ms   35.000ms   35.000ms   0.00000
           init()       120.000ms  120.000ms  120.000ms  0.00000

UserNamespace

deep_update

Do a deep merge of one dict into another.

Types

is_basictype()

is_complextype()

is_mutsequence()

is_mutmapping()

is_sametype()

Tree

prudent_update(d, u)

Updates a MutableMapping or MutalbeSequence ‘d’ from another one ‘u’. The update is done trying to minimize changes: the update is done only on leaves of the tree if possible. This is to preserve the original object as much as possible.

update_node_info(node, d)

math rounding

rounder()

Return rounded string representation of a number according to a template number. Rounding is performed by string formatting (i.e. uses round() ?).

from bliss.common.utils import rounder

assert rounder(0.0001, 16.12345) == "16.1234"
assert rounder(1, 16.123) == "16"
assert rounder(0.1, 8.5) == "8.5"
assert rounder(1e-8, 1.123456789123456789) == "1.12345679"

NB: Used to display axes positions.

Shell

ShellStr

Network

get_open_ports(n)

Return a list of open ports.

Help/Errors

ErrorWithTraceback

WrappedMethod

shorten_signature

By default it is removing the annotation of each parameter or replacing it with a custum one.

custom_error_msg

typecheck_var_args_pattern

modify_annotations

Modify the annotation in an existing signature.

is_pattern

Return true if the input string is a pattern for get_matching_names.

get_matching_names

Search a pattern into a list of names (unix pattern style).

Messages

nonblocking_print()

countdown(timing, msg, end_msg)

countdown(<duration_in_seconds>, [<waiting message>], [<end_message>])

from bliss.shell.standard import countdown
countdown(5, "Waiting for stabilization", "Goooo")

Countdown example

getval

getval_ functions are a set of functions to prompt user to enter interactively various types of inputs: int, float, string, yes/no or answer to a question.

getval_ functions can be customized with some style. See []

getval_int()

  • getval_int(message, min, max, default): Prompt user for an int number in interval [min, max]

Note

getval_int_range() is kept for backward compatibility

In [1]: from bliss.shell.getval import getval_int

In [2]: getval_int("Please enter beamline number", min=1, max=32, default=1)

Please enter beamline number [1]: f
Error: f is not a valid integer
Please enter beamline number [1]: 99
Error: 99 is not in the valid range of 1 to 32.
Please enter beamline number [1]: 5
Out[2]: 5

getval_float()

  • Same behavior than getval_int() but for floating point numbers.

getval_idx_list(list, msg)

  • getval_idx_list(): Return the index and string chosen by user in list of N strings. Selection is done by index in [1..N].

Example:

from bliss.shell.getval import getval_idx_list

dspacing_list = ["111", "311", "642"]
print(getval_idx_list(dspacing_list,"Choose the index of dspacing you want to use"))

Execution of previous example:

1 - 111
2 - 311
3 - 642
Choose the index of dspacing you want to use [1]: 2
311

getval_char_list(list)

from bliss.shell.getval import getval_char_list

actions_list= [("a", "add a roi"), ("r", "remove a roi"), ("m", "modify a roi")]
getval_char_list(actions_list, "Action to do")

Execution of previous example:

a - add a roi
r - remove a roi
m - modify a roi
Action to do: a
  Out [8]: ('a', 'add a roi')

getval_yes_no(msg)

  • getval_yes_no(message, default=True)
from bliss.shell.getval import getval_yes_no

 In [3]: if getval_yes_no("Do you want to open shutter ?", default="no"):
   ...:     print("ok, openning...")
   ...: else:
   ...:     print("abort...")

Do you want to open shutter ? [Y/n]: 0
Error: invalid input
Do you want to open shutter ? [Y/n]: 1
Error: invalid input
Do you want to open shutter ? [Y/n]: oui
Error: invalid input
Do you want to open shutter ? [Y/n]: YES
ok, openning...