genie-python 15.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. genie_python/.pylintrc +539 -0
  2. genie_python/__init__.py +1 -0
  3. genie_python/_version.py +16 -0
  4. genie_python/block_names.py +123 -0
  5. genie_python/channel_access_exceptions.py +45 -0
  6. genie_python/genie.py +2462 -0
  7. genie_python/genie_advanced.py +418 -0
  8. genie_python/genie_alerts.py +195 -0
  9. genie_python/genie_api_setup.py +451 -0
  10. genie_python/genie_blockserver.py +64 -0
  11. genie_python/genie_cachannel_wrapper.py +551 -0
  12. genie_python/genie_change_cache.py +151 -0
  13. genie_python/genie_dae.py +2219 -0
  14. genie_python/genie_epics_api.py +906 -0
  15. genie_python/genie_experimental_data.py +186 -0
  16. genie_python/genie_logging.py +200 -0
  17. genie_python/genie_p4p_wrapper.py +203 -0
  18. genie_python/genie_plot.py +77 -0
  19. genie_python/genie_pre_post_cmd_manager.py +21 -0
  20. genie_python/genie_pv_connection_protocol.py +36 -0
  21. genie_python/genie_script_checker.py +507 -0
  22. genie_python/genie_script_generator.py +212 -0
  23. genie_python/genie_simulate.py +69 -0
  24. genie_python/genie_simulate_impl.py +1265 -0
  25. genie_python/genie_startup.py +29 -0
  26. genie_python/genie_toggle_settings.py +58 -0
  27. genie_python/genie_wait_for_move.py +154 -0
  28. genie_python/genie_waitfor.py +576 -0
  29. genie_python/matplotlib_backend/__init__.py +0 -0
  30. genie_python/matplotlib_backend/ibex_websocket_backend.py +366 -0
  31. genie_python/mysql_abstraction_layer.py +272 -0
  32. genie_python/scanning_instrument_pylint_plugin.py +31 -0
  33. genie_python/testing_utils/__init__.py +4 -0
  34. genie_python/testing_utils/script_checker.py +63 -0
  35. genie_python/typings/CaChannel/CaChannel.pyi +893 -0
  36. genie_python/typings/CaChannel/__init__.pyi +9 -0
  37. genie_python/typings/CaChannel/_version.pyi +6 -0
  38. genie_python/typings/CaChannel/ca.pyi +31 -0
  39. genie_python/utilities.py +406 -0
  40. genie_python/version.py +6 -0
  41. genie_python-15.1.0.dist-info/LICENSE +28 -0
  42. genie_python-15.1.0.dist-info/METADATA +84 -0
  43. genie_python-15.1.0.dist-info/RECORD +45 -0
  44. genie_python-15.1.0.dist-info/WHEEL +5 -0
  45. genie_python-15.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,29 @@
1
+ from __future__ import absolute_import
2
+
3
+ import ctypes
4
+ import os
5
+ import sys
6
+ from importlib import reload # noqa F401
7
+
8
+ from genie_python import BLOCK_NAMES as b # noqa F401
9
+ from genie_python import genie as g # noqa F401
10
+
11
+ # Required so that scientists can just call reload(inst) in the python console.
12
+ # Importing genie and block names is required for user scripts.
13
+ from genie_python.genie import * # noqa F403
14
+
15
+ if os.name == "nt":
16
+ # Disable Windows console quick edit mode
17
+ win32 = ctypes.windll.kernel32
18
+ hin = win32.GetStdHandle(-10)
19
+ mode = ctypes.c_ulong(0)
20
+ win32.GetConsoleMode(hin, ctypes.byref(mode))
21
+ # To disable quick edit need to disable the 7th bit and enable the 8th
22
+ new_mode = mode.value & ~(0x0040) | (0x0080)
23
+ win32.SetConsoleMode(hin, new_mode)
24
+
25
+ # Call set_instrument with None to force it to try to guess the instrument
26
+ set_instrument(None) # noqa F405 (defined from star import)
27
+
28
+ # Add shared instrument scripts to the PYTHONPATH
29
+ sys.path.append("C:\\Instrument\\scripts")
@@ -0,0 +1,58 @@
1
+ """
2
+ Genie Toggle Settings module.
3
+
4
+ This module is used for storing and updating user preferences and settings.
5
+ """
6
+
7
+ from __future__ import absolute_import, print_function
8
+
9
+ import genie_python.genie_api_setup # for _exceptions_raised
10
+ from genie_python.genie_api_setup import helparglist, log_command_and_handle_exception, usercommand
11
+
12
+
13
+ class ToggleSettings:
14
+ cset_verbose = False
15
+
16
+
17
+ @usercommand
18
+ @helparglist("")
19
+ @log_command_and_handle_exception
20
+ def exceptions_raised(toggle_on):
21
+ """
22
+ Set whether to allow exceptions to propagate (True) or let genie handle any exceptions (False).
23
+ By default (False), genie_python will handle any exceptions by printing the error message and carrying on.
24
+
25
+ Args:
26
+ toggle_on (bool): Allow exceptions if True, let genie handle exceptions if False.
27
+
28
+ Examples:
29
+ Set genie_python not to handle exceptions:
30
+
31
+ >>> exceptions_raised(True)
32
+ """
33
+ if not isinstance(toggle_on, bool):
34
+ raise ValueError("Exceptions raised setting needs to be True or False.")
35
+ genie_python.genie_api_setup._exceptions_raised = toggle_on
36
+ # noinspection PyProtectedMember
37
+ print("Raise exceptions set to {}.".format(genie_python.genie_api_setup._exceptions_raised))
38
+
39
+
40
+ @usercommand
41
+ @helparglist("")
42
+ @log_command_and_handle_exception
43
+ def cset_verbose(verbose):
44
+ """
45
+ Set the default verbosity of cset.
46
+
47
+ Args:
48
+ verbose (bool): The cset verbose flag.
49
+
50
+ Examples:
51
+ Setting up all cset calls to be verbose:
52
+
53
+ >>> cset_verbose(True)
54
+ """
55
+ if not isinstance(verbose, bool):
56
+ raise ValueError("Default verbosity needs to be True or False.")
57
+ ToggleSettings.cset_verbose = verbose
58
+ print("Default cset verbosity set to {}.".format(ToggleSettings.cset_verbose))
@@ -0,0 +1,154 @@
1
+ # encoding: UTF-8
2
+
3
+ """Waits until the supplied process variable returns 'done'.
4
+ Allows motors to complete their motion fully before proceeding."""
5
+
6
+ # If you include db/motorUtil.db and call motorUtilInit(“pv prefix”) from your IOC you get 3 PVs defined:
7
+ # $(P)alldone, $(P)allstop, $(P)moving which cover all motors in that IOC.
8
+ # The “allstop” PV is automatically reset after the stop command has been issued to all motors,
9
+ # “alldone” indicates when any motion has completed and “moving” gives a count of moving motors.
10
+
11
+ from __future__ import absolute_import, print_function
12
+
13
+ import time
14
+ from builtins import object
15
+
16
+ from genie_python.utilities import check_break
17
+
18
+
19
+ class WaitForMoveController(object):
20
+ def __init__(self, api, motion_pv):
21
+ self._api = api
22
+ self._motion_pv = motion_pv
23
+ self._polling_delay = 0.02
24
+ self._wait_succeeded = False
25
+ self._missing_blocks = list()
26
+
27
+ def wait(self, start_timeout=None, move_timeout=None):
28
+ """Wait for motor motion to complete.
29
+
30
+ Args:
31
+ start_timeout (int, optional) : the number of seconds to wait for the movement to begin
32
+ move_timeout (int, optional) : the maximum number of seconds to wait for motion to stop
33
+
34
+ If the motion does not start within the specified start_timeout then it will continue as if it did.
35
+ """
36
+ self._do_wait(start_timeout, move_timeout, self._any_motion)
37
+
38
+ def wait_specific(self, blocks, start_timeout=None, move_timeout=None):
39
+ """Wait for motor motion to complete on the specified blocks only.
40
+
41
+ Args:
42
+ blocks (list) : the names of the blocks to wait for
43
+ start_timeout (int, optional) : the number of seconds to wait for the movement to begin
44
+ move_timeout (int, optional) : the maximum number of seconds to wait for motion to stop
45
+
46
+ If the motion does not start within the specified start_timeout then it will continue as if it did
47
+ """
48
+
49
+ def check_blocks():
50
+ return self._check_specific_motion(blocks)
51
+
52
+ self._do_wait(start_timeout, move_timeout, check_blocks)
53
+ self._flag_error_conditions(blocks)
54
+
55
+ def _do_wait(self, start_timeout, move_timeout, check_for_move):
56
+ # Pause very briefly to avoid any "double move" that may occur when multiple motors are moved
57
+ # and one of the motors is sent to its current position
58
+ time.sleep(0.01)
59
+
60
+ self._missing_blocks = []
61
+
62
+ start_timeout, move_timeout = self._check_timeouts_valid(start_timeout, move_timeout)
63
+
64
+ # If not already moving then wait for up to "timeout" seconds for a move to start
65
+ self.wait_for_start(start_timeout, check_for_move)
66
+
67
+ start = time.time()
68
+ while check_for_move():
69
+ check_break(2)
70
+ time.sleep(self._polling_delay)
71
+ if move_timeout is not None and time.time() - start >= move_timeout:
72
+ self._api.logger.log_info_msg("WAITFOR_MOVE TIMED OUT")
73
+ return
74
+ self._api.logger.log_info_msg("WAITFOR_MOVE MOVE FINISHED")
75
+
76
+ def _check_timeouts_valid(self, start_timeout, move_timeout):
77
+ if start_timeout is not None and start_timeout <= 0:
78
+ self._api.logger.log_info_msg(
79
+ "Start time out cannot be less than zero - using default value"
80
+ )
81
+ start_timeout = 0
82
+ if move_timeout is not None and move_timeout <= 0:
83
+ self._api.logger.log_info_msg(
84
+ "Move time out cannot be less than zero - using default value"
85
+ )
86
+ move_timeout = None
87
+ return start_timeout, move_timeout
88
+
89
+ def wait_for_start(self, timeout, check_for_move):
90
+ if timeout is not None:
91
+ start = time.time()
92
+
93
+ while not check_for_move():
94
+ check_break(2)
95
+ time.sleep(self._polling_delay)
96
+ if time.time() - start >= timeout:
97
+ self._api.logger.log_info_msg("WAITFOR_MOVE START TIMED OUT")
98
+ return
99
+ self._api.logger.log_info_msg("WAITFOR_MOVE START FINISHED")
100
+
101
+ def _any_motion(self):
102
+ return self._api.get_pv_value(self._motion_pv) != 0
103
+
104
+ def _check_specific_motion(self, blocks):
105
+ for block in blocks:
106
+ if block in self._missing_blocks:
107
+ # Skip any missing blocks
108
+ continue
109
+ block_pv = self._api.get_pv_from_block(block)
110
+ # DMOV = 0 when moving
111
+ try:
112
+ moving = self._api.get_pv_value(block_pv + ":DMOV", attempts=1) == 0
113
+ except IOError:
114
+ # Could not find block so don't try it again
115
+ self._api.logger.log_info_msg("WAITFOR_MOVE DISCONNECTED BLOCK: {}".format(block))
116
+ print("Could not connect to block {} so ignoring it".format(block))
117
+ self._missing_blocks.append(block)
118
+ moving = False
119
+ if moving:
120
+ return True
121
+
122
+ return False
123
+
124
+ def _flag_error_conditions(self, blocks):
125
+ time.sleep(0.5)
126
+ filtered_blocks = self._filter_out_missing_blocks(blocks)
127
+
128
+ # Check alarms
129
+ minor, major, invalid = self._api.check_alarms(filtered_blocks)
130
+ for i in major:
131
+ self._api.logger.log_info_msg("WAITFOR_MOVE BLOCK %s IN MAJOR ALARM" % i)
132
+ print("Block %s is in alarm: MAJOR" % i)
133
+ for i in minor:
134
+ self._api.logger.log_info_msg("WAITFOR_MOVE BLOCK %s IN MINOR ALARM" % i)
135
+ print("Block %s is in alarm state: MINOR" % i)
136
+
137
+ # Check soft limit violations
138
+ violations = self._api.check_limit_violations(filtered_blocks)
139
+ for i in violations:
140
+ self._api.logger.log_info_msg("WAITFOR_MOVE BLOCK %s HAS SOFT LIMIT VIOLATIONS" % i)
141
+ print("Block %s has soft limit violations" % i)
142
+
143
+ # Print missing blocks
144
+ for i in self._missing_blocks:
145
+ self._api.logger.log_info_msg("WAITFOR_MOVE BLOCK %s COULD NOT BE FOUND" % i)
146
+ print("Block %s could not be found" % i)
147
+
148
+ def _filter_out_missing_blocks(self, blocks):
149
+ filtered_blocks = []
150
+ for b in blocks:
151
+ if b in self._missing_blocks:
152
+ continue
153
+ filtered_blocks.append(b)
154
+ return filtered_blocks